package com.linkedin.databus.client;
/*
*
* Copyright 2013 LinkedIn Corp. All rights reserved
*
* 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.
*
*/
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.log4j.Level;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.linkedin.databus.core.DbusEventBuffer;
import com.linkedin.databus.core.DbusEventBuffer.AllocationPolicy;
import com.linkedin.databus.core.data_model.DatabusSubscription;
import com.linkedin.databus2.test.TestUtil;
public class TestDatabusSourcesConnection
{
@BeforeClass
public void classSetup()
{
TestUtil.setupLoggingWithTimestampedFile(true, "/tmp/TestDatabusSourcesConnection_", ".log", Level.WARN);
}
@Test
public void testConfig() throws Exception
{
DatabusSourcesConnection.Config config;
DatabusSourcesConnection.StaticConfig sConfig;
{
// Make sure that ConsumerTimeBudget defaults to the relay's settings as long as
// the bootstrap's budget is not set.
config= new DatabusSourcesConnection.Config();
sConfig = config.build();
Assert.assertEquals(sConfig.getConsumerTimeBudgetMs(), sConfig.getBstConsumerTimeBudgetMs());
long timeBudget = sConfig.getConsumerTimeBudgetMs();
config.setConsumerTimeBudgetMs(timeBudget+1);
sConfig = config.build();
Assert.assertEquals(timeBudget+1, sConfig.getConsumerTimeBudgetMs());
Assert.assertEquals(timeBudget+1, sConfig.getBstConsumerTimeBudgetMs());
config.setBstConsumerTimeBudgetMs(timeBudget + 2);
sConfig = config.build();
Assert.assertEquals(timeBudget+2, sConfig.getBstConsumerTimeBudgetMs());
Assert.assertEquals(timeBudget+1, sConfig.getConsumerTimeBudgetMs());
}
{
// Make sure that EventBuffer and BstEventBuffer are distinct only after some parameter in BstEventBuffer is set.
config = new DatabusSourcesConnection.Config();
Assert.assertFalse(config.hasBstEventBuffer());
sConfig = config.build();
Assert.assertEquals(sConfig.getEventBuffer().getBufferRemoveWaitPeriod(), sConfig.getBstEventBuffer().getBufferRemoveWaitPeriod());
long waitPeriod = sConfig.getEventBuffer().getBufferRemoveWaitPeriod();
config.getEventBuffer().setBufferRemoveWaitPeriodSec(waitPeriod + 1);
sConfig = config.build();
Assert.assertEquals(waitPeriod+1, sConfig.getEventBuffer().getBufferRemoveWaitPeriod());
Assert.assertEquals(waitPeriod+1, sConfig.getBstEventBuffer().getBufferRemoveWaitPeriod());
Assert.assertFalse(config.hasBstEventBuffer());
config.getBstEventBuffer().setBufferRemoveWaitPeriodSec(waitPeriod+2);
Assert.assertTrue(config.hasBstEventBuffer());
sConfig = config.build();
Assert.assertEquals(waitPeriod+1, sConfig.getEventBuffer().getBufferRemoveWaitPeriod());
Assert.assertEquals(waitPeriod+2, sConfig.getBstEventBuffer().getBufferRemoveWaitPeriod());
// We should return the same object no matter how many times get is called.
Assert.assertEquals(System.identityHashCode(config.getBstEventBuffer()),
System.identityHashCode(config.getBstEventBuffer()));
}
{
// Make sure that DispatcherRetries and BstDispatcherRetries are distinct only after some parameter in BstDispatcherRetries is set.
config = new DatabusSourcesConnection.Config();
Assert.assertFalse(config.hasBstDispatcherRetries());
sConfig = config.build();
Assert.assertEquals(sConfig.getDispatcherRetries().getMaxRetryNum(), sConfig.getBstDispatcherRetries().getMaxRetryNum());
int retryNum = sConfig.getDispatcherRetries().getMaxRetryNum();
config.getDispatcherRetries().setMaxRetryNum(retryNum+1);
sConfig = config.build();
Assert.assertEquals(retryNum+1, sConfig.getDispatcherRetries().getMaxRetryNum());
Assert.assertEquals(retryNum+1, sConfig.getBstDispatcherRetries().getMaxRetryNum());
Assert.assertFalse(config.hasBstDispatcherRetries());
config.getBstDispatcherRetries().setMaxRetryNum(retryNum+2);
Assert.assertTrue(config.hasBstDispatcherRetries());
sConfig = config.build();
Assert.assertEquals(retryNum+1, sConfig.getDispatcherRetries().getMaxRetryNum());
Assert.assertEquals(retryNum+2, sConfig.getBstDispatcherRetries().getMaxRetryNum());
// We should return the same object no matter how many times get is called.
Assert.assertEquals(System.identityHashCode(config.getBstDispatcherRetries()),
System.identityHashCode(config.getBstDispatcherRetries()));
}
{
// Make sure that PullerRetries and BstPullerRetries are distinct only after some parameter in BstPullerRetries is set.
config = new DatabusSourcesConnection.Config();
Assert.assertFalse(config.hasBstPullerRetries());
sConfig = config.build();
Assert.assertEquals(sConfig.getPullerRetries().getMaxRetryNum(), sConfig.getBstPullerRetries().getMaxRetryNum());
int retryNum = sConfig.getPullerRetries().getMaxRetryNum();
config.getPullerRetries().setMaxRetryNum(retryNum+1);
sConfig = config.build();
Assert.assertEquals(retryNum+1, sConfig.getPullerRetries().getMaxRetryNum());
Assert.assertEquals(retryNum+1, sConfig.getBstPullerRetries().getMaxRetryNum());
Assert.assertFalse(config.hasBstPullerRetries());
config.getBstPullerRetries().setMaxRetryNum(retryNum+2);
Assert.assertTrue(config.hasBstPullerRetries());
sConfig = config.build();
Assert.assertEquals(retryNum+1, sConfig.getPullerRetries().getMaxRetryNum());
Assert.assertEquals(retryNum+2, sConfig.getBstPullerRetries().getMaxRetryNum());
// We should return the same object no matter how many times get is called.
Assert.assertEquals(System.identityHashCode(config.getBstPullerRetries()),
System.identityHashCode(config.getBstPullerRetries()));
}
{
config = new DatabusSourcesConnection.Config();
sConfig = config.build();
Assert.assertEquals(sConfig.getNoEventsConnectionResetTimeSec(), 15*60, "default setting for NoEventsConnectionResetTime");
config.setNoEventsConnectionResetTimeSec(3600);
sConfig = config.build();
Assert.assertEquals(sConfig.getNoEventsConnectionResetTimeSec(), 3600, "applied setting for NoEventsConnectionResetTime");
}
//validate the adjustment of maxEventSize based on checkpointThresholdPct
config = new DatabusSourcesConnection.Config();
config.setCheckpointThresholdPct(30.0);
config.setFreeBufferThreshold(1);
DbusEventBuffer.Config bufCfg = config.getEventBuffer();
bufCfg.setAllocationPolicy(AllocationPolicy.HEAP_MEMORY.toString());
bufCfg.setEnableScnIndex(false);
bufCfg.setMaxSize(1024);
//default maxEventSize
sConfig = config.build();
Assert.assertEquals(sConfig.getEventBuffer().getMaxEventSize(), (int)(bufCfg.maxMaxEventSize() * 0.7));
Assert.assertEquals(sConfig.getBstEventBuffer().getMaxEventSize(), (int)(bufCfg.maxMaxEventSize() * 0.7));
//default maxEventSize with bootstrap override
DbusEventBuffer.Config bstBufCfg = config.getBstEventBuffer();
bstBufCfg.setAllocationPolicy(AllocationPolicy.HEAP_MEMORY.toString());
bstBufCfg.setEnableScnIndex(false);
bstBufCfg.setMaxSize(2048);
sConfig = config.build();
Assert.assertEquals(sConfig.getEventBuffer().getMaxEventSize(), (int)(bufCfg.maxMaxEventSize() * 0.7));
Assert.assertEquals(sConfig.getBstEventBuffer().getMaxEventSize(), (int)(bstBufCfg.maxMaxEventSize() * 0.7));
//too big max event size
bufCfg.setMaxEventSize(10240);
sConfig = config.build();
Assert.assertEquals(sConfig.getEventBuffer().getMaxEventSize(), (int)(bufCfg.maxMaxEventSize() * 0.7));
Assert.assertEquals(sConfig.getBstEventBuffer().getMaxEventSize(), (int)(bstBufCfg.maxMaxEventSize() * 0.7));
}
@Test
public void testLoggerNameV2_1()
throws InvocationTargetException,NoSuchMethodException,IllegalAccessException
{
String source = "com.linkedin.events.dbName.tableName";
List<DatabusSubscription> ds = DatabusSubscription.createSubscriptionList(Arrays.asList(source));
DatabusSourcesConnection dsc = DatabusSourcesConnection.createDatabusSourcesConnectionForTesting();
String partName = DatabusSubscription.getPrettyNameForListOfSubscriptions(ds);
Assert.assertEquals(partName, "dbName_tableName");
Class<?>[] arg1 = new Class<?>[] {List.class, String.class};
Method constructPrettyNameForLogging = DatabusSourcesConnection.class.getDeclaredMethod("constructPrettyNameForLogging", arg1);
constructPrettyNameForLogging.setAccessible(true);
Object prettyName = constructPrettyNameForLogging.invoke(dsc, ds, "test_1234");
Assert.assertEquals(prettyName, "dbName_tableName_test_1234");
}
@Test
public void testLoggerNameV2_2()
throws InvocationTargetException,NoSuchMethodException,IllegalAccessException
{
// They are of same db, but may have different
String source1 = "com.linkedin.events.db.dbPrefix1.tableName1";
String source2 = "com.linkedin.events.db.dbPrefix2.tableName2";
List<String> ls = new ArrayList<String>();
ls.add(source1);
ls.add(source2);
List<DatabusSubscription> ds = DatabusSubscription.createSubscriptionList(ls);
DatabusSourcesConnection dsc = DatabusSourcesConnection.createDatabusSourcesConnectionForTesting();
String partName = DatabusSubscription.getPrettyNameForListOfSubscriptions(ds);
Assert.assertEquals(partName, "dbPrefix1_tableName1_dbPrefix2_tableName2");
Class<?>[] arg1 = new Class<?>[] {List.class, String.class};
Method constructPrettyNameForLogging = DatabusSourcesConnection.class.getDeclaredMethod("constructPrettyNameForLogging", arg1);
constructPrettyNameForLogging.setAccessible(true);
Object prettyName = constructPrettyNameForLogging.invoke(dsc, ds, "test_1234");
Assert.assertEquals(prettyName, "dbPrefix1_tableName1_dbPrefix2_tableName2_test_1234");
}
}