1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.exceptions;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.apache.hadoop.classification.InterfaceAudience;
23 import org.apache.hadoop.classification.InterfaceStability;
24 import org.apache.hadoop.hbase.HConstants;
25 import org.apache.hadoop.hbase.NotServingRegionException;
26 import org.apache.hadoop.hbase.ServerName;
27 import org.apache.hadoop.ipc.RemoteException;
28
29
30
31
32
33 @InterfaceAudience.Private
34 @InterfaceStability.Evolving
35 public class RegionMovedException extends NotServingRegionException {
36 private static final Log LOG = LogFactory.getLog(RegionMovedException.class);
37 private static final long serialVersionUID = -7232903522310558396L;
38
39 private final String hostname;
40 private final int port;
41 private final long startCode;
42 private final long locationSeqNum;
43
44 private static final String HOST_FIELD = "hostname=";
45 private static final String PORT_FIELD = "port=";
46 private static final String STARTCODE_FIELD = "startCode=";
47 private static final String LOCATIONSEQNUM_FIELD = "locationSeqNum=";
48
49
50 public RegionMovedException(ServerName serverName, long locationSeqNum) {
51 this.hostname = serverName.getHostname();
52 this.port = serverName.getPort();
53 this.startCode = serverName.getStartcode();
54 this.locationSeqNum = locationSeqNum;
55 }
56
57 public String getHostname() {
58 return hostname;
59 }
60
61 public int getPort() {
62 return port;
63 }
64
65 public ServerName getServerName(){
66 return new ServerName(hostname, port, startCode);
67 }
68
69 public long getLocationSeqNum() {
70 return locationSeqNum;
71 }
72
73
74
75
76
77
78 public RegionMovedException(String s) {
79 int posHostname = s.indexOf(HOST_FIELD) + HOST_FIELD.length();
80 int posPort = s.indexOf(PORT_FIELD) + PORT_FIELD.length();
81 int posStartCode = s.indexOf(STARTCODE_FIELD) + STARTCODE_FIELD.length();
82 int posSeqNum = s.indexOf(LOCATIONSEQNUM_FIELD) + LOCATIONSEQNUM_FIELD.length();
83
84 String tmpHostname = null;
85 int tmpPort = -1;
86 long tmpStartCode = -1;
87 long tmpSeqNum = HConstants.NO_SEQNUM;
88 try {
89
90 tmpHostname = s.substring(posHostname, s.indexOf(' ', posHostname));
91 tmpPort = Integer.parseInt(s.substring(posPort, s.indexOf(' ', posPort)));
92 tmpStartCode = Long.parseLong(s.substring(posStartCode, s.indexOf('.', posStartCode)));
93 tmpSeqNum = Long.parseLong(s.substring(posSeqNum, s.indexOf('.', posSeqNum)));
94 } catch (Exception ignored) {
95 LOG.warn("Can't parse the hostname, port and startCode from this string: " +
96 s + ", continuing");
97 }
98
99 hostname = tmpHostname;
100 port = tmpPort;
101 startCode = tmpStartCode;
102 locationSeqNum = tmpSeqNum;
103 }
104
105 @Override
106 public String getMessage() {
107
108
109 return "Region moved to: " + HOST_FIELD + hostname + " " + PORT_FIELD + port + " " +
110 STARTCODE_FIELD + startCode + ". As of " + LOCATIONSEQNUM_FIELD + locationSeqNum + ".";
111 }
112
113
114
115
116
117
118
119 public static RegionMovedException find(Object exception) {
120 if (exception == null || !(exception instanceof Throwable)){
121 return null;
122 }
123
124 Throwable cur = (Throwable)exception;
125 RegionMovedException res = null;
126
127 while (res == null && cur != null) {
128 if (cur instanceof RegionMovedException) {
129 res = (RegionMovedException) cur;
130 } else {
131 if (cur instanceof RemoteException) {
132 RemoteException re = (RemoteException) cur;
133 Exception e = re.unwrapRemoteException(RegionMovedException.class);
134 if (e == null){
135 e = re.unwrapRemoteException();
136 }
137
138
139
140 if (e != re){
141 res = find(e);
142 }
143 }
144 cur = cur.getCause();
145 }
146 }
147
148 if (res != null && (res.getPort() < 0 || res.getHostname() == null)){
149
150 return null;
151 } else {
152 return res;
153 }
154 }
155 }