1 package org.apache.hadoop.hbase.regionserver;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.DataOutputStream;
5 import java.io.IOException;
6
7 import org.apache.commons.logging.Log;
8 import org.apache.commons.logging.LogFactory;
9 import org.apache.hadoop.conf.Configuration;
10 import org.apache.hadoop.hbase.HBaseConfiguration;
11 import org.apache.hadoop.hbase.HMsg;
12 import org.apache.hadoop.hbase.executor.RegionTransitionEventData;
13 import org.apache.hadoop.hbase.executor.HBaseEventHandler;
14 import org.apache.hadoop.hbase.executor.HBaseEventHandler.HBaseEventType;
15 import org.apache.hadoop.hbase.util.Writables;
16 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWrapper;
17 import org.apache.zookeeper.CreateMode;
18 import org.apache.zookeeper.data.Stat;
19
20
21
22
23
24
25
26
27
28
29
30
31 public class RSZookeeperUpdater {
32 private static final Log LOG = LogFactory.getLog(RSZookeeperUpdater.class);
33 private final String regionServerName;
34 private String regionName = null;
35 private String regionZNode = null;
36 private ZooKeeperWrapper zkWrapper = null;
37 private int zkVersion = 0;
38 HBaseEventType lastUpdatedState;
39
40 public RSZookeeperUpdater(Configuration conf,
41 String regionServerName, String regionName) {
42 this(conf, regionServerName, regionName, 0);
43 }
44
45 public RSZookeeperUpdater(Configuration conf, String regionServerName,
46 String regionName, int zkVersion) {
47 this.zkWrapper = ZooKeeperWrapper.getInstance(conf, regionServerName);
48 this.regionServerName = regionServerName;
49 this.regionName = regionName;
50
51 this.regionZNode = zkWrapper.getZNode(zkWrapper.getRegionInTransitionZNode(), regionName);
52 this.zkVersion = zkVersion;
53 }
54
55
56
57
58
59
60 public void startRegionCloseEvent(HMsg hmsg, boolean updatePeriodically) throws IOException {
61
62 if(zkWrapper.exists(regionZNode, true)) {
63 String msg = "ZNode " + regionZNode + " already exists in ZooKeeper, will NOT close region.";
64 LOG.error(msg);
65 throw new IOException(msg);
66 }
67
68
69 zkWrapper.createZNodeIfNotExists(regionZNode, null, CreateMode.PERSISTENT, true);
70
71
72 updateZKWithEventData(HBaseEventType.RS2ZK_REGION_CLOSING, hmsg);
73
74
75 }
76
77
78
79
80
81
82 public void finishRegionCloseEvent(HMsg hmsg) throws IOException {
83
84
85
86 updateZKWithEventData(HBaseEventType.RS2ZK_REGION_CLOSED, hmsg);
87 }
88
89
90
91
92
93
94 public void startRegionOpenEvent(HMsg hmsg, boolean updatePeriodically) throws IOException {
95 Stat stat = new Stat();
96 byte[] data = zkWrapper.readZNode(regionZNode, stat);
97
98 if(data == null) {
99 String msg = "ZNode " + regionZNode + " does not exist in ZooKeeper, will NOT open region.";
100 LOG.error(msg);
101 throw new IOException(msg);
102 }
103
104 HBaseEventType rsEvent = HBaseEventType.fromByte(data[0]);
105 if(rsEvent != HBaseEventType.RS2ZK_REGION_CLOSED && rsEvent != HBaseEventType.M2ZK_REGION_OFFLINE) {
106 String msg = "ZNode " + regionZNode + " is not in CLOSED/OFFLINE state (state = " + rsEvent + "), will NOT open region.";
107 LOG.error(msg);
108 throw new IOException(msg);
109 }
110
111
112 zkVersion = stat.getVersion();
113
114
115 updateZKWithEventData(HBaseEventType.RS2ZK_REGION_OPENING, hmsg);
116
117
118 }
119
120
121
122
123
124
125 public void finishRegionOpenEvent(HMsg hmsg) throws IOException {
126
127
128
129 updateZKWithEventData(HBaseEventType.RS2ZK_REGION_OPENED, hmsg);
130 }
131
132 public boolean isClosingRegion() {
133 return (lastUpdatedState == HBaseEventType.RS2ZK_REGION_CLOSING);
134 }
135
136 public boolean isOpeningRegion() {
137 return (lastUpdatedState == HBaseEventType.RS2ZK_REGION_OPENING);
138 }
139
140 public void abortOpenRegion(HMsg hmsg) throws IOException {
141 LOG.error("Aborting open of region " + regionName);
142
143
144
145
146 updateZKWithEventData(HBaseEventType.RS2ZK_REGION_CLOSED, hmsg);
147 }
148
149 private void updateZKWithEventData(HBaseEventType hbEventType, HMsg hmsg) throws IOException {
150
151 byte[] data = null;
152 try {
153 data = Writables.getBytes(new RegionTransitionEventData(hbEventType, regionServerName, hmsg));
154 } catch (IOException e) {
155 LOG.error("Error creating event data for " + hbEventType, e);
156 }
157 LOG.debug("Updating ZNode " + regionZNode +
158 " with [" + hbEventType + "]" +
159 " expected version = " + zkVersion);
160 lastUpdatedState = hbEventType;
161 zkWrapper.writeZNode(regionZNode, data, zkVersion, true);
162 zkVersion++;
163 }
164 }