org.apache.hadoop.hdfs.server.namenode.TestAvatarStorageSetup.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.hdfs.server.namenode.TestAvatarStorageSetup.java

Source

/**
 * 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.namenode;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.hdfs.protocol.AvatarConstants.InstanceId;
import org.apache.hadoop.hdfs.server.common.Util;
import org.apache.hadoop.hdfs.server.namenode.AvatarNode.StartupInfo;
import org.apache.hadoop.hdfs.server.namenode.JournalStream.JournalType;
import org.apache.hadoop.hdfs.server.namenode.NNStorage.StorageLocationType;
import org.apache.hadoop.hdfs.server.namenode.ValidateNamespaceDirPolicy.NNStorageLocation;
import org.junit.Before;
import org.junit.Test;

public class TestAvatarStorageSetup {

    public static final Log LOG = LogFactory.getLog(TestAvatarStorageSetup.class.getName());

    private static String baseDir = System.getProperty("test.build.data", "build/test/data/") + "/";

    // names for image/edits
    private final String imageLclName = baseDir + "image/";
    private final String imageShdName0 = baseDir + "imageShared0/";
    private final String imageShdName1 = baseDir + "imageShared1/";

    private final String editsLclName = baseDir + "edits/";
    private final String editsShdName0 = baseDir + "editsShared0/";
    private final String editsShdName1 = baseDir + "editsShared1/";

    // usr's for image/edits
    private URI imageLcl, imageShd0, imageShd1;
    private URI editsLcl, editsShd0, editsShd1;

    private Configuration conf;

    @Before
    public void setUp() throws Exception {
        Collection<String> dirList = new ArrayList<String>();
        dirList.add(imageLclName);
        dirList.add(imageShdName0);
        dirList.add(imageShdName1);
        dirList.add(editsLclName);
        dirList.add(editsShdName0);
        dirList.add(editsShdName1);

        for (String name : dirList) {
            File dir = new File(name);
            FileUtil.fullyDelete(dir);
            dir.mkdirs();
        }

        imageLcl = Util.stringAsURI(imageLclName);
        imageShd0 = Util.stringAsURI(imageShdName0);
        imageShd1 = Util.stringAsURI(imageShdName1);

        editsLcl = Util.stringAsURI(editsLclName);
        editsShd0 = Util.stringAsURI(editsShdName0);
        editsShd1 = Util.stringAsURI(editsShdName1);

        conf = new Configuration();
    }

    @Test
    public void testStringToUris() {
        // set strings in configuration
        conf.set("dfs.name.dir", imageLclName + "," + imageShdName0);
        conf.set("dfs.name.edits.dir", editsLclName + "," + editsShdName0);

        Collection<URI> dirs = NNStorageConfiguration.getNamespaceDirs(conf, null);
        // check if conversion to URIs is correct
        assertEqualsCol(getList(imageLcl, imageShd0), dirs);

        dirs = NNStorageConfiguration.getNamespaceEditsDirs(conf, null);
        // check if conversion to URIs is correct
        assertEqualsCol(getList(editsLcl, editsShd0), dirs);
    }

    // test parameter correctness

    @Test(expected = IOException.class)
    public void sharedImageShoudlNotOverlap() throws IOException {
        // dfs.name.dir already contains the shared directory
        AvatarStorageSetup.validate(conf, getList(imageLcl, imageShd0), getList(editsLcl), imageShd0, imageShd1,
                editsShd0, editsShd1);
    }

    @Test(expected = IOException.class)
    public void sharedImageQJMNotEqualToEdits() throws IOException, URISyntaxException {
        // QJM shared image location
        URI qjmSharedImage = new URI("qjm://testjournalImage");
        URI qjmSharedJournal = new URI("qjm://testjournalJournal");

        AvatarStorageSetup.validate(conf, getList(imageLcl), getList(editsLcl), qjmSharedImage, imageShd1,
                qjmSharedJournal, editsShd1);
    }

    @Test
    public void sharedImageQJM() throws IOException, URISyntaxException {
        // QJM shared image location
        URI qjmShared = new URI("qjm://testjournal");

        AvatarStorageSetup.validate(conf, getList(imageLcl), getList(editsLcl), qjmShared, imageShd1, qjmShared,
                editsShd1);
    }

    @Test(expected = IOException.class)
    public void sharedEditsShoudlNotOverlap() throws IOException {
        // dfs.name.edits.dir already contains the shared directory
        AvatarStorageSetup.validate(conf, getList(imageLcl), getList(editsLcl, editsShd0), imageShd0, imageShd1,
                editsShd0, editsShd1);
    }

    @Test(expected = IOException.class)
    public void shouldNotContainSharedImageLocation() throws IOException {
        // dfs.name.dir.shared is set manually
        conf.set("dfs.name.dir.shared", "/somelocation");
        AvatarStorageSetup.validate(conf, getList(imageLcl), getList(editsLcl), imageShd0, imageShd1, editsShd0,
                editsShd1);
    }

    @Test(expected = IOException.class)
    public void shouldNotContainSharedEditsLocation() throws IOException {
        // dfs.name.edits.dir.shared is set manually
        conf.set("dfs.name.edits.dir.shared", "/somelocation");
        AvatarStorageSetup.validate(conf, getList(imageLcl), getList(editsLcl), imageShd0, imageShd1, editsShd0,
                editsShd1);
    }

    @Test(expected = IOException.class)
    public void shouldNotContainNulls() throws IOException {
        conf.set("dfs.name.edits.dir.shared", "/somelocation");
        AvatarStorageSetup.validate(conf, getList(imageLcl), getList(editsLcl), null, imageShd1, editsShd0,
                editsShd1);
    }

    // test configuration setup

    @Test
    public void testSetup() throws IOException {
        Configuration newconf = null;

        // validate
        AvatarStorageSetup.validate(conf, getList(imageLcl), getList(editsLcl), imageShd0, imageShd1, editsShd0,
                editsShd1);

        // update configuration for nodezero
        newconf = new Configuration();
        StartupInfo startInfoZero = new StartupInfo(null, InstanceId.NODEZERO, false, "service", false);
        updateConf(startInfoZero, newconf);

        // check configuration
        assertEqualsCol(getList(imageLcl, imageShd0), NNStorageConfiguration.getNamespaceDirs(newconf, null));
        assertEqualsCol(getList(editsLcl, editsShd0), NNStorageConfiguration.getNamespaceEditsDirs(newconf, null));

        // check shared directory
        checkKey(imageShd0, "dfs.name.dir.shared", newconf);
        checkKey(editsShd0, "dfs.name.edits.dir.shared", newconf);

        // update configuration for nodeone
        newconf = new Configuration();
        StartupInfo startInfoOne = new StartupInfo(null, InstanceId.NODEONE, true, "service", false);
        updateConf(startInfoOne, newconf);

        // check configuration
        assertEqualsCol(getList(imageLcl, imageShd1), NNStorageConfiguration.getNamespaceDirs(newconf, null));
        assertEqualsCol(getList(editsLcl, editsShd1), NNStorageConfiguration.getNamespaceEditsDirs(newconf, null));

        // check shared directory
        checkKey(imageShd1, "dfs.name.dir.shared", newconf);
        checkKey(editsShd1, "dfs.name.edits.dir.shared", newconf);
    }

    @Test
    public void testLocationMapForFiles() throws IOException {
        // standard configuration with all file journal/images
        testLocationMap(conf, imageLcl, imageShd0, imageShd1, editsLcl, editsShd0, editsShd1);
    }

    @Test
    public void testLocationMapForNonFiles() throws Exception {
        // configure non-file journals
        // local image and edits must be file-based
        editsShd0 = Util.stringAsURI("foo:/editsshd0");
        editsShd1 = Util.stringAsURI("foo:/editsshd1");

        testLocationMap(conf, imageLcl, imageShd0, imageShd1, editsLcl, editsShd0, editsShd1);
    }

    public void testLocationMap(Configuration conf, URI imageLcl, URI imageShd0, URI imageShd1, URI editsLcl,
            URI editsShd0, URI editsShd1) throws IOException {
        Configuration newconf = null;

        // validate
        AvatarStorageSetup.validate(conf, getList(imageLcl), getList(editsLcl), imageShd0, imageShd1, editsShd0,
                editsShd1);

        // update configuration for nodezero
        newconf = new Configuration();
        StartupInfo startInfoZero = new StartupInfo(null, InstanceId.NODEZERO, false, "service", false);
        updateConf(startInfoZero, newconf);

        // validate
        Map<URI, NNStorageLocation> map = ValidateNamespaceDirPolicy.validate(newconf);

        // shared image and edits
        assertTrue(map.get(imageShd0).type == StorageLocationType.SHARED);
        assertTrue(map.get(editsShd0).type == StorageLocationType.SHARED);

        // local are not shared
        Collection<URI> l = getList(imageLcl, editsLcl);
        for (URI u : l) {
            if ((u.getScheme().compareTo(JournalType.FILE.name().toLowerCase()) == 0))
                assertTrue(map.get(editsLcl).type == StorageLocationType.LOCAL);
            else
                assertTrue(map.get(editsLcl).type == StorageLocationType.REMOTE);
        }

        // all locations are present
        for (URI u : getList(imageLcl, imageShd0, editsLcl, editsShd0)) {
            assertNotNull(map.get(u));
        }
    }

    @Test
    public void testSameSharedImageLocation() throws Exception {

        Configuration conf = new Configuration();

        URI img0 = new URI("qjm://localhost:1234;localhost:1235;localhost:1236/test-id/");
        URI img1 = new URI("qjm://localhost:1234;localhost:1235;localhost:1236/test-id/");
        URI edit0 = new URI("qjm://localhost:1234;localhost:1235;localhost:1236/test-id/zero/");
        URI edit1 = new URI("qjm://localhost:1234;localhost:1235;localhost:1236/test-id/one/");
        conf.set("dfs.name.dir.shared0", img0.toString());
        conf.set("dfs.name.dir.shared1", img1.toString());
        conf.set("dfs.name.edits.dir.shared0", edit0.toString());
        conf.set("dfs.name.edits.dir.shared1", edit1.toString());

        // local locations for image and edits
        Collection<URI> namedirs = NNStorageConfiguration.getNamespaceDirs(conf, null);
        Collection<URI> editsdir = NNStorageConfiguration.getNamespaceEditsDirs(conf, null);

        try {
            AvatarStorageSetup.validate(conf, namedirs, editsdir, img0, img1, edit0, edit1);
            fail("fail of same shared image location");
        } catch (IOException ex) {
            assertTrue(ex.getMessage().contains("same image location"));
        }
    }

    @Test
    public void testSameSharedEditsLocation() throws Exception {

        Configuration conf = new Configuration();

        URI img0 = new URI("qjm://localhost:1234;localhost:1235;localhost:1236/test-id/zero/");
        URI img1 = new URI("qjm://localhost:1234;localhost:1235;localhost:1236/test-id/one/");
        URI edit0 = new URI("qjm://localhost:1234;localhost:1235;localhost:1236/test-id/");
        URI edit1 = new URI("qjm://localhost:1234;localhost:1235;localhost:1236/test-id/");
        conf.set("dfs.name.dir.shared0", img0.toString());
        conf.set("dfs.name.dir.shared1", img1.toString());
        conf.set("dfs.name.edits.dir.shared0", edit0.toString());
        conf.set("dfs.name.edits.dir.shared1", edit1.toString());

        // local locations for image and edits
        Collection<URI> namedirs = NNStorageConfiguration.getNamespaceDirs(conf, null);
        Collection<URI> editsdir = NNStorageConfiguration.getNamespaceEditsDirs(conf, null);

        try {
            AvatarStorageSetup.validate(conf, namedirs, editsdir, img0, img1, edit0, edit1);
            fail("fail of same shared eduts location");
        } catch (IOException ex) {
            assertTrue(ex.getMessage().contains("same edits location"));
        }
    }

    ///// helpers

    private void checkKey(URI expected, String key, Configuration conf) throws IOException {
        assertEquals(expected, Util.stringAsURI(conf.get(key)));
    }

    private void updateConf(StartupInfo si, Configuration newconf) {
        AvatarStorageSetup.updateConf(si, newconf, getList(imageLcl), imageShd0, imageShd1, "dfs.name.dir");
        AvatarStorageSetup.updateConf(si, newconf, getList(editsLcl), editsShd0, editsShd1, "dfs.name.edits.dir");
    }

    private void assertEqualsCol(Collection<URI> obj1, Collection<URI> obj2) {
        assertTrue(obj1.containsAll(obj2));
        assertTrue(obj2.containsAll(obj1));
    }

    private Collection<URI> getList(URI... uris) {
        List<URI> result = new ArrayList<URI>();
        for (URI u : uris) {
            result.add(u);
        }
        return result;
    }
}