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