package com.linkedin.databus.core; /* * * 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 static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.channels.Channels; import java.nio.channels.WritableByteChannel; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.io.IOUtils; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import com.linkedin.databus.core.DbusEventBufferMult.PhysicalPartitionKey; import com.linkedin.databus.core.data_model.DatabusSubscription; import com.linkedin.databus.core.data_model.LogicalPartition; import com.linkedin.databus.core.data_model.LogicalSource; import com.linkedin.databus.core.data_model.LogicalSourceId; import com.linkedin.databus.core.data_model.PhysicalPartition; import com.linkedin.databus.core.data_model.PhysicalSource; import com.linkedin.databus.core.monitoring.mbean.AggregatedDbusEventsStatisticsCollector; import com.linkedin.databus.core.monitoring.mbean.DbusEventsStatisticsCollector; import com.linkedin.databus.core.monitoring.mbean.DbusEventsTotalStats; import com.linkedin.databus.core.monitoring.mbean.StatsCollectors; import com.linkedin.databus.core.util.InvalidConfigException; import com.linkedin.databus2.core.BufferNotFoundException; import com.linkedin.databus2.core.DatabusException; import com.linkedin.databus2.core.filter.AllowAllDbusFilter; import com.linkedin.databus2.core.filter.ConjunctionDbusFilter; import com.linkedin.databus2.core.filter.DbusFilter; import com.linkedin.databus2.core.filter.LogicalSourceAndPartitionDbusFilter; import com.linkedin.databus2.core.filter.PhysicalPartitionDbusFilter; import com.linkedin.databus2.core.filter.SourceDbusFilter; import com.linkedin.databus2.relay.config.PhysicalSourceConfig; import com.linkedin.databus2.relay.config.PhysicalSourceStaticConfig; import com.linkedin.databus2.test.TestUtil; public class TestDbusEventBufferMult { public static final Logger LOG = Logger.getLogger(TestDbusEventBufferMult.class); /** Encapsulate test set so that multiple threads can run in parallel */ static class TestSetup { PhysicalSourceStaticConfig [] _physConfigs; DbusEventBufferMult _eventBuffer; TestSetup() throws JsonParseException, JsonMappingException, IOException, InvalidConfigException { ObjectMapper mapper = new ObjectMapper(); InputStreamReader isr = new InputStreamReader(IOUtils.toInputStream(_configSource1)); PhysicalSourceConfig pConfig1 = mapper.readValue(isr, PhysicalSourceConfig.class); isr.close(); isr = new InputStreamReader(IOUtils.toInputStream(_configSource2)); PhysicalSourceConfig pConfig2 = mapper.readValue(isr, PhysicalSourceConfig.class); PhysicalSourceStaticConfig pStatConf1 = pConfig1.build(); PhysicalSourceStaticConfig pStatConf2 = pConfig2.build(); _physConfigs = new PhysicalSourceStaticConfig [] {pStatConf1, pStatConf2}; DbusEventBuffer.Config conf = new DbusEventBuffer.Config(); conf.setAllocationPolicy("MMAPPED_MEMORY"); DbusEventBuffer.StaticConfig config = conf.build(); _eventBuffer = new DbusEventBufferMult(_physConfigs, config, new DbusEventV2Factory()); for(DbusEventBuffer b : _eventBuffer.bufIterable()) { b.start(1); } } } DbusEventBuffer.StaticConfig _config; PhysicalSourceStaticConfig [] _pConfigs; DbusEventBufferMult _eventBufferMult; TestDbusEvent [] _events; PhysicalSource _phSource; PhysicalPartition _phPartition; ObjectMapper _mapper; static final String _configSource1 = "{\n" + " \"name\" : \"multBufferTest1\",\n" + " \"id\" : 100,\n" + " \"uri\" : \"uri1\",\n" + " \"slowSourceQueryThreshold\" : 2000,\n" + " \"sources\" :\n" + " [\n" + " {\"id\" : 1, \n" + " \"name\" : \"srcName1\",\n" + " \"uri\": \"member2.member_profile\", \n" + " \"partitionFunction\" : \"constant:1\", \n" + " \"partition\" : 0 \n" + " },\n" + " {\"id\" : 2, \n" + " \"name\" : \"srcName2\",\n" + " \"uri\" : \"member2.member_account\", \n" + " \"partitionFunction\" : \"constant:1\", \n" + " \"partition\" : 0 \n" + " },\n" + " {\"id\" : 2, \n" + " \"name\" : \"srcName2\",\n" + " \"uri\" : \"member2.member_account\", \n" + " \"partitionFunction\" : \"constant:1\", \n" + " \"partition\" : 1 \n" + " }\n" + " ]\n" + "}"; static final String _configSource2 = "{\n" + " \"name\" : \"multBufferTest2\",\n" + " \"id\" : 101,\n" + " \"uri\" : \"uri2\",\n" + " \"slowSourceQueryThreshold\" : 2000,\n" + " \"sources\" :\n" + " [\n" + " {\"id\" : 11, \n" + " \"name\" : \"srcName11\",\n" + " \"uri\": \"member2.member_profile\", \n" + " \"partitionFunction\" : \"constant:1\",\n" + " \"partition\" : 0 \n" + " },\n" + " {\"id\" : 12, \n" + " \"name\" : \"srcName12\",\n" + " \"uri\" : \"member2.member_account\", \n" + " \"partitionFunction\" : \"constant:1\",\n" + " \"partition\" : 0 \n" + " },\n" + " {\"id\" : 12, \n" + " \"name\" : \"srcName12\",\n" + " \"uri\" : \"member2.member_account\", \n" + " \"partitionFunction\" : \"constant:1\"\n" + " },\n" + " {\"id\" : 2, \n" + " \"name\" : \"srcName2\",\n" + " \"uri\" : \"member2.member_account\", \n" + " \"partitionFunction\" : \"constant:1\", \n" + " \"partition\" : 2 \n" + " }\n" + " ]\n" + "}"; static final String _configSource3 = "{\n" + " \"name\" : \"multBufferTest3\",\n" + " \"id\" : 102,\n" + " \"uri\" : \"uri3\",\n" + " \"slowSourceQueryThreshold\" : 2000,\n" + " \"sources\" :\n" + " [\n" + " {\"id\" : 21, \n" + " \"name\" : \"srcName21\",\n" + " \"uri\": \"member2.member_profile\", \n" + " \"partitionFunction\" : \"constant:1\", \n" + " \"partition\" : 0 \n" + " },\n" + " {\"id\" : 22, \n" + " \"name\" : \"srcName22\",\n" + " \"uri\" : \"member2.member_account\", \n" + " \"partitionFunction\" : \"constant:1\", \n" + " \"partition\" : 0 \n" + " },\n" + " {\"id\" : 23, \n" + " \"name\" : \"srcName23\",\n" + " \"uri\" : \"member2.member_account\", \n" + " \"partitionFunction\" : \"constant:1\", \n" + " \"partition\" : 0 \n" + " }\n" + " ]\n" + "}"; public PhysicalSourceConfig convertToPhysicalSourceConfig(String str) { _mapper = new ObjectMapper(); InputStreamReader isr = new InputStreamReader(IOUtils.toInputStream(str)); PhysicalSourceConfig pConfig = null; try { pConfig = _mapper.readValue(isr, PhysicalSourceConfig.class); } catch (JsonParseException e) { fail("Failed parsing", e); } catch (JsonMappingException e){ fail("Failed parsing", e); } catch (IOException e){ fail("Failed parsing", e); } try { isr.close(); } catch (IOException e) { fail("Failed",e); } return pConfig; } @BeforeTest public void setUpTest () throws IOException, InvalidConfigException { LOG.info("Setting up Test"); PhysicalSourceStaticConfig pStatConf1 = convertToPhysicalSourceConfig(_configSource1).build(); PhysicalSourceStaticConfig pStatConf2 = convertToPhysicalSourceConfig(_configSource2).build(); PhysicalSourceStaticConfig pStatConf3 = convertToPhysicalSourceConfig(_configSource3).build(); _pConfigs = new PhysicalSourceStaticConfig [] {pStatConf1, pStatConf2, pStatConf3}; // generate testData int scn = 100; String srcName = "srcName"; int srcId = 1; PhysicalSource pS = pStatConf1.getPhysicalSource(); PhysicalPartition pP = pStatConf1.getPhysicalPartition(); _events = new TestDbusEvent [20]; LogicalPartition lP = new LogicalPartition((short)0); for(int i=0; i<_events.length; i++) { _events[i] = new TestDbusEvent(i, scn, new LogicalSource(srcId, srcName+srcId), pS, pP, lP); switch(i) { case 4: srcId =2; break; case 9: srcId = 11; pS = pStatConf2.getPhysicalSource(); pP = pStatConf2.getPhysicalPartition(); break; case 14: srcId = 12; break; } if((i & 1) == 1) scn++; }; } private static class TestDbusEvent { public TestDbusEvent(int k, int scn, LogicalSource lS, PhysicalSource pS, PhysicalPartition pP, LogicalPartition lP) { _key = k; _scn = scn; _lSource = lS; _lPartition=lP; _phPartition=pP; _phSource=pS; } public int _key; public int _scn; public LogicalSource _lSource; public PhysicalPartition _phPartition; public PhysicalSource _phSource; public LogicalPartition _lPartition; } // create the bufs - we want a new set for every test private void createBufMult() throws InvalidConfigException { if(_config == null) { try { DbusEventBuffer.Config cfgBuilder = new DbusEventBuffer.Config(); LOG.info("max size = " + cfgBuilder.getMaxSize()); LOG.info("scnIndex size = " + cfgBuilder.getScnIndexSize()); cfgBuilder.setMaxSize(10*1024*1024); cfgBuilder.setScnIndexSize(2*1024*1024); cfgBuilder.setAllocationPolicy("MMAPPED_MEMORY"); _config = cfgBuilder.build(); //_config = new DbusEventBuffer.Config().build(); } catch (InvalidConfigException e) { fail("invalid configuration" ,e); } } _eventBufferMult = new DbusEventBufferMult(_pConfigs, _config, new DbusEventV2Factory()); for(DbusEventBuffer b : _eventBufferMult.bufIterable()) { b.start(1); } } private void addEvents() { byte [] schema = "abcdefghijklmnop".getBytes(Charset.defaultCharset()); for(int i=0; i<_events.length; i++) { TestDbusEvent e = _events[i]; DbusEventBufferAppendable buf = _eventBufferMult.getDbusEventBufferAppendable(e._phPartition); //System.out.println("i= " + i + "; phS = " + e._phSource + "; phP = " + e._phPartition + // "; buf=" + buf.hashCode()); // two events per scn if(i%2 == 0) buf.startEvents(); DbusEventKey key = new DbusEventKey(e._key); //short lPartitionId = (short) (key.getLongKey() % Short.MAX_VALUE); String value = "" + i; short srcId = e._lSource.getId().shortValue(); LogicalPartition lPart = e._lPartition; //System.out.print("appending events for i=" + i + "; lSource=" + srcId); short pPartitionId = _eventBufferMult.getPhysicalPartition(srcId, lPart).getId().shortValue(); //System.out.println(";partitionid=" + pPartitionId); assertTrue(buf.appendEvent(key, pPartitionId, lPart.getId(), System.currentTimeMillis(), srcId, schema, value.getBytes(Charset.defaultCharset()), false, null)); if(i%2 != 0) buf.endEvents(e._scn, null); } } @Test public void verifyMultBuffer() throws InvalidConfigException { createBufMult(); assertEquals(_eventBufferMult.bufsNum(), 3); } @Test // reading from the source that belong to the same physical buffer public void verifyReadingSingleBuf() throws IOException, ScnNotFoundException, DatabusException, OffsetNotFoundException { createBufMult(); addEvents(); Set<Integer> srcIds = new HashSet<Integer>(2); srcIds.add(1); srcIds.add(2); // total expected events 15 = 10 original (from first buffer (src 1 and 2) + 5 control events batchReading(srcIds, 10); } @Test //reading from the source that belong to two different physical buffers public void verifyReadingMultBuf() throws IOException, ScnNotFoundException, InvalidConfigException, DatabusException, OffsetNotFoundException { verifyReadingMultBuf(2000); verifyReadingMultBuf(100); // Pretty much only one event can fit at a time. } private void verifyReadingMultBuf(final int batchFetchSize) throws IOException, ScnNotFoundException, InvalidConfigException, DatabusException, OffsetNotFoundException { createBufMult(); addEvents(); Set<Integer> srcIds = new HashSet<Integer>(2); srcIds.add(1); srcIds.add(12); // total expected events 20 = 20 original events - 10 filtered out (srcs 2 and 11) batchReading(srcIds, 10, batchFetchSize); } @Test public void verifyReadingLogicalPartitionWildcard() throws IOException, ScnNotFoundException, InvalidConfigException, DatabusException, OffsetNotFoundException { createBufMult(); PhysicalSourceStaticConfig pStatConf1 = convertToPhysicalSourceConfig(_configSource1).build(); PhysicalSourceStaticConfig pStatConf2 = convertToPhysicalSourceConfig(_configSource2).build(); PhysicalPartition pP = pStatConf1.getPhysicalPartition(); DbusEventBufferAppendable buf = _eventBufferMult.getDbusEventBufferAppendable(pP); buf.startEvents(); byte [] schema = "abcdefghijklmnop".getBytes(Charset.defaultCharset()); assertTrue(buf.appendEvent(new DbusEventKey(1), (short)100, (short)0, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); assertTrue(buf.appendEvent(new DbusEventKey(1), (short)100, (short)1, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); buf.endEvents(100, null); pP = pStatConf2.getPhysicalPartition(); buf = _eventBufferMult.getDbusEventBufferAppendable(pP); buf.startEvents(); assertTrue(buf.appendEvent(new DbusEventKey(1), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); buf.endEvents(200, null); Set<Integer> srcIds = new HashSet<Integer>(1); srcIds.add(2); // total expected events 3 - for pp100:lp=0,pp100:lp=1;pp101:lp=2 batchReading(srcIds, 3); } private StatsCollectors<DbusEventsStatisticsCollector> createStats(String[] pNames) { DbusEventsStatisticsCollector stats = new AggregatedDbusEventsStatisticsCollector(1, "test", true, true, null); StatsCollectors<DbusEventsStatisticsCollector> statsColl = new StatsCollectors<DbusEventsStatisticsCollector>(stats); int count = 1; for (String pname : pNames) { DbusEventsStatisticsCollector s = new DbusEventsStatisticsCollector(1, "test"+count, true, true, null); statsColl.addStatsCollector(pname, s); ++count; } return statsColl; } @Test public void testMultiPPartionStreamStats() throws Exception { createBufMult(); PhysicalPartition[] p = {_pConfigs[0].getPhysicalPartition(), _pConfigs[1].getPhysicalPartition(), _pConfigs[2].getPhysicalPartition() }; //generate a bunch of windows for 3 partitions int windowsNum = 10; for (int i = 1; i <= windowsNum; ++i) { DbusEventBufferAppendable buf = _eventBufferMult.getDbusEventBufferAppendable(p[0]); buf.startEvents(); byte [] schema = "abcdefghijklmnop".getBytes(Charset.defaultCharset()); assertTrue(buf.appendEvent(new DbusEventKey(1), (short)100, (short)0, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[10], false, null)); buf.endEvents(100 * i, null); buf = _eventBufferMult.getDbusEventBufferAppendable(p[1]); buf.startEvents(); assertTrue(buf.appendEvent(new DbusEventKey(1), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); assertTrue(buf.appendEvent(new DbusEventKey(2), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[10], false, null)); buf.endEvents(100 * i + 1, null); buf = _eventBufferMult.getDbusEventBufferAppendable(p[2]); buf.startEvents(); assertTrue(buf.appendEvent(new DbusEventKey(1), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); assertTrue(buf.appendEvent(new DbusEventKey(2), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[10], false, null)); assertTrue(buf.appendEvent(new DbusEventKey(3), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[10], false, null)); buf.endEvents(100 * i + 2, null); } String[] pnames = new String[p.length]; int count=0; for (PhysicalPartition ip:p) { pnames[count++] = ip.toSimpleString(); } StatsCollectors<DbusEventsStatisticsCollector> statsColl = createStats(pnames); PhysicalPartitionKey[] pkeys = {new PhysicalPartitionKey(p[0]), new PhysicalPartitionKey(p[1]), new PhysicalPartitionKey(p[2])}; CheckpointMult cpMult = new CheckpointMult(); for (int i =0; i < 3; ++i) { Checkpoint cp = new Checkpoint(); cp.setFlexible(); cp.setConsumptionMode(DbusClientMode.ONLINE_CONSUMPTION); cpMult.addCheckpoint(p[i], cp); } DbusEventBufferBatchReadable reader = _eventBufferMult.getDbusEventBufferBatchReadable(cpMult, Arrays.asList(pkeys), statsColl); ByteArrayOutputStream baos = new ByteArrayOutputStream(); WritableByteChannel writeChannel = Channels.newChannel(baos); reader.streamEvents(false, 1000000, writeChannel, Encoding.BINARY, new AllowAllDbusFilter()); writeChannel.close(); baos.close(); //make sure we got the physical partition names right List<String> ppartNames = statsColl.getStatsCollectorKeys(); assertEquals(ppartNames.size(), 3); HashSet<String> expectedPPartNames = new HashSet<String>(Arrays.asList(p[0].toSimpleString(), p[1].toSimpleString(), p[2].toSimpleString())); for (String ppartName: ppartNames) { assertTrue(expectedPPartNames.contains(ppartName)); } //verify event counts per partition DbusEventsTotalStats[] ppartStats = {statsColl.getStatsCollector(p[0].toSimpleString()).getTotalStats(), statsColl.getStatsCollector(p[1].toSimpleString()).getTotalStats(), statsColl.getStatsCollector(p[2].toSimpleString()).getTotalStats()}; assertEquals(ppartStats[0].getNumDataEvents(), windowsNum); assertEquals(ppartStats[1].getNumDataEvents(), windowsNum * 2); assertEquals(ppartStats[2].getNumDataEvents(), windowsNum * 3); assertEquals(ppartStats[0].getNumSysEvents(), windowsNum); assertEquals(ppartStats[1].getNumSysEvents(), windowsNum); assertEquals(ppartStats[2].getNumSysEvents(), windowsNum); assertEquals(statsColl.getStatsCollector().getTotalStats().getNumDataEvents(), windowsNum * (1 + 2 + 3)); assertEquals(statsColl.getStatsCollector().getTotalStats().getNumSysEvents(), windowsNum * 3); assertEquals(statsColl.getStatsCollector().getTotalStats().getMaxTimeLag(), Math.max(ppartStats[0].getTimeLag(), Math.max(ppartStats[1].getTimeLag(), ppartStats[2].getTimeLag()))); assertEquals(statsColl.getStatsCollector().getTotalStats().getMinTimeLag(), Math.min(ppartStats[0].getTimeLag(), Math.min(ppartStats[1].getTimeLag(), ppartStats[2].getTimeLag()))); } @Test public void testSinglePPartionStreamFromLatest() throws Exception { createBufMult(); PhysicalPartition[] p = {_pConfigs[0].getPhysicalPartition() }; //generate a bunch of windows for 3 partitions int windowsNum = 10; for (int i = 1; i <= windowsNum; ++i) { DbusEventBufferAppendable buf = _eventBufferMult.getDbusEventBufferAppendable(p[0]); buf.startEvents(); byte [] schema = "abcdefghijklmnop".getBytes(Charset.defaultCharset()); assertTrue(buf.appendEvent(new DbusEventKey(1), (short)100, (short)0, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[10], false, null)); buf.endEvents(100 * i, null); } String[] pnames = new String[p.length]; int count=0; for (PhysicalPartition ip:p) { pnames[count++] = ip.toSimpleString(); } StatsCollectors<DbusEventsStatisticsCollector> statsColl = createStats(pnames); PhysicalPartitionKey[] pkeys = {new PhysicalPartitionKey(p[0]) }; CheckpointMult cpMult = new CheckpointMult(); Checkpoint cp = new Checkpoint(); cp.setFlexible(); cp.setConsumptionMode(DbusClientMode.ONLINE_CONSUMPTION); cpMult.addCheckpoint(p[0], cp); DbusEventBufferBatchReadable reader = _eventBufferMult.getDbusEventBufferBatchReadable(cpMult, Arrays.asList(pkeys), statsColl); ByteArrayOutputStream baos = new ByteArrayOutputStream(); WritableByteChannel writeChannel = Channels.newChannel(baos); // Set streamFromLatestScn == true reader.streamEvents(true, 1000000, writeChannel, Encoding.BINARY, new AllowAllDbusFilter()); writeChannel.close(); baos.close(); //make sure we got the physical partition names right List<String> ppartNames = statsColl.getStatsCollectorKeys(); assertEquals(ppartNames.size(), 1); HashSet<String> expectedPPartNames = new HashSet<String>(Arrays.asList(p[0].toSimpleString())); for (String ppartName: ppartNames) { assertTrue(expectedPPartNames.contains(ppartName)); } //verify event counts per partition DbusEventsTotalStats[] ppartStats = {statsColl.getStatsCollector(p[0].toSimpleString()).getTotalStats()}; // Only the last window is returned in each of the partitions assertEquals(ppartStats[0].getNumDataEvents(), 1); assertEquals(ppartStats[0].getNumSysEvents(), 1); assertEquals(statsColl.getStatsCollector().getTotalStats().getNumDataEvents(), (1)); assertEquals(statsColl.getStatsCollector().getTotalStats().getNumSysEvents(), (1)); assertEquals(statsColl.getStatsCollector().getTotalStats().getMaxTimeLag(), ppartStats[0].getTimeLag()); assertEquals(statsColl.getStatsCollector().getTotalStats().getMinTimeLag(), ppartStats[0].getTimeLag()); } @Test public void testMultiPPartionStreamFromLatest() throws Exception { createBufMult(); PhysicalPartition[] p = {_pConfigs[0].getPhysicalPartition(), _pConfigs[1].getPhysicalPartition(), _pConfigs[2].getPhysicalPartition() }; //generate a bunch of windows for 3 partitions int windowsNum = 10; for (int i = 1; i <= windowsNum; ++i) { DbusEventBufferAppendable buf = _eventBufferMult.getDbusEventBufferAppendable(p[0]); buf.startEvents(); byte [] schema = "abcdefghijklmnop".getBytes(Charset.defaultCharset()); assertTrue(buf.appendEvent(new DbusEventKey(1), (short)100, (short)0, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[10], false, null)); buf.endEvents(100 * i, null); buf = _eventBufferMult.getDbusEventBufferAppendable(p[1]); buf.startEvents(); assertTrue(buf.appendEvent(new DbusEventKey(1), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); assertTrue(buf.appendEvent(new DbusEventKey(2), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[10], false, null)); buf.endEvents(100 * i + 1, null); buf = _eventBufferMult.getDbusEventBufferAppendable(p[2]); buf.startEvents(); assertTrue(buf.appendEvent(new DbusEventKey(1), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); assertTrue(buf.appendEvent(new DbusEventKey(2), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[10], false, null)); assertTrue(buf.appendEvent(new DbusEventKey(3), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[10], false, null)); buf.endEvents(100 * i + 2, null); } String[] pnames = new String[p.length]; int count=0; for (PhysicalPartition ip:p) { pnames[count++] = ip.toSimpleString(); } StatsCollectors<DbusEventsStatisticsCollector> statsColl = createStats(pnames); PhysicalPartitionKey[] pkeys = {new PhysicalPartitionKey(p[0]), new PhysicalPartitionKey(p[1]), new PhysicalPartitionKey(p[2])}; CheckpointMult cpMult = new CheckpointMult(); for (int i =0; i < 3; ++i) { Checkpoint cp = new Checkpoint(); cp.setFlexible(); cp.setConsumptionMode(DbusClientMode.ONLINE_CONSUMPTION); cpMult.addCheckpoint(p[i], cp); } DbusEventBufferBatchReadable reader = _eventBufferMult.getDbusEventBufferBatchReadable(cpMult, Arrays.asList(pkeys), statsColl); ByteArrayOutputStream baos = new ByteArrayOutputStream(); WritableByteChannel writeChannel = Channels.newChannel(baos); // Set streamFromLatestScn == true reader.streamEvents(true, 1000000, writeChannel, Encoding.BINARY, new AllowAllDbusFilter()); writeChannel.close(); baos.close(); //make sure we got the physical partition names right List<String> ppartNames = statsColl.getStatsCollectorKeys(); assertEquals(ppartNames.size(), 3); HashSet<String> expectedPPartNames = new HashSet<String>(Arrays.asList(p[0].toSimpleString(), p[1].toSimpleString(), p[2].toSimpleString())); for (String ppartName: ppartNames) { assertTrue(expectedPPartNames.contains(ppartName)); } //verify event counts per partition DbusEventsTotalStats[] ppartStats = {statsColl.getStatsCollector(p[0].toSimpleString()).getTotalStats(), statsColl.getStatsCollector(p[1].toSimpleString()).getTotalStats(), statsColl.getStatsCollector(p[2].toSimpleString()).getTotalStats()}; // Only the last window is returned in each of the partitions assertEquals(ppartStats[0].getNumDataEvents(), 1); assertEquals(ppartStats[1].getNumDataEvents(), 2); assertEquals(ppartStats[2].getNumDataEvents(), 3); assertEquals(ppartStats[0].getNumSysEvents(), 1); assertEquals(ppartStats[1].getNumSysEvents(), 1); assertEquals(ppartStats[2].getNumSysEvents(), 1); assertEquals(statsColl.getStatsCollector().getTotalStats().getNumDataEvents(), (1+2+3)); assertEquals(statsColl.getStatsCollector().getTotalStats().getNumSysEvents(), (1+1+1)); assertEquals(statsColl.getStatsCollector().getTotalStats().getMaxTimeLag(), Math.max(ppartStats[0].getTimeLag(), Math.max(ppartStats[1].getTimeLag(), ppartStats[2].getTimeLag()))); assertEquals(statsColl.getStatsCollector().getTotalStats().getMinTimeLag(), Math.min(ppartStats[0].getTimeLag(), Math.min(ppartStats[1].getTimeLag(), ppartStats[2].getTimeLag()))); } private void batchReading(Set<Integer> srcIds, final int expectEvents) throws IOException, ScnNotFoundException, DatabusException, OffsetNotFoundException { batchReading(srcIds, expectEvents, 2000); } private void batchReading(Set<Integer> srcIds, final int expectEvents, final int batchFetchSize) throws IOException, ScnNotFoundException, DatabusException, OffsetNotFoundException { // for debug generate this line String inputSrcIds = Arrays.toString(srcIds.toArray()); LOG.info("Reading events from " + inputSrcIds); // create checkpoints CheckpointMult cpMult = new CheckpointMult(); for(PhysicalSourceStaticConfig pConf : _pConfigs) { PhysicalPartition pPart = pConf.getPhysicalPartition(); Checkpoint cp; if(cpMult.getCheckpoint(pPart) == null) { // needs a new checkpoint cp = new Checkpoint(); cp.setFlexible(); cpMult.addCheckpoint(pPart, cp); } } DbusEventBufferBatchReadable read = _eventBufferMult.getDbusEventBufferBatchReadable(srcIds, cpMult, null); int totalRead = 0; int numEventsRead = Integer.MAX_VALUE; int numNonControlEventsRead = 0; int maxIterNum = 100, iterCount = 0; String prevEvent = ""; while(numEventsRead > 0) { if(iterCount++ > maxIterNum) { fail("Checkpoint doesn't work - it is a never-ending loop"); } ByteArrayOutputStream jsonOut = new ByteArrayOutputStream(); WritableByteChannel jsonOutChannel = Channels.newChannel(jsonOut); numEventsRead = read.streamEvents(false, batchFetchSize, jsonOutChannel, Encoding.JSON_PLAIN_VALUE, new SourceDbusFilter(srcIds)).getNumEventsStreamed(); totalRead += numEventsRead; LOG.info("read for " + inputSrcIds + ": " + numEventsRead + " events"); byte[] jsonBytes = jsonOut.toByteArray(); if(jsonBytes.length == 0) break; // nothing more to read String jsonString = new String(jsonBytes); String [] jsonStrings = jsonString.split("\n"); assertEquals(jsonStrings.length, numEventsRead); ObjectMapper mapper = new ObjectMapper(); for(int i=0; i<jsonStrings.length; i++) { // verify what was written String evtStr = jsonStrings[i]; if (evtStr.equals(prevEvent)) { // It may so happen that we receive the same event twice, especially when the // offered buffer is small. This check gets around the issue. continue; } prevEvent = evtStr; Map<String, Object> jsonMap = mapper.readValue(evtStr, new TypeReference<Map<String, Object>>(){}); //assertEquals(jsonMap.size(), 10); Integer srcId = (Integer)jsonMap.get("srcId"); if(!DbusEventUtils.isControlSrcId(srcId)) { // not a control message numNonControlEventsRead++; Integer physicalPartitionId = (Integer)jsonMap.get("physicalPartitionId"); Integer logicalPartitionId = (Integer)jsonMap.get("logicalPartitionId"); PhysicalPartition pPartition = _eventBufferMult.getPhysicalPartition(srcId, new LogicalPartition(logicalPartitionId.shortValue())); LOG.info("EVENT: " + jsonMap.toString()); assertTrue( srcIds.contains(srcId), "src id " + srcId + " doesn't match to " + inputSrcIds); assertEquals(physicalPartitionId, pPartition.getId(), "physical partition id didn't match"); } else { LOG.info("Control event: " + jsonMap.toString()); } } } assertTrue(totalRead>numNonControlEventsRead); assertEquals(numNonControlEventsRead, expectEvents); } @BeforeClass public void setupClass() { TestUtil.setupLoggingWithTimestampedFile(true, "/tmp/TestDbusEventBufferMult_", ".log", Level.INFO); } @Test public void testGetBuffer() throws InvalidConfigException { // get buffer by physical partition createBufMult(); addEvents(); Integer pPartitionId = 100; // get buffer by partition id PhysicalPartition pPartition = new PhysicalPartition(pPartitionId, "multBufferTest1"); DbusEventBufferAppendable buf = _eventBufferMult.getDbusEventBufferAppendable(pPartition); assertNotNull(buf,"cannot get by pPartition" + pPartition); // get buffer by physical partition buf = _eventBufferMult.getDbusEventBufferAppendable(pPartition); assertNotNull(buf,"cannot get by pPartition" + pPartition); // get buffer by logical source id int lSrcId = 1; buf = _eventBufferMult.getDbusEventBufferAppendable(lSrcId); assertNotNull(buf,"cannot get by lSrcId" + lSrcId); // logical source 2 , default partition - SAME BUFFER lSrcId = 2; LogicalSource lSource = new LogicalSource(lSrcId, "srcName2"); // correct source name, default partition 0 DbusEventBufferAppendable buf1 = _eventBufferMult.getDbusEventBufferAppendable(lSource); assertNotNull(buf1, "cannot get buffer by lSource " + lSource); assertTrue(buf1 == buf, "buf and buf1 should be the same buffer"); // logical source, different logical partition 1 - SAME BUFFER LogicalPartition lPartition = new LogicalPartition((short)1); buf1 = _eventBufferMult.getDbusEventBufferAppendable(lSource, lPartition); // should be the same buffer assertNotNull(buf1, "cannot get buffer by lSource " + lSource + ";lPartition =" + lPartition); assertTrue(buf1 == buf, "buf and buf1 should be the same buffer"); // logical source, different logical partition 2 - DIFFERENT BUFFER lPartition = new LogicalPartition((short)2); buf1 = _eventBufferMult.getDbusEventBufferAppendable(lSource, lPartition); assertNotNull(buf1, "cannot get buffer by lSource " + lSource + ";lPartition =" + lPartition); assertTrue(buf1 != buf, "buf and buf1 should not be the same buffer"); // logical source, different logical partition 12 - DIFFERENT BUFFER (same as for lsr=2,lp=2) DbusEventBufferAppendable buf2 = _eventBufferMult.getDbusEventBufferAppendable(12); assertNotNull(buf2, "cannot get buffer by lSourceid " + 12); assertTrue(buf2 != buf, "buf and buf2 should not be the same buffer"); assertTrue(buf1 == buf2, "buf2 and buf1 should be the same buffer"); } @Test public void testReset() throws Exception { createBufMult(); addEvents(); Integer pPartitionId = 100; PhysicalPartition pPartition = new PhysicalPartition(pPartitionId, "multBufferTest1"); _eventBufferMult.resetBuffer(pPartition, 108L); DbusEventBufferAppendable eventBuffer = _eventBufferMult.getDbusEventBufferAppendable(pPartition); Assert.assertTrue(eventBuffer.empty()); pPartition = new PhysicalPartition(pPartitionId, "unknownBuffer"); boolean caughtException = false; try { _eventBufferMult.resetBuffer(pPartition, -1L); } catch(BufferNotFoundException e) { caughtException = true; } assertTrue(caughtException); } @Test public void testConstructFilters() throws Exception { TestSetup t = new TestSetup(); //test single Physical Partition subscription DatabusSubscription sub1 = DatabusSubscription.createPhysicalPartitionReplicationSubscription(new PhysicalPartition(100, "multBufferTest1")); DbusFilter filter1 = t._eventBuffer.constructFilters(Arrays.asList(sub1)); assertNotNull(filter1); assertTrue(filter1 instanceof PhysicalPartitionDbusFilter); PhysicalPartitionDbusFilter ppfilter1 = (PhysicalPartitionDbusFilter)filter1; assertEquals(ppfilter1.getPhysicalPartition(), new PhysicalPartition(100, "multBufferTest1")); assertNull(ppfilter1.getNestedFilter()); DatabusSubscription sub2 = DatabusSubscription.createPhysicalPartitionReplicationSubscription(new PhysicalPartition(101, "multBufferTest2")); //test two Physical Partition subscriptions DbusFilter filter2 = t._eventBuffer.constructFilters(Arrays.asList(sub1, sub2)); assertNotNull(filter2); assertTrue(filter2 instanceof ConjunctionDbusFilter); ConjunctionDbusFilter conjFilter2 = (ConjunctionDbusFilter)filter2; boolean hasPP100 = false; boolean hasPP101 = false; assertEquals(conjFilter2.getFilterList().size(), 2); for (DbusFilter f: conjFilter2.getFilterList()) { assertTrue(f instanceof PhysicalPartitionDbusFilter); PhysicalPartitionDbusFilter ppf = (PhysicalPartitionDbusFilter)f; if (ppf.getPhysicalPartition().getId() == 100) hasPP100 = true; else if (ppf.getPhysicalPartition().getId() == 101) hasPP101 = true; else fail("unknown physical partition filter:" + ppf.getPhysicalPartition()); } assertTrue(hasPP100); assertTrue(hasPP101); //test a subcription with a logical source DatabusSubscription sub3 = DatabusSubscription.createSimpleSourceSubscription(new LogicalSource(2, "srcName2")); DbusFilter filter3 = t._eventBuffer.constructFilters(Arrays.asList(sub3)); assertNotNull(filter3); assertTrue(filter3 instanceof PhysicalPartitionDbusFilter); PhysicalPartitionDbusFilter ppfilter3 = (PhysicalPartitionDbusFilter)filter3; assertEquals(ppfilter3.getPhysicalPartition(), PhysicalPartition.ANY_PHYSICAL_PARTITION); DbusFilter ppfilter3_child = ppfilter3.getNestedFilter(); assertNotNull(ppfilter3_child); assertTrue(ppfilter3_child instanceof LogicalSourceAndPartitionDbusFilter); LogicalSourceAndPartitionDbusFilter lsourceFilter3 = (LogicalSourceAndPartitionDbusFilter)ppfilter3_child; LogicalSourceAndPartitionDbusFilter.LogicalPartitionDbusFilter lpartFilter3_1 = lsourceFilter3.getSourceFilter(2); assertNotNull(lpartFilter3_1); assertTrue(lpartFilter3_1.isAllPartitionsWildcard()); //test a subcription with a physical and logical partition DatabusSubscription sub4 = new DatabusSubscription(PhysicalSource.MASTER_PHISYCAL_SOURCE, new PhysicalPartition(101, "multBufferTest2"), new LogicalSourceId(new LogicalSource(2, "srcName2"), (short)2) ); DbusFilter filter4 = t._eventBuffer.constructFilters(Arrays.asList(sub4)); assertNotNull(filter4); assertTrue(filter4 instanceof PhysicalPartitionDbusFilter); PhysicalPartitionDbusFilter ppfilter4 = (PhysicalPartitionDbusFilter)filter4; assertEquals(ppfilter4.getPhysicalPartition(), new PhysicalPartition(101, "multBufferTest2")); DbusFilter ppfilter4_child = ppfilter4.getNestedFilter(); assertNotNull(ppfilter4_child); assertTrue(ppfilter4_child instanceof LogicalSourceAndPartitionDbusFilter); LogicalSourceAndPartitionDbusFilter lsourceFilter4 = (LogicalSourceAndPartitionDbusFilter)ppfilter4_child; LogicalSourceAndPartitionDbusFilter.LogicalPartitionDbusFilter lpartFilter4_1 = lsourceFilter4.getSourceFilter(2); assertNotNull(lpartFilter4_1); assertTrue(lpartFilter4_1.getPartitionsMask().contains(2)); } @Test public void testSubscriptionStream() throws Exception { final Logger log = Logger.getLogger("TestDbusEventBufferMult.testSubscriptionStream"); log.info("start"); TestSetup t = new TestSetup(); PhysicalPartition pp100 = new PhysicalPartition(100, "multBufferTest1"); PhysicalPartitionKey pk1 = new PhysicalPartitionKey(pp100); PhysicalPartition pp101 = new PhysicalPartition(101, "multBufferTest2"); PhysicalPartitionKey pk2 = new PhysicalPartitionKey(pp101); //generate events in pp100 byte [] schema = "abcdefghijklmnop".getBytes(Charset.defaultCharset()); DbusEventBufferAppendable buf100 = t._eventBuffer.getDbusEventBufferAppendable(pp100); buf100.startEvents(); assertTrue(buf100.appendEvent(new DbusEventKey(1), (short)100, (short)0, System.currentTimeMillis() * 1000000, (short)1, schema, new byte[100], false, null)); assertTrue(buf100.appendEvent(new DbusEventKey(10), (short)100, (short)0, System.currentTimeMillis() * 1000000, (short)1, schema, new byte[100], false, null)); assertTrue(buf100.appendEvent(new DbusEventKey(11), (short)100, (short)0, System.currentTimeMillis() * 1000000, (short)1, schema, new byte[100], false, null)); assertTrue(buf100.appendEvent(new DbusEventKey(2), (short)100, (short)0, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); buf100.endEvents(100, null); buf100.startEvents(); assertTrue(buf100.appendEvent(new DbusEventKey(3), (short)100, (short)0, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); assertTrue(buf100.appendEvent(new DbusEventKey(4), (short)100, (short)1, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); buf100.endEvents(200, null); //generate events in pp100 DbusEventBufferAppendable buf101 = t._eventBuffer.getDbusEventBufferAppendable(pp101); buf101.startEvents(); assertTrue(buf101.appendEvent(new DbusEventKey(51), (short)101, (short)0, System.currentTimeMillis() * 1000000, (short)11, schema, new byte[100], false, null)); assertTrue(buf101.appendEvent(new DbusEventKey(52), (short)101, (short)0, System.currentTimeMillis() * 1000000, (short)12, schema, new byte[100], false, null)); assertTrue(buf101.appendEvent(new DbusEventKey(53), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); buf101.endEvents(120, null); buf101.startEvents(); assertTrue(buf101.appendEvent(new DbusEventKey(54), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); assertTrue(buf101.appendEvent(new DbusEventKey(55), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); assertTrue(buf101.appendEvent(new DbusEventKey(56), (short)101, (short)2, System.currentTimeMillis() * 1000000, (short)2, schema, new byte[100], false, null)); buf101.endEvents(200, null); //initialization DatabusSubscription sub1 = DatabusSubscription.createPhysicalPartitionReplicationSubscription(new PhysicalPartition(100, "multBufferTest1")); DbusFilter filter1 = t._eventBuffer.constructFilters(Arrays.asList(sub1)); assertNotNull(filter1); CheckpointMult cpMult1 = new CheckpointMult(); Checkpoint cp100 = new Checkpoint(); cp100.init(); cp100.setConsumptionMode(DbusClientMode.ONLINE_CONSUMPTION); cp100.setWindowScn(10L); cp100.setWindowOffset(-1); cpMult1.addCheckpoint(pp100, cp100); String[] pnames = {"multBufferTest1:100","multBufferTest2:101"}; StatsCollectors<DbusEventsStatisticsCollector> statsColls1 = createStats(pnames); DbusEventsStatisticsCollector statsCol1 = statsColls1.getStatsCollector("multBufferTest1:100"); DbusEventsStatisticsCollector statsCol2 = statsColls1.getStatsCollector("multBufferTest2:101"); //read an entire buffer DbusEventBufferBatchReadable reader1 = t._eventBuffer.getDbusEventBufferBatchReadable(cpMult1, Arrays.asList(pk1), statsColls1); ByteArrayOutputStream baos = new ByteArrayOutputStream(); // Try a call with 20 bytes of fetch size, we should see the event size in the first return with 0 events read. StreamEventsResult result = reader1.streamEvents(false, 20, Channels.newChannel(baos), Encoding.BINARY, filter1); assertEquals(0, result.getNumEventsStreamed()); assertEquals(161, result.getSizeOfPendingEvent()); result = reader1.streamEvents(false, 1000000, Channels.newChannel(baos), Encoding.BINARY, filter1); int eventsRead = result.getNumEventsStreamed(); assertEquals(eventsRead, 8); //4 events + 1 eop + 2 events + 1 eop assertEquals(statsColls1.getStatsCollector("multBufferTest1:100").getTotalStats().getNumSysEvents(), 2); assertEquals(statsColls1.getStatsCollector("multBufferTest1:100").getTotalStats().getNumDataEvents(), 6); assertEquals(result.getSizeOfPendingEvent(), 0, "Size of pending event not zero"); // Now that we have read all the events, we should not see a pending event even if we offer a small fetch size. result = reader1.streamEvents(false, 20, Channels.newChannel(baos), Encoding.BINARY, filter1); assertEquals(0, result.getNumEventsStreamed(), "There should be no more events in the buffer now"); assertEquals(0, result.getSizeOfPendingEvent(), "We should not see pending event size since there are no events in buffer"); baos.reset(); statsCol1.reset(); statsCol2.reset(); //read from two buffers, filtering out one cpMult1 = new CheckpointMult(); cp100.init(); cp100.setConsumptionMode(DbusClientMode.ONLINE_CONSUMPTION); cp100.setWindowScn(10L); cp100.setWindowOffset(-1); cpMult1.addCheckpoint(pp100, cp100); reader1 = t._eventBuffer.getDbusEventBufferBatchReadable(cpMult1, Arrays.asList(pk1, pk2), statsColls1); eventsRead = reader1.streamEvents(false, 1000000, Channels.newChannel(baos), Encoding.BINARY, filter1).getNumEventsStreamed(); assertEquals(eventsRead, 10); //4 events + 1 eop + 1 eop from the other buffer + 2 events + //1 eop + 1 eop from the other buffer assertEquals(statsColls1.getStatsCollector("multBufferTest1:100").getTotalStats().getNumSysEvents(), 2); assertEquals(statsColls1.getStatsCollector("multBufferTest1:100").getTotalStats().getNumDataEvents(), 6); baos.reset(); statsCol1.reset(); //read from one buffer and one source partition DatabusSubscription sub2 = new DatabusSubscription(PhysicalSource.MASTER_PHISYCAL_SOURCE, new PhysicalPartition(101, "multBufferTest2"), new LogicalSourceId(new LogicalSource(2, "srcName2"), (short)2) ); DbusFilter filter2 = t._eventBuffer.constructFilters(Arrays.asList(sub2)); assertNotNull(filter2); CheckpointMult cpMult2 = new CheckpointMult(); Checkpoint cp101 = new Checkpoint(); cp101.init(); cp101.setConsumptionMode(DbusClientMode.ONLINE_CONSUMPTION); cp101.setWindowScn(10L); cp101.setWindowOffset(-1); cpMult2.addCheckpoint(pp101, cp101); DbusEventBufferBatchReadable reader2 = t._eventBuffer.getDbusEventBufferBatchReadable(cpMult2, Arrays.asList(pk2), statsColls1); eventsRead = reader2.streamEvents(false, 1000000, Channels.newChannel(baos), Encoding.BINARY, filter2).getNumEventsStreamed(); assertEquals(eventsRead, 6); //1 events + 1 eop + 3events + 1 eop baos.reset(); statsCol1.reset();statsCol2.reset(); //read all partitions for a source DatabusSubscription sub3 = new DatabusSubscription(PhysicalSource.MASTER_PHISYCAL_SOURCE, PhysicalPartition.ANY_PHYSICAL_PARTITION, LogicalSourceId.createAllPartitionsWildcard(new LogicalSource(2, "srcName2")) ); DbusFilter filter3 = t._eventBuffer.constructFilters(Arrays.asList(sub3)); assertNotNull(filter3); CheckpointMult cpMult3 = new CheckpointMult(); cp100.init(); cp100.setConsumptionMode(DbusClientMode.ONLINE_CONSUMPTION); cp100.setWindowScn(10L); cp100.setWindowOffset(-1); cpMult1.addCheckpoint(pp100, cp100); cp101.init(); cp101.setConsumptionMode(DbusClientMode.ONLINE_CONSUMPTION); cp101.setWindowScn(10L); cp101.setWindowOffset(-1); cpMult2.addCheckpoint(pp101, cp101); DbusEventBufferBatchReadable reader3 = t._eventBuffer.getDbusEventBufferBatchReadable(cpMult3, Arrays.asList(pk1, pk2), statsColls1); eventsRead = reader3.streamEvents(false, 1000000, Channels.newChannel(baos), Encoding.BINARY, filter3).getNumEventsStreamed(); assertEquals(eventsRead, 11); //1 events + 1 eop + 1 events + 1 eop + 2 events + 1 eop + 3 events + 1 eop assertEquals(statsColls1.getStatsCollector("multBufferTest1:100").getTotalStats().getNumSysEvents(), 2); assertEquals(statsColls1.getStatsCollector("multBufferTest2:101").getTotalStats().getNumSysEvents(), 2); assertEquals(statsColls1.getStatsCollector("multBufferTest1:100").getTotalStats().getNumDataEventsFiltered(), 3); assertEquals(statsColls1.getStatsCollector("multBufferTest2:101").getTotalStats().getNumDataEventsFiltered(), 4); baos.reset(); statsCol1.reset(); statsCol2.reset(); log.info("end"); } @Test public void addRemoveBuffers() throws IOException, ScnNotFoundException, InvalidConfigException, DatabusException, OffsetNotFoundException { createBufMult(); addEvents(); Set<Integer> srcIds = new HashSet<Integer>(2); srcIds.add(1); // total expected events from source 1 is 5 batchReading(srcIds, 5); PhysicalSourceStaticConfig pConfig = convertToPhysicalSourceConfig(_configSource3).build(); LOG.info("one more buffer for " + pConfig); DbusEventBuffer buf = _eventBufferMult.addNewBuffer(pConfig, _config); buf.start(100); // add events to the new buffer byte [] schema = "ABCDEFGHIJKLMNOP".getBytes(Charset.defaultCharset()); for(int i=100; i<110; i++) { if(i%2 == 0) buf.startEvents(); assertTrue(buf.appendEvent(new DbusEventKey(i), pConfig.getPhysicalPartition().getId().shortValue(), (short)0, // logical source id System.currentTimeMillis(), (short)(i<105?21:22), schema, (""+i).getBytes(Charset.defaultCharset()), false, null)); if((i & 1) == 1) buf.endEvents(i); } // read from one old and one new buffer srcIds.clear(); srcIds.add(12); srcIds.add(22); // total expected events 10 - 5 from source 12, and 5 from source 22 batchReading(srcIds, 10); // remove a buf pConfig = convertToPhysicalSourceConfig(_configSource2).build(); _eventBufferMult.removeBuffer(pConfig); _eventBufferMult.deallocateRemovedBuffers(true); srcIds.clear(); srcIds.add(11); boolean failed = false; try { batchReading(srcIds, 5); failed = false; // didn't fail } catch (java.lang.AssertionError ae) { // expected failed = true; } Assert.assertTrue(failed, "should've failed for src 11, since the buffer was removed"+pConfig); } @Test public void addRemoveBufferMapping() throws InvalidConfigException, DatabusException { createBufMult(); PhysicalSourceStaticConfig pConfig = convertToPhysicalSourceConfig(_configSource2).build(); PhysicalPartition pPart = _eventBufferMult.getPhysicalPartition(11); Assert.assertNotNull(pPart); DbusEventBuffer buf = _eventBufferMult.getDbusEventBuffer(pConfig.getSources()[0].getLogicalSource()); Assert.assertNotNull(buf); DbusEventBuffer buf1 = _eventBufferMult.getOneBuffer(pPart); Assert.assertNotNull(buf1); Assert.assertTrue(buf == buf1, "same references to the buffer"); // now remove the buffer and the mapping _eventBufferMult.removeBuffer(pConfig); _eventBufferMult.deallocateRemovedBuffers(true); // same should fail pPart = _eventBufferMult.getPhysicalPartition(11); Assert.assertNull(pPart); buf = _eventBufferMult.getDbusEventBuffer(pConfig.getSources()[0].getLogicalSource()); Assert.assertNull(buf); buf1 = _eventBufferMult.getOneBuffer(pPart); Assert.assertNull(buf1); } @Test public void testEnableStreamFromLatest() throws DatabusException, IOException { CheckpointMult cp = null; Collection<PhysicalPartitionKey> phyPartitions = new ArrayList<PhysicalPartitionKey>(); DbusEventBufferMult db = new DbusEventBufferMult(); DbusEventBufferMult.DbusEventBufferBatchReader dbr = db.new DbusEventBufferBatchReader(cp, phyPartitions, null); // Return true only once if streamFromLatest == true PhysicalPartitionKey pk = new PhysicalPartitionKey(); Set<PhysicalPartitionKey> sls = new HashSet<PhysicalPartitionKey>(); boolean streamFromLatestScn = true; // The set is initially empty - meaning none of the partitions have been served Assert.assertTrue(dbr.computeStreamFromLatestScnForPartition(pk, sls, streamFromLatestScn)); Assert.assertEquals(sls.size(), 1); Assert.assertFalse(dbr.computeStreamFromLatestScnForPartition(pk, sls, streamFromLatestScn)); sls.clear(); // Check null input Assert.assertFalse(dbr.computeStreamFromLatestScnForPartition(null, sls, streamFromLatestScn)); streamFromLatestScn = false; // The set is initially empty - meaning none of the partitions have been served Assert.assertFalse(dbr.computeStreamFromLatestScnForPartition(pk, sls, streamFromLatestScn)); Assert.assertEquals(sls.size(), 0); Assert.assertFalse(dbr.computeStreamFromLatestScnForPartition(pk, sls, streamFromLatestScn)); Assert.assertEquals(sls.size(), 0); // Check null input Assert.assertFalse(dbr.computeStreamFromLatestScnForPartition(null, sls, streamFromLatestScn)); return; } }