package com.tesora.dve.test.externalservice;
/*
* #%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 static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.net.InetSocketAddress;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.tesora.dve.common.catalog.ExternalService;
import com.tesora.dve.common.catalog.TestCatalogHelper;
import com.tesora.dve.errmap.MySQLErrors;
import com.tesora.dve.exceptions.PEException;
import com.tesora.dve.externalservice.ExternalServiceContext;
import com.tesora.dve.externalservice.ExternalServiceFactory;
import com.tesora.dve.externalservice.ExternalServicePlugin;
import com.tesora.dve.membership.GroupMembershipListener.MembershipEventType;
import com.tesora.dve.server.bootstrap.BootstrapHost;
import com.tesora.dve.server.global.HostService;
import com.tesora.dve.singleton.Singletons;
import com.tesora.dve.sql.SchemaTest;
import com.tesora.dve.sql.schema.PEExternalService;
import com.tesora.dve.sql.util.DBHelperConnectionResource;
import com.tesora.dve.sql.util.PEDDL;
import com.tesora.dve.sql.util.PortalDBHelperConnectionResource;
import com.tesora.dve.sql.util.ProjectDDL;
import com.tesora.dve.sql.util.StorageGroupDDL;
import com.tesora.dve.standalone.PETest;
public class ExternalServiceTest extends SchemaTest {
private static final ProjectDDL checkDDL = new PEDDL("checkdb",
new StorageGroupDDL("check", 2, "checkg"), "schema");
final static String testExternalServiceName = "foo";
final static String testESPlugin = "com.tesora.dve.test.externalservice.TestExternalService";
final static String testESUser = "root";
final static String testESUsesDatastore = "true";
final static String testESConfig = "localhost,3306,pduser,password,2,mysql-bin.000001,4";
final static String testESConfig2 = "localhost2,33062,pduser2,password2,22,mysql-bin.0000012,42";
PortalDBHelperConnectionResource conn;
DBHelperConnectionResource dbh;
Map<String,String> options = new HashMap<String, String>();
private static final String[] createdDBs = new String[] {
"SystemSite_es1_FileReplSlave",
"SystemSite_es1_TestService",
"SystemSite_es1_foo"
};
@BeforeClass
public static void setup() throws Throwable {
projectSetup(checkDDL);
bootHost = BootstrapHost.startServices(PETest.class);
populateMetadata(ExternalServiceTest.class, Singletons.require(HostService.class).getProperties());
try (final DBHelperConnectionResource dropper = new DBHelperConnectionResource()) {
for(String s : createdDBs)
dropper.execute("drop database if exists " + s);
}
}
@Before
public void connect() throws Throwable {
conn = new PortalDBHelperConnectionResource();
checkDDL.create(conn);
dbh = new DBHelperConnectionResource();
}
@After
public void disconnect() throws Throwable {
if (conn != null) {
conn.disconnect();
conn = null;
}
if (dbh != null) {
dbh.disconnect();
dbh = null;
}
}
public ExternalServiceTest() throws SQLException, PEException {
}
@Test
public void testExternalServiceDDL() throws Throwable {
// test CREATE ddl
options.put(PEExternalService.OPTION_PLUGIN, TestExternalService.class.getName());
options.put(PEExternalService.OPTION_CONNECT_USER, testESUser);
options.put(PEExternalService.OPTION_USE_DATASTORE, testESUsesDatastore);
options.put(PEExternalService.OPTION_CONFIG, testESConfig);
String esOptions = buildExternalServiceOptions(options);
StringBuffer sql = new StringBuffer(50);
conn.execute(sql.append("CREATE EXTERNAL SERVICE ").append(testExternalServiceName).append(" USING ").append(esOptions).toString());
dbh.execute("USE " + TestCatalogHelper.getInstance(PETest.class).getCatalogDBName());
verifyCreate();
// test Stop ddl
sql = new StringBuffer();
sql.append("STOP EXTERNAL SERVICE ").append(testExternalServiceName);
conn.execute(sql.toString());
verifyStop();
// test ALTER ddl
options.put(PEExternalService.OPTION_PLUGIN, TestExternalService.class.getName());
options.put(PEExternalService.OPTION_CONNECT_USER, testESUser);
options.put(PEExternalService.OPTION_USE_DATASTORE, testESUsesDatastore);
options.put(PEExternalService.OPTION_CONFIG, testESConfig2);
esOptions = buildExternalServiceOptions(options);
sql = new StringBuffer();
sql.append("ALTER EXTERNAL SERVICE ").append(testExternalServiceName).append(" SET ").append(esOptions);
conn.execute(sql.toString());
verifyAlter();
// test Start ddl
sql = new StringBuffer();
sql.append("START EXTERNAL SERVICE ").append(testExternalServiceName);
conn.execute(sql.toString());
verifyStart();
conn.assertResults("show external services",
br(nr,testExternalServiceName,ignore,"YES","root","YES",testESConfig2));
conn.assertResults("show external service " + testExternalServiceName,
br(nr,testExternalServiceName,null));
// test DROP ddl
// get datastore name first
String datastore = null;
ExternalService es = getGlobalDAO().findExternalService(testExternalServiceName);
if (es.usesDataStore()) {
datastore = es.getDataStoreName();
}
sql = new StringBuffer();
sql.append("DROP EXTERNAL SERVICE ").append(testExternalServiceName);
conn.execute(sql.toString());
verifyDrop(datastore);
}
String buildExternalServiceOptions(Map<String, String> options) {
boolean first = true;
StringBuffer sql = new StringBuffer();
for(String key : options.keySet()) {
if (!first) {
sql.append(' ');
}
sql.append(key).append("='").append(options.get(key)).append("'"); // NOPMD by doug on 30/11/12 3:31 PM
first = false;
}
return sql.toString();
}
void verifyCreate() throws Throwable {
dbh.assertResults("SELECT config, connect_user, uses_datastore FROM external_service WHERE name='" + testExternalServiceName + "'",
br(nr,testESConfig,testESUser,Boolean.TRUE));
// make sure datastore has been created
ExternalService es = getGlobalDAO().findExternalService(testExternalServiceName);
if (es.usesDataStore()) {
// if database does not exist we will throw
conn.execute("USE " + es.getDataStoreName());
}
// make sure service is registered and started
verifyStart();
}
void verifyAlter() throws Throwable {
dbh.assertResults("SELECT config, connect_user, uses_datastore FROM external_service WHERE name='" + testExternalServiceName + "'",
br(nr,testESConfig2,testESUser,Boolean.TRUE));
}
void verifyDrop(final String datastore) throws Throwable {
dbh.assertResults("SELECT config, connect_user, uses_datastore FROM external_service WHERE name='" + testExternalServiceName + "'",
br());
// make sure datastore has been dropped
if (datastore != null) {
new ExpectedSqlErrorTester() {
@Override
public void test() throws Throwable {
conn.execute("USE " + datastore);
}
}.assertSqlError(SQLException.class, MySQLErrors.unknownDatabaseFormatter, datastore);
}
// make sure service is gone
ExternalService es = getGlobalDAO().findExternalService(testExternalServiceName, false);
assertNull("External service must not be found.", es);
// make sure service is deregistered
assertFalse(ExternalServiceFactory.isRegistered(testExternalServiceName));
}
void verifyStart() throws PEException {
assertTrue("External service must be registered",ExternalServiceFactory.isRegistered(testExternalServiceName));
ExternalServicePlugin plugin = ExternalServiceFactory.getInstance(testExternalServiceName);
// make sure service is started
assertTrue("External service must be started.", plugin.isStarted());
}
void verifyStop() throws PEException {
assertTrue("External service must be registered",ExternalServiceFactory.isRegistered(testExternalServiceName));
ExternalServicePlugin plugin = ExternalServiceFactory.getInstance(testExternalServiceName);
// make sure service is started
assertFalse("External service must be stopped.", plugin.isStarted());
}
public static class TestExternalService implements ExternalServicePlugin {
boolean isStarted = false;
@Override
public void initialize(ExternalServiceContext ctxt) throws PEException {
}
@Override
public void start() throws PEException {
isStarted = true;
}
@Override
public void stop() {
isStarted = false;
}
@Override
public boolean isStarted() {
return isStarted;
}
@Override
public String status() throws PEException {
return null;
}
@Override
public String getName() throws PEException {
return null;
}
@Override
public String getPlugin() throws PEException {
return null;
}
@Override
public void close() {
}
@Override
public void reload() throws PEException {
}
@Override
public void restart() throws PEException {
}
@Override
public boolean denyServiceStart(ExternalServiceContext ctxt)
throws PEException {
return false;
}
@Override
public void handleGroupMembershipEvent(MembershipEventType eventType,
InetSocketAddress inetSocketAddress) {
}
}
}