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