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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 package org
.apache
.hadoop
.hbase
.exceptions
;
20 import org
.apache
.hadoop
.hbase
.HConstants
;
21 import org
.apache
.hadoop
.hbase
.NotServingRegionException
;
22 import org
.apache
.hadoop
.hbase
.ServerName
;
23 import org
.apache
.yetus
.audience
.InterfaceAudience
;
24 import org
.apache
.yetus
.audience
.InterfaceStability
;
25 import org
.slf4j
.Logger
;
26 import org
.slf4j
.LoggerFactory
;
29 * Subclass if the server knows the region is now on another server.
30 * This allows the client to call the new region server without calling the master.
32 @InterfaceAudience.Private
33 @InterfaceStability.Evolving
34 public class RegionMovedException
extends NotServingRegionException
{
35 private static final Logger LOG
= LoggerFactory
.getLogger(RegionMovedException
.class);
36 private static final long serialVersionUID
= -7232903522310558396L;
38 private final String hostname
;
39 private final int port
;
40 private final long startCode
;
41 private final long locationSeqNum
;
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=";
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
;
56 public String
getHostname() {
60 public int getPort() {
64 public ServerName
getServerName(){
65 return ServerName
.valueOf(hostname
, port
, startCode
);
68 public long getLocationSeqNum() {
69 return locationSeqNum
;
73 * For hadoop.ipc internal call. Do NOT use.
74 * We have to parse the hostname to recreate the exception.
75 * The input is the one generated by {@link #getMessage()}
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();
83 String tmpHostname
= null;
85 long tmpStartCode
= -1;
86 long tmpSeqNum
= HConstants
.NO_SEQNUM
;
88 // TODO: this whole thing is extremely brittle.
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: " +
98 hostname
= tmpHostname
;
100 startCode
= tmpStartCode
;
101 locationSeqNum
= tmpSeqNum
;
105 public String
getMessage() {
106 // TODO: deserialization above depends on this. That is bad, but also means this
107 // should be modified carefully.
108 return "Region moved to: " + HOST_FIELD
+ hostname
+ " " + PORT_FIELD
+ port
+ " " +
109 STARTCODE_FIELD
+ startCode
+ ". As of " + LOCATIONSEQNUM_FIELD
+ locationSeqNum
+ ".";