Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id EE181200CF2 for ; Sat, 2 Sep 2017 23:21:09 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id EC974164B12; Sat, 2 Sep 2017 21:21:09 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id F1122164B0E for ; Sat, 2 Sep 2017 23:21:08 +0200 (CEST) Received: (qmail 59452 invoked by uid 500); 2 Sep 2017 21:20:49 -0000 Mailing-List: contact common-commits-help@hadoop.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Delivered-To: mailing list common-commits@hadoop.apache.org Received: (qmail 56992 invoked by uid 99); 2 Sep 2017 21:20:47 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 02 Sep 2017 21:20:47 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id B6C18F5646; Sat, 2 Sep 2017 21:20:46 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: inigoiri@apache.org To: common-commits@hadoop.apache.org Date: Sat, 02 Sep 2017 21:21:30 -0000 Message-Id: In-Reply-To: <8979723b042845408c2d5ba79338af71@git.apache.org> References: <8979723b042845408c2d5ba79338af71@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [46/48] hadoop git commit: HDFS-10646. Federation admin tool. Contributed by Inigo Goiri. archived-at: Sat, 02 Sep 2017 21:21:10 -0000 http://git-wip-us.apache.org/repos/asf/hadoop/blob/37449af2/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterAdmin.java ---------------------------------------------------------------------- diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterAdmin.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterAdmin.java new file mode 100644 index 0000000..170247f --- /dev/null +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterAdmin.java @@ -0,0 +1,261 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hdfs.server.federation.router; + +import static org.apache.hadoop.hdfs.server.federation.store.FederationStateStoreTestUtils.synchronizeRecords; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hdfs.server.federation.RouterConfigBuilder; +import org.apache.hadoop.hdfs.server.federation.RouterDFSCluster.RouterContext; +import org.apache.hadoop.hdfs.server.federation.StateStoreDFSCluster; +import org.apache.hadoop.hdfs.server.federation.resolver.MountTableManager; +import org.apache.hadoop.hdfs.server.federation.resolver.RemoteLocation; +import org.apache.hadoop.hdfs.server.federation.store.StateStoreService; +import org.apache.hadoop.hdfs.server.federation.store.impl.MountTableStoreImpl; +import org.apache.hadoop.hdfs.server.federation.store.protocol.AddMountTableEntryRequest; +import org.apache.hadoop.hdfs.server.federation.store.protocol.AddMountTableEntryResponse; +import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesRequest; +import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesResponse; +import org.apache.hadoop.hdfs.server.federation.store.protocol.RemoveMountTableEntryRequest; +import org.apache.hadoop.hdfs.server.federation.store.protocol.UpdateMountTableEntryRequest; +import org.apache.hadoop.hdfs.server.federation.store.records.MountTable; +import org.apache.hadoop.util.Time; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * The administrator interface of the {@link Router} implemented by + * {@link RouterAdminServer}. + */ +public class TestRouterAdmin { + + private static StateStoreDFSCluster cluster; + private static RouterContext routerContext; + public static final String RPC_BEAN = + "Hadoop:service=Router,name=FederationRPC"; + private static List mockMountTable; + private static StateStoreService stateStore; + + @BeforeClass + public static void globalSetUp() throws Exception { + cluster = new StateStoreDFSCluster(false, 1); + // Build and start a router with State Store + admin + RPC + Configuration conf = new RouterConfigBuilder() + .stateStore() + .admin() + .rpc() + .build(); + cluster.addRouterOverrides(conf); + cluster.startRouters(); + routerContext = cluster.getRandomRouter(); + mockMountTable = cluster.generateMockMountTable(); + Router router = routerContext.getRouter(); + stateStore = router.getStateStore(); + } + + @AfterClass + public static void tearDown() { + cluster.stopRouter(routerContext); + } + + @Before + public void testSetup() throws Exception { + assertTrue( + synchronizeRecords(stateStore, mockMountTable, MountTable.class)); + } + + @Test + public void testAddMountTable() throws IOException { + MountTable newEntry = MountTable.newInstance( + "/testpath", Collections.singletonMap("ns0", "/testdir"), + Time.now(), Time.now()); + + RouterClient client = routerContext.getAdminClient(); + MountTableManager mountTable = client.getMountTableManager(); + + // Existing mount table size + List records = getMountTableEntries(mountTable); + assertEquals(records.size(), mockMountTable.size()); + + // Add + AddMountTableEntryRequest addRequest = + AddMountTableEntryRequest.newInstance(newEntry); + AddMountTableEntryResponse addResponse = + mountTable.addMountTableEntry(addRequest); + assertTrue(addResponse.getStatus()); + + // New mount table size + List records2 = getMountTableEntries(mountTable); + assertEquals(records2.size(), mockMountTable.size() + 1); + } + + @Test + public void testAddDuplicateMountTable() throws IOException { + MountTable newEntry = MountTable.newInstance("/testpath", + Collections.singletonMap("ns0", "/testdir"), Time.now(), Time.now()); + + RouterClient client = routerContext.getAdminClient(); + MountTableManager mountTable = client.getMountTableManager(); + + // Existing mount table size + List entries1 = getMountTableEntries(mountTable); + assertEquals(entries1.size(), mockMountTable.size()); + + // Add + AddMountTableEntryRequest addRequest = + AddMountTableEntryRequest.newInstance(newEntry); + AddMountTableEntryResponse addResponse = + mountTable.addMountTableEntry(addRequest); + assertTrue(addResponse.getStatus()); + + // New mount table size + List entries2 = getMountTableEntries(mountTable); + assertEquals(entries2.size(), mockMountTable.size() + 1); + + // Add again, should fail + AddMountTableEntryResponse addResponse2 = + mountTable.addMountTableEntry(addRequest); + assertFalse(addResponse2.getStatus()); + } + + @Test + public void testRemoveMountTable() throws IOException { + + RouterClient client = routerContext.getAdminClient(); + MountTableManager mountTable = client.getMountTableManager(); + + // Existing mount table size + List entries1 = getMountTableEntries(mountTable); + assertEquals(entries1.size(), mockMountTable.size()); + + // Remove an entry + RemoveMountTableEntryRequest removeRequest = + RemoveMountTableEntryRequest.newInstance("/"); + mountTable.removeMountTableEntry(removeRequest); + + // New mount table size + List entries2 = getMountTableEntries(mountTable); + assertEquals(entries2.size(), mockMountTable.size() - 1); + } + + @Test + public void testEditMountTable() throws IOException { + + RouterClient client = routerContext.getAdminClient(); + MountTableManager mountTable = client.getMountTableManager(); + + // Verify starting condition + MountTable entry = getMountTableEntry("/"); + assertEquals( + Collections.singletonList(new RemoteLocation("ns0", "/")), + entry.getDestinations()); + + // Edit the entry for / + MountTable updatedEntry = MountTable.newInstance( + "/", Collections.singletonMap("ns1", "/"), Time.now(), Time.now()); + UpdateMountTableEntryRequest updateRequest = + UpdateMountTableEntryRequest.newInstance(updatedEntry); + mountTable.updateMountTableEntry(updateRequest); + + // Verify edited condition + entry = getMountTableEntry("/"); + assertEquals( + Collections.singletonList(new RemoteLocation("ns1", "/")), + entry.getDestinations()); + } + + @Test + public void testGetMountTable() throws IOException { + + RouterClient client = routerContext.getAdminClient(); + MountTableManager mountTable = client.getMountTableManager(); + + // Verify size of table + List entries = getMountTableEntries(mountTable); + assertEquals(mockMountTable.size(), entries.size()); + + // Verify all entries are present + int matches = 0; + for (MountTable e : entries) { + for (MountTable entry : mockMountTable) { + assertEquals(e.getDestinations().size(), 1); + assertNotNull(e.getDateCreated()); + assertNotNull(e.getDateModified()); + if (entry.getSourcePath().equals(e.getSourcePath())) { + matches++; + } + } + } + assertEquals(matches, mockMountTable.size()); + } + + @Test + public void testGetSingleMountTableEntry() throws IOException { + MountTable entry = getMountTableEntry("/ns0"); + assertNotNull(entry); + assertEquals(entry.getSourcePath(), "/ns0"); + } + + /** + * Gets an existing mount table record in the state store. + * + * @param mount The mount point of the record to remove. + * @return The matching record if found, null if it is not found. + * @throws IOException If the state store could not be accessed. + */ + private MountTable getMountTableEntry(final String mount) throws IOException { + // Refresh the cache + stateStore.loadCache(MountTableStoreImpl.class, true); + + GetMountTableEntriesRequest request = + GetMountTableEntriesRequest.newInstance(mount); + RouterClient client = routerContext.getAdminClient(); + MountTableManager mountTable = client.getMountTableManager(); + List results = getMountTableEntries(mountTable, request); + if (results.size() > 0) { + // First result is sorted to have the shortest mount string length + return results.get(0); + } + return null; + } + + private List getMountTableEntries(MountTableManager mountTable) + throws IOException { + GetMountTableEntriesRequest request = + GetMountTableEntriesRequest.newInstance("/"); + return getMountTableEntries(mountTable, request); + } + + private List getMountTableEntries(MountTableManager mountTable, + GetMountTableEntriesRequest request) throws IOException { + stateStore.loadCache(MountTableStoreImpl.class, true); + GetMountTableEntriesResponse response = + mountTable.getMountTableEntries(request); + return response.getEntries(); + } +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org For additional commands, e-mail: common-commits-help@hadoop.apache.org