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