de.hybris.platform.util.database.TableNameDatabaseMetaDataCallbackTest.java Source code

Java tutorial

Introduction

Here is the source code for de.hybris.platform.util.database.TableNameDatabaseMetaDataCallbackTest.java

Source

/*
 * [y] hybris Platform
 * 
 * Copyright (c) 2000-2013 hybris AG
 * All rights reserved.
 * 
 * This software is the confidential and proprietary information of hybris
 * ("Confidential Information"). You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the
 * license agreement you entered into with hybris.
 */
package de.hybris.platform.util.database;

import de.hybris.bootstrap.annotations.IntegrationTest;
import de.hybris.platform.core.Registry;
import de.hybris.platform.core.SlaveTenant;
import de.hybris.platform.core.Tenant;
import de.hybris.platform.core.system.query.QueryProvider;
import de.hybris.platform.core.system.query.impl.QueryProviderFactory;
import de.hybris.platform.jalo.JaloSystemException;
import de.hybris.platform.jalo.security.JaloSecurityException;
import de.hybris.platform.jdbcwrapper.HybrisDataSource;
import de.hybris.platform.servicelayer.ServicelayerBaseTest;
import de.hybris.platform.testframework.RunListeners;
import de.hybris.platform.testframework.runlistener.LogRunListener;
import de.hybris.platform.util.Config;
import de.hybris.platform.util.database.DropTablesTool.TableNameDatabaseMetaDataCallback;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Properties;

import javax.annotation.Resource;
import javax.sql.DataSource;

import junit.framework.Assert;

import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.MetaDataAccessException;

/**
 * Demonstrates how the DropTablesTool filters out its tenant specific tables.
 */
@RunListeners(LogRunListener.class)
@IntegrationTest
public class TableNameDatabaseMetaDataCallbackTest extends ServicelayerBaseTest {
    private final List<String> createdTables = new ArrayList<>();

    private static final Logger LOG = Logger.getLogger(TableNameDatabaseMetaDataCallbackTest.class.getName());

    @Resource
    private DataSource dataSource;

    private Tenant before;

    static Properties DROP1_SETUP = new Properties();
    static Properties DROP2_SETUP = new Properties();
    static Properties DROP3_SETUP = new Properties();

    static {
        DROP1_SETUP.put("db.tableprefix", "");
        DROP2_SETUP.put("db.tableprefix", "dr2_");
        DROP3_SETUP.put("db.tableprefix", "dr3_");
    }

    @Mock
    private QueryProvider defaultQueryProvider;

    private Collection<SlaveTenant> allSlaves = new ArrayList<>();

    private final SlaveTenant drop1Tenant = new SlaveTenantWithJUnitDatasource("drop1", DROP1_SETUP);
    private final SlaveTenant drop2Tenant = new SlaveTenantWithJUnitDatasource("drop2", DROP2_SETUP);
    private final SlaveTenant drop3Tenant = new SlaveTenantWithJUnitDatasource("drop3", DROP3_SETUP);

    @Before
    public void prepare() {
        MockitoAnnotations.initMocks(this);
        Mockito.when(defaultQueryProvider.getTableName()).thenReturn(QueryProviderFactory.LOCK_TABLE);
        before = Registry.getCurrentTenantNoFallback();
        allSlaves = Arrays.asList(drop1Tenant, drop2Tenant, drop3Tenant);
    }

    // uses junit tenant
    @Test
    public void testDropOnlyTablesWithMyPrefix() throws MetaDataAccessException {

        final String currentPrefix = "dr2_";

        final String otherPrefix = "other_";
        final String nonePrefix = "";

        createTable(dataSource, currentPrefix + "foo");
        createTable(dataSource, currentPrefix + "bar");
        createTable(dataSource, currentPrefix + "boo");

        createTable(dataSource, otherPrefix + "foo");
        createTable(dataSource, otherPrefix + "bar");
        createTable(dataSource, otherPrefix + "boo");

        createTable(dataSource, nonePrefix + "foo");
        createTable(dataSource, nonePrefix + "bar");
        createTable(dataSource, nonePrefix + "boo");

        final TableNameDatabaseMetaDataCallback tablesFilterCallback = new TableNameDatabaseMetaDataCallback(
                defaultQueryProvider, drop2Tenant) {
            @Override
            Collection<SlaveTenant> getSlaveTenants() {
                return allSlaves;
            }

        };

        final List<String> tables = (List<String>) JdbcUtils.extractDatabaseMetaData(dataSource,
                tablesFilterCallback);

        Assert.assertTrue(containsIgnoreCase(currentPrefix + "foo", tables));
        Assert.assertTrue(containsIgnoreCase(currentPrefix + "bar", tables));
        Assert.assertTrue(containsIgnoreCase(currentPrefix + "boo", tables));

        Assert.assertFalse(containsIgnoreCase(otherPrefix + "foo", tables));
        Assert.assertFalse(containsIgnoreCase(otherPrefix + "bar", tables));
        Assert.assertFalse(containsIgnoreCase(otherPrefix + "boo", tables));

        Assert.assertFalse(containsIgnoreCase(nonePrefix + "foo", tables));
        Assert.assertFalse(containsIgnoreCase(nonePrefix + "bar", tables));
        Assert.assertFalse(containsIgnoreCase(nonePrefix + "boo", tables));

        testOmmitAdminTables();
    }

    // never drop system tables
    @Test
    public void testOmmitAdminTables() throws MetaDataAccessException {
        //
        final TableNameDatabaseMetaDataCallback tablesFilterCallback = new TableNameDatabaseMetaDataCallback(
                defaultQueryProvider, Registry.getCurrentTenantNoFallback()) {
            @Override
            Collection<SlaveTenant> getSlaveTenants() {
                return allSlaves;
            }
        };

        final List<String> tables = (List<String>) JdbcUtils.extractDatabaseMetaData(dataSource,
                tablesFilterCallback);

        Assert.assertFalse(tables.contains("JGROUPSPING"));
        Assert.assertFalse(tables.contains(QueryProviderFactory.LOCK_TABLE));
    }

    // never drop system tables
    @Test
    public void testOmmitAdminTablesForCustomTablePrefix() throws MetaDataAccessException {

        final String TABLE_PREFIX = "FoO_"; // play around with case sensitiveness

        final String before = Config.getParameter("db.tableprefix");

        Mockito.reset(defaultQueryProvider);
        Mockito.when(defaultQueryProvider.getTableName())
                .thenReturn(TABLE_PREFIX + QueryProviderFactory.LOCK_TABLE);
        try {
            Config.setParameter("db.tableprefix", TABLE_PREFIX);

            createTable(dataSource, TABLE_PREFIX + QueryProviderFactory.LOCK_TABLE);
            //
            final TableNameDatabaseMetaDataCallback tablesFilterCallback = new TableNameDatabaseMetaDataCallback(
                    defaultQueryProvider, Registry.getCurrentTenantNoFallback()) {
                @Override
                Collection<SlaveTenant> getSlaveTenants() {
                    return allSlaves;
                }
            };

            final List<String> tables = (List<String>) JdbcUtils.extractDatabaseMetaData(dataSource,
                    tablesFilterCallback);

            Assert.assertFalse(tables.contains("JGROUPSPING"));
            // Assert.assertTrue(tables.contains(QueryProviderFactory.LOCK_TABLE));
            Assert.assertFalse(tables.contains(TABLE_PREFIX + QueryProviderFactory.LOCK_TABLE));
            Assert.assertFalse(tables.contains((TABLE_PREFIX + QueryProviderFactory.LOCK_TABLE).toLowerCase()));
            Assert.assertFalse(tables.contains((TABLE_PREFIX + QueryProviderFactory.LOCK_TABLE).toUpperCase()));
        } finally {
            Config.setParameter("db.tableprefix", before);

            dropTable(dataSource, TABLE_PREFIX + QueryProviderFactory.LOCK_TABLE);
        }
    }

    // there is also drop2 on this url with other prefix
    @Test
    public void testDropAllMyNonPrefixedTablesLeaveOthersWithPrefixes() throws MetaDataAccessException {

        final String currentPrefix = getTablePrefix(drop1Tenant);

        Assume.assumeTrue(org.apache.commons.lang.StringUtils.isBlank(currentPrefix));// empty prefix

        final String otherPrefix = getTablePrefix(drop2Tenant);
        final String yetAnotherPrefix = getTablePrefix(drop3Tenant);

        createTable(dataSource, "foo");
        createTable(dataSource, "bar");
        createTable(dataSource, "boo");

        createTable(dataSource, otherPrefix + "foo");
        createTable(dataSource, otherPrefix + "bar");
        createTable(dataSource, otherPrefix + "boo");

        createTable(dataSource, yetAnotherPrefix + "foo");
        createTable(dataSource, yetAnotherPrefix + "bar");
        createTable(dataSource, yetAnotherPrefix + "boo");

        final TableNameDatabaseMetaDataCallback tablesFilterCallback = new TableNameDatabaseMetaDataCallback(
                defaultQueryProvider, drop1Tenant) {
            @Override
            Collection<SlaveTenant> getSlaveTenants() {
                return allSlaves;
            }

            @Override
            Tenant getMasterTenant() {
                // just to have different table prefix
                return drop3Tenant;
            }

        };

        final List<String> tables = (List<String>) JdbcUtils.extractDatabaseMetaData(dataSource,
                tablesFilterCallback);

        Assert.assertTrue(containsIgnoreCase(currentPrefix + "foo", tables));
        Assert.assertTrue(containsIgnoreCase(currentPrefix + "bar", tables));
        Assert.assertTrue(containsIgnoreCase(currentPrefix + "boo", tables));

        Assert.assertFalse(containsIgnoreCase(otherPrefix + "foo", tables));
        Assert.assertFalse(containsIgnoreCase(otherPrefix + "bar", tables));
        Assert.assertFalse(containsIgnoreCase(otherPrefix + "boo", tables));

        Assert.assertFalse(containsIgnoreCase(yetAnotherPrefix + "foo", tables));
        Assert.assertFalse(containsIgnoreCase(yetAnotherPrefix + "bar", tables));
        Assert.assertFalse(containsIgnoreCase(yetAnotherPrefix + "boo", tables));

        testOmmitAdminTables();

    }

    @After
    public void cleanupDB() {
        for (final String table : createdTables) {
            dropTable(dataSource, table);
        }

        Registry.setCurrentTenant(before);
    }

    /**
     * 
     */
    private boolean containsIgnoreCase(final String text, final List<String> tables) {
        return tables.contains(text.toUpperCase()) || tables.contains(text.toLowerCase());
    }

    String getTablePrefix(final Tenant tenant) {
        return tenant.getConfig().getParameter("db.tableprefix") == null ? ""
                : tenant.getConfig().getParameter("db.tableprefix");

    }

    private void createTable(final DataSource dataSource, final String tableName) {

        final JdbcTemplate create = new JdbcTemplate(dataSource);

        create.execute("CREATE TABLE " + tableName + " ( ID VARCHAR(10))");
        createdTables.add(tableName);
    }

    private void dropTable(final DataSource dataSource, final String tableName) {

        final JdbcTemplate create = new JdbcTemplate(dataSource);

        try {
            create.execute("DROP TABLE " + tableName);
        } catch (final DataAccessException e) {
            if (LOG.isDebugEnabled()) {
                LOG.debug(e);
            }
        }
    }

    @Override
    public void init() throws JaloSystemException {
        // nop
    }

    @Override
    public void finish() throws JaloSecurityException {
        // nop
    }

    private class SlaveTenantWithJUnitDatasource extends SlaveTenant {

        public SlaveTenantWithJUnitDatasource(final String systemName, final Properties props) {
            super(systemName, props);
        }

        @Override
        public HybrisDataSource getDataSource() {
            return (HybrisDataSource) dataSource;
        }

    }
}