blob: 379c53bb2f7da4225ca59cf5f9852fe8c5d14d88 [file] [log] [blame]
/*
* 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.hadoop.hive.ql.parse;
import static org.apache.hadoop.hive.ql.hooks.EnforceReadOnlyDatabaseHook.READONLY;
import static org.apache.hadoop.hive.common.repl.ReplConst.READ_ONLY_HOOK;
import static org.junit.Assert.assertEquals;
import com.google.common.collect.ImmutableMap;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.conf.MetastoreConf;
import org.apache.hadoop.hive.metastore.messaging.json.gzip.GzipJSONMessageEncoder;
import org.apache.hadoop.hive.shims.Utils;
import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
public class TestReplWithReadOnlyHook extends BaseReplicationScenariosAcidTables {
@BeforeClass
public static void classLevelSetup() throws Exception {
Map<String, String> overrides = new HashMap<>();
overrides.put(MetastoreConf.ConfVars.EVENT_MESSAGE_FACTORY.getHiveName(),
GzipJSONMessageEncoder.class.getCanonicalName());
conf = new HiveConf(TestReplWithReadOnlyHook.class);
conf.set("hadoop.proxyuser." + Utils.getUGI().getShortUserName() + ".hosts", "*");
MiniDFSCluster miniDFSCluster =
new MiniDFSCluster.Builder(conf).numDataNodes(2).format(true).build();
Map<String, String> acidEnableConf = new HashMap<String, String>();
acidEnableConf.put("fs.defaultFS", miniDFSCluster.getFileSystem().getUri().toString());
acidEnableConf.put("hive.support.concurrency", "true");
acidEnableConf.put("hive.txn.manager", "org.apache.hadoop.hive.ql.lockmgr.DbTxnManager");
acidEnableConf.put("hive.metastore.client.capability.check", "false");
acidEnableConf.put("hive.repl.bootstrap.dump.open.txn.timeout", "1s");
acidEnableConf.put("hive.exec.dynamic.partition.mode", "nonstrict");
acidEnableConf.put("hive.strict.checks.bucketing", "false");
acidEnableConf.put("hive.mapred.mode", "nonstrict");
acidEnableConf.put("mapred.input.dir.recursive", "true");
acidEnableConf.put("hive.metastore.disallow.incompatible.col.type.changes", "false");
acidEnableConf.put("metastore.warehouse.tenant.colocation", "true");
acidEnableConf.put("hive.in.repl.test", "true");
acidEnableConf.put("hive.txn.readonly.enabled", "true");
acidEnableConf.put(HiveConf.ConfVars.REPL_RUN_DATA_COPY_TASKS_ON_TARGET.varname, "false");
acidEnableConf.put(HiveConf.ConfVars.REPL_RETAIN_CUSTOM_LOCATIONS_FOR_DB_ON_TARGET.varname,
"false");
acidEnableConf.put(HiveConf.ConfVars.PREEXECHOOKS.varname, READ_ONLY_HOOK);
acidEnableConf.putAll(overrides);
primary = new WarehouseInstance(LOG, miniDFSCluster, acidEnableConf);
acidEnableConf.put(MetastoreConf.ConfVars.REPLDIR.getHiveName(), primary.repldDir);
replica = new WarehouseInstance(LOG, miniDFSCluster, acidEnableConf);
Map<String, String> overridesForHiveConf1 = new HashMap<>();
overridesForHiveConf1.put("fs.defaultFS", miniDFSCluster.getFileSystem().getUri().toString());
overridesForHiveConf1.put("hive.support.concurrency", "false");
overridesForHiveConf1.put("hive.txn.manager", "org.apache.hadoop.hive.ql.lockmgr" +
".DummyTxnManager");
overridesForHiveConf1.put("hive.metastore.client.capability.check", "false");
overridesForHiveConf1.put(MetastoreConf.ConfVars.REPLDIR.getHiveName(), primary.repldDir);
replicaNonAcid = new WarehouseInstance(LOG, miniDFSCluster, overridesForHiveConf1);
}
@After
public void afterTest() throws Throwable {
replica.run("alter database " + replicatedDbName + " set dbproperties('readonly'='false')");
}
@Test
public void testDbSetToReadOnlyAfterBootstrapLoad() throws Throwable {
primary.run("use " + primaryDbName)
.run("CREATE TABLE t1(a string) STORED AS TEXTFILE")
.dump(primaryDbName);
replica.load(replicatedDbName, primaryDbName);
Map<String, String> dbParams = replica.getDatabase(replicatedDbName).getParameters();
assertEquals("true", dbParams.get(READONLY));
}
@Test
public void testDbReadOnlyModeBackWardCompatible() throws Throwable {
//do bootstrap
primary.run("use " + primaryDbName)
.run("CREATE TABLE t1(a string) STORED AS TEXTFILE")
.dump(primaryDbName);
replica.load(replicatedDbName, primaryDbName);
// let's toggle 'readonly' of db to simulate the use case
replica.run("ALTER DATABASE " + replicatedDbName + " SET DBPROPERTIES('readonly'='false')");
// perform incremental
primary.run("insert into " + primaryDbName +".t1 values(\"AAA\")")
.dump(primaryDbName);
// before REPL LOAD ensure db parameters is not "readonly"
String isDbReadOnly = replica.getDatabase(replicatedDbName).getParameters().get(READONLY);
assertEquals(Boolean.FALSE.toString() ,isDbReadOnly);
// perform REPL LOAD
replica.load(replicatedDbName, primaryDbName);
isDbReadOnly = replica.getDatabase(replicatedDbName).getParameters().get(READONLY);
assertEquals(Boolean.TRUE.toString() ,isDbReadOnly);
}
}