001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase; 019 020import java.io.IOException; 021import java.util.Objects; 022import org.apache.hadoop.conf.Configuration; 023import org.apache.hadoop.hbase.exceptions.DeserializationException; 024import org.apache.hadoop.hbase.util.Bytes; 025import org.apache.yetus.audience.InterfaceAudience; 026 027import org.apache.hbase.thirdparty.com.google.common.base.Strings; 028 029import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 030import org.apache.hadoop.hbase.shaded.protobuf.generated.ActiveClusterSuffixProtos; 031 032/** 033 * The read-replica cluster id for this cluster. It is serialized to the filesystem and up into 034 * zookeeper. This is a container for the id. Also knows how to serialize and deserialize the 035 * cluster id. 036 */ 037@InterfaceAudience.Private 038public class ActiveClusterSuffix implements ClusterIdFile { 039 private final String clusterId; 040 private final String suffix; 041 042 public static class Parser implements ClusterIdFileParser<ActiveClusterSuffix> { 043 044 @Override 045 public String getFileName() { 046 return HConstants.ACTIVE_CLUSTER_SUFFIX_FILE_NAME; 047 } 048 049 /** 050 * Parse the serialized representation of the {@link ActiveClusterSuffix} 051 * @param bytes A pb serialized {@link ActiveClusterSuffix} instance with pb magic prefix 052 * @return An instance of {@link ActiveClusterSuffix} made from <code>bytes</code> 053 * @see #toByteArray() 054 */ 055 @Override 056 public ActiveClusterSuffix parseFrom(byte[] bytes) throws DeserializationException { 057 if (ProtobufUtil.isPBMagicPrefix(bytes)) { 058 int pblen = ProtobufUtil.lengthOfPBMagic(); 059 ActiveClusterSuffixProtos.ActiveClusterSuffix.Builder builder = 060 ActiveClusterSuffixProtos.ActiveClusterSuffix.newBuilder(); 061 ActiveClusterSuffixProtos.ActiveClusterSuffix cs = null; 062 try { 063 ProtobufUtil.mergeFrom(builder, bytes, pblen, bytes.length - pblen); 064 cs = builder.build(); 065 } catch (IOException e) { 066 throw new DeserializationException(e); 067 } 068 return convert(cs); 069 } else { 070 // Presume it was written out this way, the old way. 071 return new ActiveClusterSuffix(Bytes.toString(bytes)); 072 } 073 } 074 075 @Override 076 public ActiveClusterSuffix readString(String input) { 077 return new ActiveClusterSuffix(input); 078 } 079 } 080 081 public ActiveClusterSuffix(final String clusterId, final String suffix) { 082 this.clusterId = clusterId; 083 this.suffix = suffix; 084 } 085 086 public ActiveClusterSuffix(final String input) { 087 String[] parts = input.split(":", 2); 088 this.clusterId = parts[0]; 089 if (parts.length > 1) { 090 this.suffix = parts[1]; 091 } else { 092 this.suffix = ""; 093 } 094 } 095 096 public static ActiveClusterSuffix parseFrom(byte[] bytes) throws DeserializationException { 097 return new Parser().parseFrom(bytes); 098 } 099 100 public static ActiveClusterSuffix fromConfig(Configuration conf, ClusterId clusterId) { 101 return new ActiveClusterSuffix(clusterId.toString(), conf 102 .get(HConstants.HBASE_META_TABLE_SUFFIX, HConstants.HBASE_META_TABLE_SUFFIX_DEFAULT_VALUE)); 103 } 104 105 /** Returns The active cluster suffix serialized using pb w/ pb magic prefix */ 106 public byte[] toByteArray() { 107 return ProtobufUtil.prependPBMagic(convert().toByteArray()); 108 } 109 110 /** Returns A pb instance to represent this instance. */ 111 public ActiveClusterSuffixProtos.ActiveClusterSuffix convert() { 112 return ActiveClusterSuffixProtos.ActiveClusterSuffix.newBuilder().setClusterId(clusterId) 113 .setSuffix(suffix).build(); 114 } 115 116 /** Returns A {@link ActiveClusterSuffix} made from the passed in <code>cs</code> */ 117 public static ActiveClusterSuffix 118 convert(final ActiveClusterSuffixProtos.ActiveClusterSuffix cs) { 119 return new ActiveClusterSuffix(cs.getClusterId(), cs.getSuffix()); 120 } 121 122 /** 123 * @see java.lang.Object#toString() 124 */ 125 @Override 126 public String toString() { 127 return String.format("%s:%s", this.clusterId, 128 Strings.isNullOrEmpty(this.suffix) ? "<blank>" : this.suffix); 129 } 130 131 @Override 132 public boolean equals(Object o) { 133 if (o == null || getClass() != o.getClass()) return false; 134 ActiveClusterSuffix that = (ActiveClusterSuffix) o; 135 return Objects.equals(clusterId, that.clusterId) && Objects.equals(suffix, that.suffix); 136 } 137 138 @Override 139 public int hashCode() { 140 return Objects.hash(clusterId, suffix); 141 } 142}