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.replication;
019
020import static org.apache.hadoop.hbase.replication.ReplicationPeerConfigTestUtil.assertConfigEquals;
021import static org.apache.hadoop.hbase.replication.ReplicationPeerConfigTestUtil.getConfig;
022import static org.junit.Assert.assertEquals;
023import static org.junit.Assert.assertFalse;
024import static org.junit.Assert.assertThrows;
025import static org.junit.Assert.fail;
026
027import java.util.List;
028import org.junit.Test;
029
030public abstract class ReplicationPeerStorageTestBase {
031
032  protected static ReplicationPeerStorage STORAGE;
033
034  @Test
035  public void test() throws ReplicationException {
036    int peerCount = 10;
037    for (int i = 0; i < peerCount; i++) {
038      STORAGE.addPeer(Integer.toString(i), getConfig(i), i % 2 == 0,
039        SyncReplicationState.valueOf(i % 4));
040    }
041    List<String> peerIds = STORAGE.listPeerIds();
042    assertEquals(peerCount, peerIds.size());
043    for (String peerId : peerIds) {
044      int seed = Integer.parseInt(peerId);
045      assertConfigEquals(getConfig(seed), STORAGE.getPeerConfig(peerId));
046    }
047    for (int i = 0; i < peerCount; i++) {
048      STORAGE.updatePeerConfig(Integer.toString(i), getConfig(i + 1));
049    }
050    for (String peerId : peerIds) {
051      int seed = Integer.parseInt(peerId);
052      assertConfigEquals(getConfig(seed + 1), STORAGE.getPeerConfig(peerId));
053    }
054    for (int i = 0; i < peerCount; i++) {
055      assertEquals(i % 2 == 0, STORAGE.isPeerEnabled(Integer.toString(i)));
056    }
057    for (int i = 0; i < peerCount; i++) {
058      STORAGE.setPeerState(Integer.toString(i), i % 2 != 0);
059    }
060    for (int i = 0; i < peerCount; i++) {
061      assertEquals(i % 2 != 0, STORAGE.isPeerEnabled(Integer.toString(i)));
062    }
063    for (int i = 0; i < peerCount; i++) {
064      assertEquals(SyncReplicationState.valueOf(i % 4),
065        STORAGE.getPeerSyncReplicationState(Integer.toString(i)));
066    }
067    String toRemove = Integer.toString(peerCount / 2);
068    STORAGE.removePeer(toRemove);
069    peerIds = STORAGE.listPeerIds();
070    assertEquals(peerCount - 1, peerIds.size());
071    assertFalse(peerIds.contains(toRemove));
072
073    try {
074      STORAGE.getPeerConfig(toRemove);
075      fail("Should throw a ReplicationException when getting peer config of a removed peer");
076    } catch (ReplicationException e) {
077    }
078  }
079
080  protected abstract void removePeerSyncRelicationState(String peerId) throws Exception;
081
082  protected abstract void assertPeerSyncReplicationStateCreate(String peerId) throws Exception;
083
084  @Test
085  public void testNoSyncReplicationState() throws Exception {
086    // This could happen for a peer created before we introduce sync replication.
087    String peerId = "testNoSyncReplicationState";
088    assertThrows("Should throw a ReplicationException when getting state of inexist peer",
089      ReplicationException.class, () -> STORAGE.getPeerSyncReplicationState(peerId));
090    assertThrows("Should throw a ReplicationException when getting state of inexist peer",
091      ReplicationException.class, () -> STORAGE.getPeerNewSyncReplicationState(peerId));
092
093    STORAGE.addPeer(peerId, getConfig(0), true, SyncReplicationState.NONE);
094    // delete the sync replication state node to simulate
095    removePeerSyncRelicationState(peerId);
096    // should not throw exception as the peer exists
097    assertEquals(SyncReplicationState.NONE, STORAGE.getPeerSyncReplicationState(peerId));
098    assertEquals(SyncReplicationState.NONE, STORAGE.getPeerNewSyncReplicationState(peerId));
099    // make sure we create the node for the old format peer
100    assertPeerSyncReplicationStateCreate(peerId);
101  }
102
103  protected abstract void assertPeerNameControlException(ReplicationException e);
104
105  @Test
106  public void testPeerNameControl() throws Exception {
107    String clusterKey = "key";
108    STORAGE.addPeer("6", ReplicationPeerConfig.newBuilder().setClusterKey(clusterKey).build(), true,
109      SyncReplicationState.NONE);
110
111    try {
112      ReplicationException e = assertThrows(ReplicationException.class,
113        () -> STORAGE.addPeer("6",
114          ReplicationPeerConfig.newBuilder().setClusterKey(clusterKey).build(), true,
115          SyncReplicationState.NONE));
116      assertPeerNameControlException(e);
117    } finally {
118      // clean up
119      STORAGE.removePeer("6");
120    }
121  }
122}