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

Java tutorial

Introduction

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

Source

/*
 * Copyright (C) 2019 hops.io.
 *
 * Licensed 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 io.hops.exception.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import io.hops.metadata.HdfsStorageFactory;
import io.hops.transaction.handler.RequestHandler;
import io.hops.transaction.handler.TransactionalRequestHandler;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.impl.Log4JLogger;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;

import io.hops.transaction.handler.HDFSOperationType;
import io.hops.transaction.handler.HopsTransactionalRequestHandler;
import io.hops.transaction.lock.TransactionLockTypes;
import io.hops.transaction.lock.TransactionLocks;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.*;
import org.junit.Test;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_ACCESSTIME_PRECISION_KEY;
import static org.junit.Assert.*;

public class TestSuppressTransientExceptions {

    private static final Log LOG = LogFactory.getLog(TestSuppressTransientExceptions.class);

    @Test
    public void TestSuppressTransientExceptions() throws IOException {
        try {
            final Logger logger = Logger.getRootLogger();
            Logger.getLogger(RequestHandler.class).setLevel(Level.ALL);
            Logger.getLogger(TestSuppressTransientExceptions.class).setLevel(Level.ALL);

            final int MAX_RETRY = 2;
            Configuration conf = new HdfsConfiguration();
            RequestHandler.setRetryCount(MAX_RETRY);
            HdfsStorageFactory.resetDALInitialized();
            HdfsStorageFactory.setConfiguration(conf);
            HdfsStorageFactory.formatStorage();

            //not all transient exceptions are suppressed only
            //the dealock, dbextent and lock upgrade exceptions are suppressed

            LOG.info("******* Test 0 ********");
            final LogVerificationAppender appender = new LogVerificationAppender();
            logger.addAppender(appender);
            IOException e = new TransientStorageException("TransientStorageException");
            try {
                runWithErrors(3, e, HDFSOperationType.TEST);
                fail("Expecting Exception");
            } catch (TransientStorageException te) {
                assertTrue(getExceptionCount(appender.getLog(), e.getClass()) == 3);
            }

            LOG.info("******* Test 1 ********");
            final LogVerificationAppender appender1 = new LogVerificationAppender();
            logger.addAppender(appender1);
            e = new TransientStorageException("TransientStorageException");
            runWithErrors(2, e, HDFSOperationType.TEST);
            assertTrue(getExceptionCount(appender1.getLog(), e.getClass()) == 2);

            LOG.info("******* Test 2 ********");
            final LogVerificationAppender appender2 = new LogVerificationAppender();
            logger.addAppender(appender2);
            e = new TransientDeadLockException("TransientDeadLockException");
            runWithErrors(2, e, HDFSOperationType.TEST);
            assertTrue(getExceptionCount(appender2.getLog(), e.getClass()) == 0);

            LOG.info("******* Test 3 ********");
            final LogVerificationAppender appender3 = new LogVerificationAppender();
            logger.addAppender(appender3);
            e = new TransientDeadLockException("TransientDeadLockException");
            try {
                runWithErrors(3, e, HDFSOperationType.TEST);
                fail("Expecting Exception");
            } catch (TransientDeadLockException de) {
                assertTrue(getExceptionCount(appender3.getLog(), e.getClass()) == 3);
            }

            //Testing nontransient exceptions, i.e. OutOfDBExtentsException, LockUpgradeException
            LOG.info("******* Test 4 ********");
            int failures = 100;
            final LogVerificationAppender appender4 = new LogVerificationAppender();
            logger.addAppender(appender4);
            try {
                e = new OutOfDBExtentsException("OutOfDBExtentsException");
                runWithErrors(failures, e, HDFSOperationType.TEST);
                fail();
            } catch (OutOfDBExtentsException ex) {
            }
            assertTrue(getExceptionCount(appender4.getLog(), e.getClass()) == 1); // for
            // HDFSOperationType.TEST the exception will not be suppressed

            LOG.info("******* Test 5 ********");
            failures = 100;
            final LogVerificationAppender appender5 = new LogVerificationAppender();
            logger.addAppender(appender5);
            try {
                e = new OutOfDBExtentsException("OutOfDBExtentsException");
                runWithErrors(failures, e, HDFSOperationType.COMPLETE_FILE);
                fail();
            } catch (OutOfDBExtentsException ex) {
            }
            assertTrue(getExceptionCount(appender5.getLog(), e.getClass()) == 0);

            LOG.info("******* Test 6 ********");
            failures = 100;
            final LogVerificationAppender appender6 = new LogVerificationAppender();
            logger.addAppender(appender6);
            try {
                e = new LockUpgradeException("LockUpgradeException");
                runWithErrors(failures, e, HDFSOperationType.TEST);
                fail();
            } catch (LockUpgradeException ex) {
            }
            assertTrue(getExceptionCount(appender6.getLog(), e.getClass()) == 1); // for
            // HDFSOperationType.TEST the exception will not be suppressed

            LOG.info("******* Test 7 ********");
            failures = 100;
            final LogVerificationAppender appender7 = new LogVerificationAppender();
            logger.addAppender(appender7);
            try {
                e = new LockUpgradeException("LockUpgradeException");
                runWithErrors(failures, e, HDFSOperationType.GET_BLOCK_LOCATIONS);
                fail();
            } catch (LockUpgradeException ex) {
            }
            assertTrue(getExceptionCount(appender7.getLog(), e.getClass()) == 0);

        } finally {
        }
    }

    int getExceptionCount(List<LoggingEvent> log, Class e) {
        int count = 0;
        for (int i = 0; i < log.size(); i++) {
            if (log.get(i).getMessage().toString().contains(e.getCanonicalName())) {
                count++;
            }
        }
        return count;
    }

    void runWithErrors(final int failures, final IOException e, HDFSOperationType type) throws IOException {
        final AtomicInteger count = new AtomicInteger(0);
        HopsTransactionalRequestHandler completeFileHandler = new HopsTransactionalRequestHandler(type) {
            @Override
            public void acquireLock(TransactionLocks locks) throws IOException {
            }

            @Override
            public Object performTask() throws IOException {
                if (count.get() >= failures) {
                    return null;
                } else {
                    count.incrementAndGet();
                    throw e;
                }
            }
        };

        completeFileHandler.handle(this);
    }
}