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.hbase.classification.InterfaceAudience;
21  import org.apache.hadoop.conf.Configuration;
22  import org.apache.hadoop.hbase.exceptions.DeserializationException;
23  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
24  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
25  import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
26  import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos.SplitLogTask.RecoveryMode;
27  import org.apache.hadoop.hbase.util.Bytes;
28  
29  import com.google.protobuf.InvalidProtocolBufferException;
30  
31  /**
32   * State of a WAL log split during distributed splitting.  State is kept up in zookeeper.
33   * Encapsulates protobuf serialization/deserialization so we don't leak generated pb outside of
34   * this class.  Used by regionserver and master packages.
35   * <p>Immutable
36   */
37  @InterfaceAudience.Private
38  public class SplitLogTask {
39    private final ServerName originServer;
40    private final ZooKeeperProtos.SplitLogTask.State state;
41    private final ZooKeeperProtos.SplitLogTask.RecoveryMode mode;
42  
43    public static class Unassigned extends SplitLogTask {
44      public Unassigned(final ServerName originServer, final RecoveryMode mode) {
45        super(originServer, ZooKeeperProtos.SplitLogTask.State.UNASSIGNED, mode);
46      }
47    }
48  
49    public static class Owned extends SplitLogTask {
50      public Owned(final ServerName originServer, final RecoveryMode mode) {
51        super(originServer, ZooKeeperProtos.SplitLogTask.State.OWNED, mode);
52      }
53    }
54  
55    public static class Resigned extends SplitLogTask {
56      public Resigned(final ServerName originServer, final RecoveryMode mode) {
57        super(originServer, ZooKeeperProtos.SplitLogTask.State.RESIGNED, mode);
58      }
59    }
60  
61    public static class Done extends SplitLogTask {
62      public Done(final ServerName originServer, final RecoveryMode mode) {
63        super(originServer, ZooKeeperProtos.SplitLogTask.State.DONE, mode);
64      }
65    }
66  
67    public static class Err extends SplitLogTask {
68      public Err(final ServerName originServer, final RecoveryMode mode) {
69        super(originServer, ZooKeeperProtos.SplitLogTask.State.ERR, mode);
70      }
71    }
72  
73    SplitLogTask(final ZooKeeperProtos.SplitLogTask slt) {
74      this.originServer = ProtobufUtil.toServerName(slt.getServerName());
75      this.state = slt.getState();
76      this.mode = (slt.hasMode()) ? slt.getMode() : 
77        ZooKeeperProtos.SplitLogTask.RecoveryMode.UNKNOWN;
78    }
79  
80    SplitLogTask(final ServerName originServer, final ZooKeeperProtos.SplitLogTask.State state,
81        final ZooKeeperProtos.SplitLogTask.RecoveryMode mode) {
82      this.originServer = originServer;
83      this.state = state;
84      this.mode = mode;
85    }
86  
87    public ServerName getServerName() {
88      return this.originServer;
89    }
90    
91    public ZooKeeperProtos.SplitLogTask.RecoveryMode getMode() {
92      return this.mode;
93    }
94  
95    public boolean isUnassigned(final ServerName sn) {
96      return this.originServer.equals(sn) && isUnassigned();
97    }
98  
99    public boolean isUnassigned() {
100     return this.state == ZooKeeperProtos.SplitLogTask.State.UNASSIGNED;
101   }
102 
103   public boolean isOwned(final ServerName sn) {
104     return this.originServer.equals(sn) && isOwned();
105   }
106 
107   public boolean isOwned() {
108     return this.state == ZooKeeperProtos.SplitLogTask.State.OWNED;
109   }
110 
111   public boolean isResigned(final ServerName sn) {
112     return this.originServer.equals(sn) && isResigned();
113   }
114 
115   public boolean isResigned() {
116     return this.state == ZooKeeperProtos.SplitLogTask.State.RESIGNED;
117   }
118 
119   public boolean isDone(final ServerName sn) {
120     return this.originServer.equals(sn) && isDone();
121   }
122 
123   public boolean isDone() {
124     return this.state == ZooKeeperProtos.SplitLogTask.State.DONE;
125   }
126 
127   public boolean isErr(final ServerName sn) {
128     return this.originServer.equals(sn) && isErr();
129   }
130 
131   public boolean isErr() {
132     return this.state == ZooKeeperProtos.SplitLogTask.State.ERR;
133   }
134 
135   @Override
136   public String toString() {
137     return this.state.toString() + " " + this.originServer.toString();
138   }
139 
140   @Override
141   public boolean equals(Object obj) {
142     if (!(obj instanceof SplitLogTask)) return false;
143     SplitLogTask other = (SplitLogTask)obj;
144     return other.state.equals(this.state) && other.originServer.equals(this.originServer);
145   }
146 
147   @Override
148   public int hashCode() {
149     int hash = 7;
150     hash = 31 * hash + this.state.hashCode();
151     return 31 * hash + this.originServer.hashCode();
152   }
153 
154   /**
155    * @param data Serialized date to parse.
156    * @return An SplitLogTaskState instance made of the passed <code>data</code>
157    * @throws DeserializationException 
158    * @see #toByteArray()
159    */
160   public static SplitLogTask parseFrom(final byte [] data) throws DeserializationException {
161     ProtobufUtil.expectPBMagicPrefix(data);
162     try {
163       int prefixLen = ProtobufUtil.lengthOfPBMagic();
164       ZooKeeperProtos.SplitLogTask slt = ZooKeeperProtos.SplitLogTask.newBuilder().
165         mergeFrom(data, prefixLen, data.length - prefixLen).build();
166       return new SplitLogTask(slt);
167     } catch (InvalidProtocolBufferException e) {
168       throw new DeserializationException(Bytes.toStringBinary(data, 0, 64), e);
169     }
170   }
171 
172   /**
173    * @return This instance serialized into a byte array
174    * @see #parseFrom(byte[])
175    */
176   public byte [] toByteArray() {
177     // First create a pb ServerName.  Then create a ByteString w/ the TaskState
178     // bytes in it.  Finally create a SplitLogTaskState passing in the two
179     // pbs just created.
180     HBaseProtos.ServerName snpb = ProtobufUtil.toServerName(this.originServer);
181     ZooKeeperProtos.SplitLogTask slts =
182       ZooKeeperProtos.SplitLogTask.newBuilder().setServerName(snpb).setState(this.state).
183       setMode(this.mode).build();
184     return ProtobufUtil.prependPBMagic(slts.toByteArray());
185   }
186 }