001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.client.replication; 020 021import java.io.Closeable; 022import java.io.IOException; 023import java.util.ArrayList; 024import java.util.Collection; 025import java.util.HashMap; 026import java.util.List; 027import java.util.Map; 028import java.util.TreeMap; 029import java.util.regex.Pattern; 030import org.apache.hadoop.conf.Configuration; 031import org.apache.hadoop.hbase.HConstants; 032import org.apache.hadoop.hbase.ReplicationPeerNotFoundException; 033import org.apache.hadoop.hbase.TableName; 034import org.apache.hadoop.hbase.client.Admin; 035import org.apache.hadoop.hbase.client.Connection; 036import org.apache.hadoop.hbase.client.ConnectionFactory; 037import org.apache.hadoop.hbase.replication.ReplicationException; 038import org.apache.hadoop.hbase.replication.ReplicationPeerConfig; 039import org.apache.hadoop.hbase.replication.ReplicationPeerDescription; 040import org.apache.yetus.audience.InterfaceAudience; 041import org.slf4j.Logger; 042import org.slf4j.LoggerFactory; 043 044import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; 045import org.apache.hbase.thirdparty.com.google.common.collect.Lists; 046 047/** 048 * <p> 049 * This class provides the administrative interface to HBase cluster 050 * replication. 051 * </p> 052 * <p> 053 * Adding a new peer results in creating new outbound connections from every 054 * region server to a subset of region servers on the slave cluster. Each 055 * new stream of replication will start replicating from the beginning of the 056 * current WAL, meaning that edits from that past will be replicated. 057 * </p> 058 * <p> 059 * Removing a peer is a destructive and irreversible operation that stops 060 * all the replication streams for the given cluster and deletes the metadata 061 * used to keep track of the replication state. 062 * </p> 063 * <p> 064 * To see which commands are available in the shell, type 065 * <code>replication</code>. 066 * </p> 067 * 068 * @deprecated use {@link org.apache.hadoop.hbase.client.Admin} instead. 069 */ 070@InterfaceAudience.Public 071@Deprecated 072public class ReplicationAdmin implements Closeable { 073 private static final Logger LOG = LoggerFactory.getLogger(ReplicationAdmin.class); 074 075 public static final String TNAME = "tableName"; 076 public static final String CFNAME = "columnFamilyName"; 077 078 // only Global for now, can add other type 079 // such as, 1) no global replication, or 2) the table is replicated to this cluster, etc. 080 public static final String REPLICATIONTYPE = "replicationType"; 081 public static final String REPLICATIONGLOBAL = Integer 082 .toString(HConstants.REPLICATION_SCOPE_GLOBAL); 083 084 private final Connection connection; 085 private Admin admin; 086 087 /** 088 * Constructor that creates a connection to the local ZooKeeper ensemble. 089 * @param conf Configuration to use 090 * @throws IOException if an internal replication error occurs 091 * @throws RuntimeException if replication isn't enabled. 092 */ 093 public ReplicationAdmin(Configuration conf) throws IOException { 094 this.connection = ConnectionFactory.createConnection(conf); 095 admin = connection.getAdmin(); 096 } 097 098 /** 099 * Add a new remote slave cluster for replication. 100 * @param id a short name that identifies the cluster 101 * @param peerConfig configuration for the replication slave cluster 102 * @param tableCfs the table and column-family list which will be replicated for this peer. 103 * A map from tableName to column family names. An empty collection can be passed 104 * to indicate replicating all column families. Pass null for replicating all table and column 105 * families 106 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0, 107 * use {@link #addPeer(String, ReplicationPeerConfig)} instead. 108 */ 109 @Deprecated 110 public void addPeer(String id, ReplicationPeerConfig peerConfig, 111 Map<TableName, ? extends Collection<String>> tableCfs) throws ReplicationException, 112 IOException { 113 if (tableCfs != null) { 114 peerConfig.setTableCFsMap(tableCfs); 115 } 116 this.admin.addReplicationPeer(id, peerConfig); 117 } 118 119 /** 120 * Add a new remote slave cluster for replication. 121 * @param id a short name that identifies the cluster 122 * @param peerConfig configuration for the replication slave cluster 123 * @deprecated use 124 * {@link org.apache.hadoop.hbase.client.Admin#addReplicationPeer(String, ReplicationPeerConfig)} 125 * instead 126 */ 127 @Deprecated 128 public void addPeer(String id, ReplicationPeerConfig peerConfig) throws ReplicationException, 129 IOException { 130 this.admin.addReplicationPeer(id, peerConfig); 131 } 132 133 /** 134 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0 135 * */ 136 @Deprecated 137 public static Map<TableName, List<String>> parseTableCFsFromConfig(String tableCFsConfig) { 138 return ReplicationPeerConfigUtil.parseTableCFsFromConfig(tableCFsConfig); 139 } 140 141 /** 142 * @deprecated use 143 * {@link org.apache.hadoop.hbase.client.Admin#updateReplicationPeerConfig(String, ReplicationPeerConfig)} 144 * instead 145 */ 146 @Deprecated 147 public void updatePeerConfig(String id, ReplicationPeerConfig peerConfig) throws IOException { 148 this.admin.updateReplicationPeerConfig(id, peerConfig); 149 } 150 151 /** 152 * Removes a peer cluster and stops the replication to it. 153 * @param id a short name that identifies the cluster 154 * @deprecated use {@link org.apache.hadoop.hbase.client.Admin#removeReplicationPeer(String)} instead 155 */ 156 @Deprecated 157 public void removePeer(String id) throws IOException { 158 this.admin.removeReplicationPeer(id); 159 } 160 161 /** 162 * Restart the replication stream to the specified peer. 163 * @param id a short name that identifies the cluster 164 * @deprecated use {@link org.apache.hadoop.hbase.client.Admin#enableReplicationPeer(String)} 165 * instead 166 */ 167 @Deprecated 168 public void enablePeer(String id) throws IOException { 169 this.admin.enableReplicationPeer(id); 170 } 171 172 /** 173 * Stop the replication stream to the specified peer. 174 * @param id a short name that identifies the cluster 175 * @deprecated use {@link org.apache.hadoop.hbase.client.Admin#disableReplicationPeer(String)} 176 * instead 177 */ 178 @Deprecated 179 public void disablePeer(String id) throws IOException { 180 this.admin.disableReplicationPeer(id); 181 } 182 183 /** 184 * Get the number of slave clusters the local cluster has. 185 * @return number of slave clusters 186 * @throws IOException 187 * @deprecated 188 */ 189 @Deprecated 190 public int getPeersCount() throws IOException { 191 return this.admin.listReplicationPeers().size(); 192 } 193 194 /** 195 * @deprecated use {@link org.apache.hadoop.hbase.client.Admin#listReplicationPeers()} instead 196 */ 197 @Deprecated 198 public Map<String, ReplicationPeerConfig> listPeerConfigs() throws IOException { 199 List<ReplicationPeerDescription> peers = this.admin.listReplicationPeers(); 200 Map<String, ReplicationPeerConfig> result = new TreeMap<>(); 201 for (ReplicationPeerDescription peer : peers) { 202 result.put(peer.getPeerId(), peer.getPeerConfig()); 203 } 204 return result; 205 } 206 207 /** 208 * @deprecated use {@link org.apache.hadoop.hbase.client.Admin#getReplicationPeerConfig(String)} 209 * instead 210 */ 211 @Deprecated 212 public ReplicationPeerConfig getPeerConfig(String id) throws IOException { 213 return admin.getReplicationPeerConfig(id); 214 } 215 216 /** 217 * Get the replicable table-cf config of the specified peer. 218 * @param id a short name that identifies the cluster 219 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0, 220 * use {@link #getPeerConfig(String)} instead. 221 * */ 222 @Deprecated 223 public String getPeerTableCFs(String id) throws IOException { 224 ReplicationPeerConfig peerConfig = admin.getReplicationPeerConfig(id); 225 return ReplicationPeerConfigUtil.convertToString(peerConfig.getTableCFsMap()); 226 } 227 228 /** 229 * Append the replicable table-cf config of the specified peer 230 * @param id a short that identifies the cluster 231 * @param tableCfs table-cfs config str 232 * @throws ReplicationException 233 * @throws IOException 234 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0, 235 * use {@link #appendPeerTableCFs(String, Map)} instead. 236 */ 237 @Deprecated 238 public void appendPeerTableCFs(String id, String tableCfs) throws ReplicationException, 239 IOException { 240 appendPeerTableCFs(id, ReplicationPeerConfigUtil.parseTableCFsFromConfig(tableCfs)); 241 } 242 243 /** 244 * Append the replicable table-cf config of the specified peer 245 * @param id a short that identifies the cluster 246 * @param tableCfs A map from tableName to column family names 247 * @throws ReplicationException 248 * @throws IOException 249 */ 250 @Deprecated 251 public void appendPeerTableCFs(String id, Map<TableName, ? extends Collection<String>> tableCfs) 252 throws ReplicationException, IOException { 253 this.admin.appendReplicationPeerTableCFs(id, copyTableCFs(tableCfs)); 254 } 255 256 /** 257 * Remove some table-cfs from table-cfs config of the specified peer 258 * @param id a short name that identifies the cluster 259 * @param tableCf table-cfs config str 260 * @throws ReplicationException 261 * @throws IOException 262 * @deprecated as release of 2.0.0, and it will be removed in 3.0.0, 263 * use {@link #removePeerTableCFs(String, Map)} instead. 264 */ 265 @Deprecated 266 public void removePeerTableCFs(String id, String tableCf) throws ReplicationException, 267 IOException { 268 removePeerTableCFs(id, ReplicationPeerConfigUtil.parseTableCFsFromConfig(tableCf)); 269 } 270 271 /** 272 * Remove some table-cfs from config of the specified peer 273 * @param id a short name that identifies the cluster 274 * @param tableCfs A map from tableName to column family names 275 * @throws ReplicationException 276 * @throws IOException 277 */ 278 @Deprecated 279 public void removePeerTableCFs(String id, Map<TableName, ? extends Collection<String>> tableCfs) 280 throws ReplicationException, IOException { 281 this.admin.removeReplicationPeerTableCFs(id, copyTableCFs(tableCfs)); 282 } 283 284 private Map<TableName, List<String>> 285 copyTableCFs(Map<TableName, ? extends Collection<String>> tableCfs) { 286 Map<TableName, List<String>> newTableCfs = new HashMap<>(); 287 if (tableCfs != null) { 288 tableCfs.forEach( 289 (table, cfs) -> newTableCfs.put(table, cfs != null ? Lists.newArrayList(cfs) : null)); 290 } 291 return newTableCfs; 292 } 293 294 /** 295 * Set the replicable table-cf config of the specified peer 296 * @param id a short name that identifies the cluster 297 * @param tableCfs the table and column-family list which will be replicated for this peer. 298 * A map from tableName to column family names. An empty collection can be passed 299 * to indicate replicating all column families. Pass null for replicating all table and column 300 * families 301 */ 302 @Deprecated 303 public void setPeerTableCFs(String id, Map<TableName, ? extends Collection<String>> tableCfs) 304 throws IOException { 305 ReplicationPeerConfig peerConfig = getPeerConfig(id); 306 peerConfig.setTableCFsMap(tableCfs); 307 updatePeerConfig(id, peerConfig); 308 } 309 310 /** 311 * Get the state of the specified peer cluster 312 * @param id String format of the Short name that identifies the peer, 313 * an IllegalArgumentException is thrown if it doesn't exist 314 * @return true if replication is enabled to that peer, false if it isn't 315 */ 316 @Deprecated 317 public boolean getPeerState(String id) throws ReplicationException, IOException { 318 List<ReplicationPeerDescription> peers = admin.listReplicationPeers(Pattern.compile(id)); 319 if (peers.isEmpty() || !id.equals(peers.get(0).getPeerId())) { 320 throw new ReplicationPeerNotFoundException(id); 321 } 322 return peers.get(0).isEnabled(); 323 } 324 325 @Override 326 public void close() throws IOException { 327 if (this.connection != null) { 328 this.connection.close(); 329 } 330 admin.close(); 331 } 332 333 /** 334 * Find all column families that are replicated from this cluster 335 * @return the full list of the replicated column families of this cluster as: 336 * tableName, family name, replicationType 337 * 338 * Currently replicationType is Global. In the future, more replication 339 * types may be extended here. For example 340 * 1) the replication may only apply to selected peers instead of all peers 341 * 2) the replicationType may indicate the host Cluster servers as Slave 342 * for the table:columnFam. 343 * @deprecated use {@link org.apache.hadoop.hbase.client.Admin#listReplicatedTableCFs()} instead 344 */ 345 @Deprecated 346 public List<HashMap<String, String>> listReplicated() throws IOException { 347 List<HashMap<String, String>> replicationColFams = new ArrayList<>(); 348 admin.listReplicatedTableCFs().forEach( 349 (tableCFs) -> { 350 String table = tableCFs.getTable().getNameAsString(); 351 tableCFs.getColumnFamilyMap() 352 .forEach( 353 (cf, scope) -> { 354 HashMap<String, String> replicationEntry = new HashMap<>(); 355 replicationEntry.put(TNAME, table); 356 replicationEntry.put(CFNAME, cf); 357 replicationEntry.put(REPLICATIONTYPE, REPLICATIONGLOBAL); 358 replicationColFams.add(replicationEntry); 359 }); 360 }); 361 return replicationColFams; 362 } 363 364 /** 365 * Enable a table's replication switch. 366 * @param tableName name of the table 367 * @throws IOException if a remote or network exception occurs 368 * @deprecated use {@link org.apache.hadoop.hbase.client.Admin#enableTableReplication(TableName)} 369 * instead 370 */ 371 @Deprecated 372 public void enableTableRep(final TableName tableName) throws IOException { 373 admin.enableTableReplication(tableName); 374 } 375 376 /** 377 * Disable a table's replication switch. 378 * @param tableName name of the table 379 * @throws IOException if a remote or network exception occurs 380 * @deprecated use {@link org.apache.hadoop.hbase.client.Admin#disableTableReplication(TableName)} 381 * instead 382 */ 383 @Deprecated 384 public void disableTableRep(final TableName tableName) throws IOException { 385 admin.disableTableReplication(tableName); 386 } 387 388 /** 389 * @deprecated use {@link org.apache.hadoop.hbase.client.Admin#listReplicationPeers()} instead 390 */ 391 @VisibleForTesting 392 @Deprecated 393 List<ReplicationPeerDescription> listReplicationPeers() throws IOException { 394 return admin.listReplicationPeers(); 395 } 396}