package com.tesora.dve.common.catalog; /* * #%L * Tesora Inc. * Database Virtualization Engine * %% * Copyright (C) 2011 - 2014 Tesora Inc. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Properties; import com.tesora.dve.common.DBHelper; import com.tesora.dve.common.DBType; import com.tesora.dve.common.PEConstants; import com.tesora.dve.common.PEXmlUtils; import com.tesora.dve.common.catalog.CatalogDAO.CatalogDAOFactory; import com.tesora.dve.db.DBNative; import com.tesora.dve.db.DBNative.DBNativeFactory; import com.tesora.dve.exceptions.PEException; import com.tesora.dve.siteprovider.onpremise.OnPremiseSiteProvider; import com.tesora.dve.siteprovider.onpremise.jaxb.OnPremiseSiteProviderConfig; import com.tesora.dve.sql.transexec.CatalogHelper; import com.tesora.dve.sql.util.Pair; import com.tesora.dve.variables.KnownVariables; import com.tesora.dve.variables.VariableHandler; public class TestCatalogHelper extends CatalogHelper { private static TestCatalogHelper instance = null; public TestCatalogHelper(Class<?> bootClass) throws PEException { super(bootClass); } /** * Get a <code>Properties</code> object containing the PE Project Catalog * properties. Properties file is loaded once and then the * <code>Properties</code> object is store in a static variable * * @param bootClass * * @return <code>Properties</code> object * @throws PEException * if catalog properties file can't be loaded */ public static Properties getTestCatalogProps(Class<?> bootClass) throws PEException { return getInstance(bootClass).getProperties(); } public static TestCatalogHelper getInstance(Class<?> bootClass) throws PEException { if (instance == null) instance = new TestCatalogHelper(bootClass); return instance; } public static TestCatalogHelper getInstance() { return instance; } /** * Create a fresh DVE Project Catalog database based on a catalog properties * file. An existing database with same name will be DROPped. The * .properties file must contain: driverClass: - e.g., com.mysql.jdbc.Driver * instanceURL: - e.g., jdbc:mysql://localhost dbName: - e.g., test_catalog * userid: - e.g., root password: - e.g., password * * NOTE: It is expected that a DVE server isn't running when this method is * called. i.e. it should be called before BootstrapHost.startServices(). * * @param bootClass * * @throws PEException * if catalog properties file can't be loaded * @throws SQLException */ public static void createMinimalCatalog(Class<?> bootClass) throws PEException, SQLException { TestCatalogHelper helper = null; try { helper = new TestCatalogHelper(bootClass); helper.createMinimalCatalog(); } finally { if (helper != null) { helper.close(); helper = null; } } } private void createMinimalCatalog() throws PEException { recreateCatalogDB(); CatalogDAO c = CatalogDAOFactory.newInstance(catalogProperties); try { c.begin(); createMinimalCatalog(c, getCatalogUser(), getCatalogPassword()); c.commit(); } finally { c.close(); } } /** * Brute force recreate the catalog database. Any existing catalog will be * blown away * * @throws PEException */ protected void recreateCatalogDB() throws PEException { CatalogDAOFactory.shutdown(); getDBNative(); DBHelper dbHelper = createDBHelper(); try { dbHelper.connect(); // DROP/CREATE the database dbHelper.executeQuery(dbNative.getDropDatabaseStmt(DBHelper.getConnectionCharset(dbHelper), getCatalogDBName()).getSQL()); final String catalogName = getCatalogDBName(); final String defaultScharSet = dbNative.getDefaultServerCharacterSet(); final String defaultCollation = dbNative.getDefaultServerCollation(); dbHelper.executeQuery(dbNative .getCreateDatabaseStmt(DBHelper.getConnectionCharset(dbHelper), catalogName, false, defaultScharSet, defaultCollation).getSQL()); } catch (SQLException e) { throw new PEException("Error recreating catalog - " + e.getMessage(), e); } finally { dbHelper.disconnect(); } } /** * Create a Test Catalog that has no persistent sites or groups pre-defined * * NOTE: It is expected that a DVE server isn't running when this method is * called. i.e. it should be called before BootstrapHost.startServices(). * * @throws PEException * if catalog properties file can't be loaded * @throws SQLException */ public static void createTestCatalog(Class<?> bootClass) throws PEException { TestCatalogHelper helper = null; try { helper = new TestCatalogHelper(bootClass); helper.createTestCatalog(); } finally { if (helper != null) { helper.close(); helper = null; } } } /** * Populate an empty DVE Project Catalog with some initial settings - one * Persistent Group ("DefaultGroup") with <code>numSites</code> Persistent * Sites ("site1"..."siteN"). - one UserDatabase ("DefaultDB") * * NOTE: It is expected that a DVE server isn't running when this method is * called. i.e. it should be called before BootstrapHost.startServices(). * * @param bootClass * * @param numSites * - number of StorageSites to create * @throws PEException * if properties file can't be loaded */ public static void createTestCatalog(Class<?> bootClass, int numSites) throws PEException { createTestCatalog(bootClass, numSites, null, null); } public static void createTestCatalog(Class<?> bootClass, int numSites, String rootUser, String rootPassword) throws PEException { TestCatalogHelper helper = null; try { helper = new TestCatalogHelper(bootClass); if(rootUser == null) helper.createTestCatalogWithDB(numSites, true); else helper.createTestCatalogWithDB(numSites, true, rootUser, rootPassword); if (numSites != -1) { // add 10 - numSites more StorageSites for (int i = numSites + 1; i <= 10; i++) { helper.createStorageSite("site" + i, helper.getCatalogBaseUrl(), helper.getCatalogUser(), helper.getCatalogPassword()); } } } finally { if (helper != null) { helper.close(); helper = null; } } } public PersistentSite createStorageSite(String name, String url, String user, String password) throws PEException { CatalogDAO c = CatalogDAOFactory.newInstance(catalogProperties); try { c.begin(); PersistentSite site = c.createPersistentSite(name, url, user, password); c.commit(); return site; } finally { c.close(); } } // ------------------------------------------------------------------------- // TEST Methods // /** * Create a catalog for testing purposes. This is the same as creating a * minimal catalog and then defining the default policy and default site * providers * * @throws PEException */ public void createTestCatalog() throws PEException { recreateCatalogDB(); CatalogDAO c = CatalogDAOFactory.newInstance(catalogProperties); try { c.begin(); createTestCatalog(c); c.commit(); } finally { c.close(); } } private Project createTestCatalog(CatalogDAO c) throws PEException { return createTestCatalog(c, getCatalogUser(), getCatalogPassword()).getFirst(); } @SuppressWarnings("rawtypes") private Pair<Project,Map<VariableHandler,VariableConfig>> createTestCatalog(CatalogDAO c, String user, String password) throws PEException { Pair<Project,Map<VariableHandler,VariableConfig>> minimal = createMinimalCatalog(c,user,password); Project p = minimal.getFirst(); // Create a default dynamic site policy addTestDefaultDynamicPolicy(minimal, c); // Register the built in Providers addTestDefaultSiteProviders(c); // TODO - should we validate that the dynamic policy is referencing // providers that actually exist and that the site providers are using // siteClasses that are specified in the policies ? return minimal; } private PersistentGroup createTestStorageGroup(CatalogDAO c, String name, int numStorageSites, String prefix) throws PEException { // Create the required persistent sites List<PersistentSite> sites = new ArrayList<PersistentSite>(); for (int i = 1; i <= numStorageSites; i++) { String siteName = prefix + "site" + i; sites.add(createStorageSite(siteName, getCatalogBaseUrl(), getCatalogUser(), getCatalogPassword())); } // Create a persistent group and add the sites created above return createStorageGroup(c, name, sites); } /** * Create a catalog for testing purposes that has persistent sites and a * default persistent group and also has an optional default database. * * @param numStorageSites * @throws PEException */ public void createTestCatalogWithDB(int numStorageSites, boolean withDB) throws PEException { createTestCatalogWithDB(numStorageSites, withDB, getCatalogUser(), getCatalogPassword()); } @SuppressWarnings("rawtypes") public void createTestCatalogWithDB(int numStorageSites, boolean withDB, String user, String password) throws PEException { recreateCatalogDB(); CatalogDAO c = CatalogDAOFactory.newInstance(catalogProperties); try { c.begin(); Pair<Project,Map<VariableHandler,VariableConfig>> minimal = createTestCatalog(c, user, password); PersistentGroup sg = createTestStorageGroup(c, PEConstants.DEFAULT_GROUP_NAME, numStorageSites, ""); minimal.getSecond().get(KnownVariables.PERSISTENT_GROUP).setValue(sg.getName()); if (withDB) { DBNative dbn = DBNativeFactory.newInstance(DBType.fromDriverClass(catalogProperties .getProperty(PEConstants.PROP_FULL_JDBC_DRIVER))); c.createDatabase(UserDatabase.DEFAULT, sg, dbn.getDefaultServerCharacterSet(), dbn.getDefaultServerCollation()); } c.commit(); } finally { c.close(); } } private int siteCount = 5; @SuppressWarnings("rawtypes") private DynamicPolicy addTestDefaultDynamicPolicy(Pair<Project,Map<VariableHandler,VariableConfig>> minimal, CatalogDAO c) throws PEException { try { DynamicPolicy policy = generatePolicyConfig(siteCount, OnPremiseSiteProvider.DEFAULT_NAME); c.persistToCatalog(policy); minimal.getSecond().get(KnownVariables.DYNAMIC_POLICY).setValue(policy.getName()); return policy; } catch (Throwable t) { throw new PEException("Cannot create Dynamic Policy: " + t.getMessage(), t); } } private OnPremiseSiteProviderConfig addTestDefaultSiteProviders(CatalogDAO c) throws PEException { OnPremiseSiteProviderConfig config = generateProviderConfig(siteCount, OnPremiseSiteProvider.DEFAULT_NAME, getCatalogBaseUrl(), getCatalogUser(), getCatalogPassword()); c.createProvider(OnPremiseSiteProvider.DEFAULT_NAME, OnPremiseSiteProvider.class.getCanonicalName(), PEXmlUtils.marshalJAXB(config)); return config; } }