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 */ 018 019package org.apache.hadoop.hbase.replication; 020 021import java.util.Collection; 022import java.util.Collections; 023import java.util.HashMap; 024import java.util.List; 025import java.util.Map; 026import java.util.Set; 027import java.util.TreeMap; 028 029import org.apache.hadoop.hbase.TableName; 030import org.apache.yetus.audience.InterfaceAudience; 031import org.apache.hadoop.hbase.util.Bytes; 032 033/** 034 * A configuration for the replication peer cluster. 035 */ 036@InterfaceAudience.Public 037public class ReplicationPeerConfig { 038 039 private String clusterKey; 040 private String replicationEndpointImpl; 041 private final Map<byte[], byte[]> peerData; 042 private final Map<String, String> configuration; 043 private Map<TableName, ? extends Collection<String>> tableCFsMap = null; 044 private Set<String> namespaces = null; 045 // Default value is true, means replicate all user tables to peer cluster. 046 private boolean replicateAllUserTables = true; 047 private Map<TableName, ? extends Collection<String>> excludeTableCFsMap = null; 048 private Set<String> excludeNamespaces = null; 049 private long bandwidth = 0; 050 051 private ReplicationPeerConfig(ReplicationPeerConfigBuilderImpl builder) { 052 this.clusterKey = builder.clusterKey; 053 this.replicationEndpointImpl = builder.replicationEndpointImpl; 054 this.peerData = Collections.unmodifiableMap(builder.peerData); 055 this.configuration = Collections.unmodifiableMap(builder.configuration); 056 this.tableCFsMap = 057 builder.tableCFsMap != null ? unmodifiableTableCFsMap(builder.tableCFsMap) : null; 058 this.namespaces = 059 builder.namespaces != null ? Collections.unmodifiableSet(builder.namespaces) : null; 060 this.replicateAllUserTables = builder.replicateAllUserTables; 061 this.excludeTableCFsMap = 062 builder.excludeTableCFsMap != null ? unmodifiableTableCFsMap(builder.excludeTableCFsMap) 063 : null; 064 this.excludeNamespaces = 065 builder.excludeNamespaces != null ? Collections.unmodifiableSet(builder.excludeNamespaces) 066 : null; 067 this.bandwidth = builder.bandwidth; 068 } 069 070 private Map<TableName, List<String>> 071 unmodifiableTableCFsMap(Map<TableName, List<String>> tableCFsMap) { 072 Map<TableName, List<String>> newTableCFsMap = new HashMap<>(); 073 tableCFsMap.forEach((table, cfs) -> newTableCFsMap.put(table, 074 cfs != null ? Collections.unmodifiableList(cfs) : null)); 075 return Collections.unmodifiableMap(newTableCFsMap); 076 } 077 078 /** 079 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0. Use 080 * {@link ReplicationPeerConfigBuilder} to create new ReplicationPeerConfig. 081 */ 082 @Deprecated 083 public ReplicationPeerConfig() { 084 this.peerData = new TreeMap<>(Bytes.BYTES_COMPARATOR); 085 this.configuration = new HashMap<>(0); 086 } 087 088 /** 089 * Set the clusterKey which is the concatenation of the slave cluster's: 090 * hbase.zookeeper.quorum:hbase.zookeeper.property.clientPort:zookeeper.znode.parent 091 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0. Use 092 * {@link ReplicationPeerConfigBuilder#setClusterKey(String)} instead. 093 */ 094 @Deprecated 095 public ReplicationPeerConfig setClusterKey(String clusterKey) { 096 this.clusterKey = clusterKey; 097 return this; 098 } 099 100 /** 101 * Sets the ReplicationEndpoint plugin class for this peer. 102 * @param replicationEndpointImpl a class implementing ReplicationEndpoint 103 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0. Use 104 * {@link ReplicationPeerConfigBuilder#setReplicationEndpointImpl(String)} instead. 105 */ 106 @Deprecated 107 public ReplicationPeerConfig setReplicationEndpointImpl(String replicationEndpointImpl) { 108 this.replicationEndpointImpl = replicationEndpointImpl; 109 return this; 110 } 111 112 public String getClusterKey() { 113 return clusterKey; 114 } 115 116 public String getReplicationEndpointImpl() { 117 return replicationEndpointImpl; 118 } 119 120 public Map<byte[], byte[]> getPeerData() { 121 return peerData; 122 } 123 124 public Map<String, String> getConfiguration() { 125 return configuration; 126 } 127 128 public Map<TableName, List<String>> getTableCFsMap() { 129 return (Map<TableName, List<String>>) tableCFsMap; 130 } 131 132 /** 133 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0. Use 134 * {@link ReplicationPeerConfigBuilder#setTableCFsMap(Map)} instead. 135 */ 136 @Deprecated 137 public ReplicationPeerConfig setTableCFsMap(Map<TableName, 138 ? extends Collection<String>> tableCFsMap) { 139 this.tableCFsMap = tableCFsMap; 140 return this; 141 } 142 143 public Set<String> getNamespaces() { 144 return this.namespaces; 145 } 146 147 /** 148 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0. Use 149 * {@link ReplicationPeerConfigBuilder#setNamespaces(Set)} instead. 150 */ 151 @Deprecated 152 public ReplicationPeerConfig setNamespaces(Set<String> namespaces) { 153 this.namespaces = namespaces; 154 return this; 155 } 156 157 public long getBandwidth() { 158 return this.bandwidth; 159 } 160 161 /** 162 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0. Use 163 * {@link ReplicationPeerConfigBuilder#setBandwidth(long)} instead. 164 */ 165 @Deprecated 166 public ReplicationPeerConfig setBandwidth(long bandwidth) { 167 this.bandwidth = bandwidth; 168 return this; 169 } 170 171 public boolean replicateAllUserTables() { 172 return this.replicateAllUserTables; 173 } 174 175 /** 176 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0. Use 177 * {@link ReplicationPeerConfigBuilder#setReplicateAllUserTables(boolean)} instead. 178 */ 179 @Deprecated 180 public ReplicationPeerConfig setReplicateAllUserTables(boolean replicateAllUserTables) { 181 this.replicateAllUserTables = replicateAllUserTables; 182 return this; 183 } 184 185 public Map<TableName, List<String>> getExcludeTableCFsMap() { 186 return (Map<TableName, List<String>>) excludeTableCFsMap; 187 } 188 189 /** 190 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0. Use 191 * {@link ReplicationPeerConfigBuilder#setExcludeTableCFsMap(Map)} instead. 192 */ 193 @Deprecated 194 public ReplicationPeerConfig setExcludeTableCFsMap(Map<TableName, 195 ? extends Collection<String>> tableCFsMap) { 196 this.excludeTableCFsMap = tableCFsMap; 197 return this; 198 } 199 200 public Set<String> getExcludeNamespaces() { 201 return this.excludeNamespaces; 202 } 203 204 /** 205 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0. Use 206 * {@link ReplicationPeerConfigBuilder#setExcludeNamespaces(Set)} instead. 207 */ 208 @Deprecated 209 public ReplicationPeerConfig setExcludeNamespaces(Set<String> namespaces) { 210 this.excludeNamespaces = namespaces; 211 return this; 212 } 213 214 public static ReplicationPeerConfigBuilder newBuilder() { 215 return new ReplicationPeerConfigBuilderImpl(); 216 } 217 218 public static ReplicationPeerConfigBuilder newBuilder(ReplicationPeerConfig peerConfig) { 219 ReplicationPeerConfigBuilderImpl builder = new ReplicationPeerConfigBuilderImpl(); 220 builder.setClusterKey(peerConfig.getClusterKey()) 221 .setReplicationEndpointImpl(peerConfig.getReplicationEndpointImpl()) 222 .putAllPeerData(peerConfig.getPeerData()).putAllConfiguration(peerConfig.getConfiguration()) 223 .setTableCFsMap(peerConfig.getTableCFsMap()).setNamespaces(peerConfig.getNamespaces()) 224 .setReplicateAllUserTables(peerConfig.replicateAllUserTables()) 225 .setExcludeTableCFsMap(peerConfig.getExcludeTableCFsMap()) 226 .setExcludeNamespaces(peerConfig.getExcludeNamespaces()) 227 .setBandwidth(peerConfig.getBandwidth()); 228 return builder; 229 } 230 231 static class ReplicationPeerConfigBuilderImpl implements ReplicationPeerConfigBuilder { 232 233 private String clusterKey; 234 235 private String replicationEndpointImpl; 236 237 private Map<byte[], byte[]> peerData = new TreeMap<>(Bytes.BYTES_COMPARATOR); 238 239 private Map<String, String> configuration = new HashMap<>(); 240 241 private Map<TableName, List<String>> tableCFsMap = null; 242 243 private Set<String> namespaces = null; 244 245 // Default value is true, means replicate all user tables to peer cluster. 246 private boolean replicateAllUserTables = true; 247 248 private Map<TableName, List<String>> excludeTableCFsMap = null; 249 250 private Set<String> excludeNamespaces = null; 251 252 private long bandwidth = 0; 253 254 @Override 255 public ReplicationPeerConfigBuilder setClusterKey(String clusterKey) { 256 this.clusterKey = clusterKey; 257 return this; 258 } 259 260 @Override 261 public ReplicationPeerConfigBuilder setReplicationEndpointImpl(String replicationEndpointImpl) { 262 this.replicationEndpointImpl = replicationEndpointImpl; 263 return this; 264 } 265 266 @Override 267 public ReplicationPeerConfigBuilder putConfiguration(String key, String value) { 268 this.configuration.put(key, value); 269 return this; 270 } 271 272 @Override 273 public ReplicationPeerConfigBuilder putPeerData(byte[] key, byte[] value) { 274 this.peerData.put(key, value); 275 return this; 276 } 277 278 @Override 279 public ReplicationPeerConfigBuilder 280 setTableCFsMap(Map<TableName, List<String>> tableCFsMap) { 281 this.tableCFsMap = tableCFsMap; 282 return this; 283 } 284 285 @Override 286 public ReplicationPeerConfigBuilder setNamespaces(Set<String> namespaces) { 287 this.namespaces = namespaces; 288 return this; 289 } 290 291 @Override 292 public ReplicationPeerConfigBuilder setReplicateAllUserTables(boolean replicateAllUserTables) { 293 this.replicateAllUserTables = replicateAllUserTables; 294 return this; 295 } 296 297 @Override 298 public ReplicationPeerConfigBuilder 299 setExcludeTableCFsMap(Map<TableName, List<String>> excludeTableCFsMap) { 300 this.excludeTableCFsMap = excludeTableCFsMap; 301 return this; 302 } 303 304 @Override 305 public ReplicationPeerConfigBuilder setExcludeNamespaces(Set<String> excludeNamespaces) { 306 this.excludeNamespaces = excludeNamespaces; 307 return this; 308 } 309 310 @Override 311 public ReplicationPeerConfigBuilder setBandwidth(long bandwidth) { 312 this.bandwidth = bandwidth; 313 return this; 314 } 315 316 @Override 317 public ReplicationPeerConfig build() { 318 // It would be nice to validate the configuration, but we have to work with "old" data 319 // from ZK which makes it much more difficult. 320 return new ReplicationPeerConfig(this); 321 } 322 } 323 324 @Override 325 public String toString() { 326 StringBuilder builder = new StringBuilder("clusterKey=").append(clusterKey).append(","); 327 builder.append("replicationEndpointImpl=").append(replicationEndpointImpl).append(","); 328 builder.append("replicateAllUserTables=").append(replicateAllUserTables).append(","); 329 if (replicateAllUserTables) { 330 if (excludeNamespaces != null) { 331 builder.append("excludeNamespaces=").append(excludeNamespaces.toString()).append(","); 332 } 333 if (excludeTableCFsMap != null) { 334 builder.append("excludeTableCFsMap=").append(excludeTableCFsMap.toString()).append(","); 335 } 336 } else { 337 if (namespaces != null) { 338 builder.append("namespaces=").append(namespaces.toString()).append(","); 339 } 340 if (tableCFsMap != null) { 341 builder.append("tableCFs=").append(tableCFsMap.toString()).append(","); 342 } 343 } 344 builder.append("bandwidth=").append(bandwidth); 345 return builder.toString(); 346 } 347 348 /** 349 * Decide whether the table need replicate to the peer cluster 350 * @param table name of the table 351 * @return true if the table need replicate to the peer cluster 352 */ 353 public boolean needToReplicate(TableName table) { 354 if (replicateAllUserTables) { 355 if (excludeNamespaces != null && excludeNamespaces.contains(table.getNamespaceAsString())) { 356 return false; 357 } 358 if (excludeTableCFsMap != null && excludeTableCFsMap.containsKey(table)) { 359 return false; 360 } 361 return true; 362 } else { 363 if (namespaces != null && namespaces.contains(table.getNamespaceAsString())) { 364 return true; 365 } 366 if (tableCFsMap != null && tableCFsMap.containsKey(table)) { 367 return true; 368 } 369 return false; 370 } 371 } 372}