org.apache.falcon.validation.ClusterEntityValidationIT.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.falcon.validation.ClusterEntityValidationIT.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.falcon.validation;

import com.sun.jersey.api.client.ClientResponse;
import org.apache.falcon.entity.ClusterHelper;
import org.apache.falcon.entity.parser.ClusterEntityParser;
import org.apache.falcon.entity.parser.EntityParserFactory;
import org.apache.falcon.entity.parser.ValidationException;
import org.apache.falcon.entity.v0.EntityType;
import org.apache.falcon.entity.v0.cluster.ACL;
import org.apache.falcon.entity.v0.cluster.Cluster;
import org.apache.falcon.entity.v0.cluster.ClusterLocationType;
import org.apache.falcon.entity.v0.cluster.Interface;
import org.apache.falcon.entity.v0.cluster.Interfacetype;
import org.apache.falcon.hadoop.HadoopClientFactory;
import org.apache.falcon.resource.TestContext;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsAction;
import org.apache.hadoop.fs.permission.FsPermission;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

/**
 * Tests cluster entity validation to verify if each of the specified
 * interface endpoints are valid.
 */
public class ClusterEntityValidationIT {
    private static final FsPermission OWNER_ONLY_PERMISSION = new FsPermission(FsAction.ALL, FsAction.NONE,
            FsAction.NONE);

    private final TestContext context = new TestContext();
    private Map<String, String> overlay;

    private final ClusterEntityParser parser = (ClusterEntityParser) EntityParserFactory
            .getParser(EntityType.CLUSTER);
    private Cluster cluster;
    private FileSystem fs;

    @BeforeClass
    public void setup() throws Exception {
        TestContext.prepare();

        overlay = context.getUniqueOverlay();
        String filePath = TestContext.overlayParametersOverTemplate(TestContext.CLUSTER_TEMPLATE, overlay);
        context.setCluster(filePath);
        InputStream stream = new FileInputStream(filePath);
        cluster = (Cluster) EntityType.CLUSTER.getUnmarshaller().unmarshal(stream);
        Assert.assertNotNull(cluster);

        fs = FileSystem.get(ClusterHelper.getConfiguration(cluster));
    }

    @AfterClass
    public void tearDown() throws Exception {
        TestContext.deleteEntitiesFromStore();
    }

    /**
     * Positive test.
     *
     * @throws Exception
     */
    @Test
    public void testClusterEntityWithValidInterfaces() throws Exception {
        overlay = context.getUniqueOverlay();
        overlay.put("colo", "default");
        ClientResponse response = context.submitToFalcon(TestContext.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
        context.assertSuccessful(response);
    }

    @DataProvider(name = "interfaceToInvalidURLs")
    public Object[][] createInterfaceToInvalidURLData() {
        return new Object[][] {
                // TODO FileSystem validates invalid hftp url, does NOT fail
                // {Interfacetype.READONLY, "hftp://localhost:41119"},
                { Interfacetype.READONLY, "" }, { Interfacetype.READONLY, "localhost:41119" },
                { Interfacetype.WRITE, "write-interface:9999" },
                { Interfacetype.WRITE, "hdfs://write-interface:9999" },
                { Interfacetype.EXECUTE, "execute-interface:9999" },
                { Interfacetype.WORKFLOW, "workflow-interface:9999/oozie/" },
                { Interfacetype.WORKFLOW, "http://workflow-interface:9999/oozie/" },
                { Interfacetype.MESSAGING, "messaging-interface:9999" },
                { Interfacetype.MESSAGING, "tcp://messaging-interface:9999" },
                { Interfacetype.REGISTRY, "catalog-interface:9999" },
                { Interfacetype.REGISTRY, "http://catalog-interface:9999" }, };
    }

    @Test(dataProvider = "interfaceToInvalidURLs")
    public void testClusterEntityWithInvalidInterfaces(Interfacetype interfacetype, String endpoint)
            throws Exception {
        overlay = context.getUniqueOverlay();
        String filePath = TestContext.overlayParametersOverTemplate(TestContext.CLUSTER_TEMPLATE, overlay);
        InputStream stream = new FileInputStream(filePath);
        Cluster clusterEntity = (Cluster) EntityType.CLUSTER.getUnmarshaller().unmarshal(stream);
        Assert.assertNotNull(clusterEntity);
        clusterEntity.setColo("default"); // validations will be ignored if not default & tests fail

        Interface anInterface = ClusterHelper.getInterface(clusterEntity, interfacetype);
        anInterface.setEndpoint(endpoint);

        File tmpFile = TestContext.getTempFile();
        EntityType.CLUSTER.getMarshaller().marshal(clusterEntity, tmpFile);
        System.out.println("Starting Interface type " + interfacetype + "Endpoint " + endpoint);
        ClientResponse response = context.submitFileToFalcon(EntityType.CLUSTER, tmpFile.getAbsolutePath());
        context.assertFailure(response);
        System.out.println("Completed Interface type " + interfacetype + "Endpoint " + endpoint);
    }

    @Test
    public void testValidateACL() throws Exception {
        overlay = context.getUniqueOverlay();
        String filePath = TestContext.overlayParametersOverTemplate(TestContext.CLUSTER_TEMPLATE, overlay);
        InputStream stream = new FileInputStream(filePath);
        Cluster clusterEntity = (Cluster) EntityType.CLUSTER.getUnmarshaller().unmarshal(stream);
        Assert.assertNotNull(clusterEntity);

        // Adding ACL with authorization disabled must not hurt
        ACL clusterACL = new ACL();
        clusterACL.setOwner(TestContext.REMOTE_USER);
        clusterACL.setGroup(TestContext.REMOTE_USER);
        clusterEntity.setACL(clusterACL);

        clusterEntity.setColo("default"); // validations will be ignored if not default & tests fail

        File tmpFile = TestContext.getTempFile();
        EntityType.CLUSTER.getMarshaller().marshal(clusterEntity, tmpFile);
        ClientResponse response = context.submitFileToFalcon(EntityType.CLUSTER, tmpFile.getAbsolutePath());
        context.assertSuccessful(response);
    }

    @Test
    public void testValidateClusterLocations() throws Exception {
        TestContext.createClusterLocations(cluster, fs);
        parser.validate(cluster);
    }

    @Test
    public void testValidateClusterLocationsWithoutWorking() throws Exception {
        overlay = context.getUniqueOverlay();
        String filePath = TestContext.overlayParametersOverTemplate(TestContext.CLUSTER_TEMPLATE, overlay);
        InputStream stream = new FileInputStream(filePath);
        Cluster clusterEntity = (Cluster) EntityType.CLUSTER.getUnmarshaller().unmarshal(stream);
        clusterEntity.getLocations().getLocations().remove(2);
        FileSystem clusterFileSystem = FileSystem.get(ClusterHelper.getConfiguration(cluster));
        TestContext.createClusterLocations(clusterEntity, clusterFileSystem, false);
        parser.validate(clusterEntity);
        String expectedPath = ClusterHelper.getLocation(clusterEntity, ClusterLocationType.STAGING).getPath()
                + "/working";
        Assert.assertEquals(ClusterHelper.getLocation(clusterEntity, ClusterLocationType.WORKING).getPath(),
                expectedPath);
        Assert.assertTrue(clusterFileSystem.getFileLinkStatus(new Path(expectedPath)).isDirectory());
        Assert.assertEquals(clusterFileSystem.getFileLinkStatus(new Path(expectedPath)).getPermission(),
                HadoopClientFactory.READ_EXECUTE_PERMISSION);
    }

    @Test(expectedExceptions = ValidationException.class)
    public void testValidateClusterLocationsThatDontExist() throws Exception {
        TestContext.deleteClusterLocations(cluster, fs);
        parser.validate(cluster);
        Assert.fail("Should have thrown a validation exception");
    }

    @Test(expectedExceptions = ValidationException.class)
    public void testValidateClusterLocationsThatExistWithBadOwner() throws Exception {
        createClusterLocationsBadPermissions(cluster);
        parser.validate(cluster);
        Assert.fail("Should have thrown a validation exception");
    }

    private void createClusterLocationsBadPermissions(Cluster clusterEntity) throws IOException {
        FileSystem clusterFileSystem = FileSystem.get(ClusterHelper.getConfiguration(clusterEntity));
        TestContext.deleteClusterLocations(clusterEntity, clusterFileSystem);
        String stagingLocation = ClusterHelper.getLocation(clusterEntity, ClusterLocationType.STAGING).getPath();
        Path stagingPath = new Path(stagingLocation);
        FileSystem.mkdirs(clusterFileSystem, stagingPath, OWNER_ONLY_PERMISSION);

        String workingLocation = ClusterHelper.getLocation(clusterEntity, ClusterLocationType.WORKING).getPath();
        Path workingPath = new Path(workingLocation);
        FileSystem.mkdirs(clusterFileSystem, stagingPath, OWNER_ONLY_PERMISSION);
    }
}