/* * 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.geode.internal.cache; import static org.apache.geode.distributed.ConfigurationProperties.*; import static org.junit.Assert.*; import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; import java.util.HashSet; import java.util.List; import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; import org.junit.Test; import org.junit.experimental.categories.Category; import org.apache.geode.cache.AttributesFactory; import org.apache.geode.cache.Cache; import org.apache.geode.cache.CacheException; import org.apache.geode.cache.CacheFactory; import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.DiskStore; import org.apache.geode.cache.DiskStoreFactory; import org.apache.geode.cache.EntryNotFoundException; import org.apache.geode.cache.Operation; import org.apache.geode.cache.PartitionAttributesFactory; import org.apache.geode.cache.Region; import org.apache.geode.cache.Region.Entry; import org.apache.geode.cache.Scope; import org.apache.geode.cache.client.internal.LocatorDiscoveryCallbackAdapter; import org.apache.geode.cache.wan.GatewayEventFilter; import org.apache.geode.cache.wan.GatewayReceiver; import org.apache.geode.cache.wan.GatewayReceiverFactory; import org.apache.geode.cache.wan.GatewaySender; import org.apache.geode.cache.wan.GatewaySenderFactory; import org.apache.geode.distributed.internal.InternalDistributedSystem; import org.apache.geode.internal.AvailablePortHelper; import org.apache.geode.internal.cache.LocalRegion.NonTXEntry; import org.apache.geode.internal.cache.partitioned.PRLocallyDestroyedException; import org.apache.geode.internal.cache.versions.VersionSource; import org.apache.geode.internal.cache.versions.VersionStamp; import org.apache.geode.internal.cache.versions.VersionTag; import org.apache.geode.internal.cache.wan.InternalGatewaySenderFactory; import org.apache.geode.test.dunit.Host; import org.apache.geode.test.dunit.IgnoredException; import org.apache.geode.test.dunit.Invoke; import org.apache.geode.test.dunit.LogWriterUtils; import org.apache.geode.test.dunit.SerializableCallable; import org.apache.geode.test.dunit.SerializableRunnable; import org.apache.geode.test.dunit.VM; import org.apache.geode.test.dunit.Wait; import org.apache.geode.test.dunit.WaitCriterion; import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase; import org.apache.geode.test.junit.categories.DistributedTest; /** * @since GemFire 7.0.1 */ @Category(DistributedTest.class) public class UpdateVersionDUnitTest extends JUnit4DistributedTestCase { protected static final String regionName = "testRegion"; protected static Cache cache; private static Set<IgnoredException> expectedExceptions = new HashSet<IgnoredException>(); @Override public final void preTearDown() throws Exception { closeCache(); Invoke.invokeInEveryVM(new SerializableRunnable() { public void run() { closeCache(); } }); } @Test public void testUpdateVersionAfterCreateWithSerialSender() { Host host = Host.getHost(0); VM vm0 = host.getVM(0); // server1 site1 VM vm1 = host.getVM(1); // server2 site1 VM vm2 = host.getVM(2); // server1 site2 VM vm3 = host.getVM(3); // server2 site2 final String key = "key-1"; // Site 1 Integer lnPort = (Integer) vm0.invoke(() -> UpdateVersionDUnitTest.createFirstLocatorWithDSId(1)); vm0.invoke(() -> UpdateVersionDUnitTest.createCache(lnPort)); vm0.invoke(() -> UpdateVersionDUnitTest.createSender("ln1", 2, false, 10, 1, false, false, null, true)); vm0.invoke(() -> UpdateVersionDUnitTest.createPartitionedRegion(regionName, "ln1", 1, 1)); vm0.invoke(() -> UpdateVersionDUnitTest.startSender("ln1")); vm0.invoke(() -> UpdateVersionDUnitTest.waitForSenderRunningState("ln1")); // Site 2 Integer nyPort = (Integer) vm2.invoke(() -> UpdateVersionDUnitTest.createFirstRemoteLocator(2, lnPort)); Integer nyRecPort = (Integer) vm2.invoke(() -> UpdateVersionDUnitTest.createReceiver(nyPort)); vm2.invoke(() -> UpdateVersionDUnitTest.createPartitionedRegion(regionName, "", 1, 1)); vm3.invoke(() -> UpdateVersionDUnitTest.createCache(nyPort)); vm3.invoke(() -> UpdateVersionDUnitTest.createPartitionedRegion(regionName, "", 1, 1)); final VersionTag tag = (VersionTag) vm0 .invoke(new SerializableCallable("Update a single entry and get its version") { @Override public Object call() throws CacheException { Cache cache = CacheFactory.getAnyInstance(); Region region = cache.getRegion(regionName); assertTrue(region instanceof PartitionedRegion); region.put(key, "value-1"); region.put(key, "value-2"); Entry entry = region.getEntry(key); assertTrue(entry instanceof EntrySnapshot); RegionEntry regionEntry = ((EntrySnapshot) entry).getRegionEntry(); VersionStamp stamp = regionEntry.getVersionStamp(); // Create a duplicate entry version tag from stamp with newer // time-stamp. VersionSource memberId = (VersionSource) cache.getDistributedSystem().getDistributedMember(); VersionTag tag = VersionTag.create(memberId); int entryVersion = stamp.getEntryVersion() - 1; int dsid = stamp.getDistributedSystemId(); long time = System.currentTimeMillis(); tag.setEntryVersion(entryVersion); tag.setDistributedSystemId(dsid); tag.setVersionTimeStamp(time); tag.setIsRemoteForTesting(); EntryEventImpl event = createNewEvent((PartitionedRegion) region, tag, entry.getKey(), "value-3"); ((LocalRegion) region).basicUpdate(event, false, true, 0L, false); // Verify the new stamp entry = region.getEntry(key); assertTrue(entry instanceof EntrySnapshot); regionEntry = ((EntrySnapshot) entry).getRegionEntry(); stamp = regionEntry.getVersionStamp(); assertEquals( "Time stamp did NOT get updated by UPDATE_VERSION operation on LocalRegion", time, stamp.getVersionTimeStamp()); assertEquals(++entryVersion, stamp.getEntryVersion()); assertEquals(dsid, stamp.getDistributedSystemId()); return stamp.asVersionTag(); } }); VersionTag remoteTag = (VersionTag) vm3.invoke(new SerializableCallable("Get timestamp from remote site") { @Override public Object call() throws Exception { Cache cache = CacheFactory.getAnyInstance(); final PartitionedRegion region = (PartitionedRegion) cache.getRegion(regionName); // wait for entry to be received WaitCriterion wc = new WaitCriterion() { public boolean done() { Entry<?, ?> entry = null; try { entry = region.getDataStore().getEntryLocally(0, key, false, false); } catch (EntryNotFoundException e) { // expected } catch (ForceReattemptException e) { // expected } catch (PRLocallyDestroyedException e) { throw new RuntimeException("unexpected exception", e); } if (entry != null) { LogWriterUtils.getLogWriter().info("found entry " + entry); } return (entry != null); } public String description() { return "Expected " + key + " to be received on remote WAN site"; } }; Wait.waitForCriterion(wc, 30000, 500, true); wc = new WaitCriterion() { public boolean done() { Entry entry = region.getEntry(key); assertTrue(entry instanceof EntrySnapshot); RegionEntry regionEntry = ((EntrySnapshot) entry).getRegionEntry(); return regionEntry.getVersionStamp().getVersionTimeStamp() == tag .getVersionTimeStamp(); } public String description() { return "waiting for timestamp to be updated"; } }; Wait.waitForCriterion(wc, 30000, 500, true); Entry entry = region.getEntry(key); assertTrue("entry class is wrong: " + entry, entry instanceof EntrySnapshot); RegionEntry regionEntry = ((EntrySnapshot) entry).getRegionEntry(); VersionStamp stamp = regionEntry.getVersionStamp(); return stamp.asVersionTag(); } }); assertEquals("Local and remote site have different timestamps", tag.getVersionTimeStamp(), remoteTag.getVersionTimeStamp()); } @Test public void testUpdateVersionAfterCreateWithSerialSenderOnDR() { Host host = Host.getHost(0); VM vm0 = host.getVM(0); // server1 site1 VM vm1 = host.getVM(1); // server2 site1 VM vm2 = host.getVM(2); // server1 site2 VM vm3 = host.getVM(3); // server2 site2 final String key = "key-1"; // Site 1 Integer lnPort = (Integer) vm0.invoke(() -> UpdateVersionDUnitTest.createFirstLocatorWithDSId(1)); vm0.invoke(() -> UpdateVersionDUnitTest.createCache(lnPort)); vm0.invoke(() -> UpdateVersionDUnitTest.createSender("ln1", 2, false, 10, 1, false, false, null, true)); vm0.invoke(() -> UpdateVersionDUnitTest.createReplicatedRegion(regionName, "ln1")); vm0.invoke(() -> UpdateVersionDUnitTest.startSender("ln1")); vm0.invoke(() -> UpdateVersionDUnitTest.waitForSenderRunningState("ln1")); // Site 2 Integer nyPort = (Integer) vm2.invoke(() -> UpdateVersionDUnitTest.createFirstRemoteLocator(2, lnPort)); Integer nyRecPort = (Integer) vm2.invoke(() -> UpdateVersionDUnitTest.createReceiver(nyPort)); vm2.invoke(() -> UpdateVersionDUnitTest.createReplicatedRegion(regionName, "")); vm3.invoke(() -> UpdateVersionDUnitTest.createCache(nyPort)); vm3.invoke(() -> UpdateVersionDUnitTest.createReplicatedRegion(regionName, "")); final VersionTag tag = (VersionTag) vm0 .invoke(new SerializableCallable("Update a single entry and get its version") { @Override public Object call() throws CacheException { Cache cache = CacheFactory.getAnyInstance(); Region region = cache.getRegion(regionName); assertTrue(region instanceof DistributedRegion); region.put(key, "value-1"); region.put(key, "value-2"); Entry entry = region.getEntry(key); assertTrue(entry instanceof NonTXEntry); RegionEntry regionEntry = ((NonTXEntry) entry).getRegionEntry(); VersionStamp stamp = regionEntry.getVersionStamp(); // Create a duplicate entry version tag from stamp with newer // time-stamp. VersionSource memberId = (VersionSource) cache.getDistributedSystem().getDistributedMember(); VersionTag tag = VersionTag.create(memberId); int entryVersion = stamp.getEntryVersion() - 1; int dsid = stamp.getDistributedSystemId(); long time = System.currentTimeMillis(); tag.setEntryVersion(entryVersion); tag.setDistributedSystemId(dsid); tag.setVersionTimeStamp(time); tag.setIsRemoteForTesting(); EntryEventImpl event = createNewEvent((DistributedRegion) region, tag, entry.getKey(), "value-3"); ((LocalRegion) region).basicUpdate(event, false, true, 0L, false); // Verify the new stamp entry = region.getEntry(key); assertTrue(entry instanceof NonTXEntry); regionEntry = ((NonTXEntry) entry).getRegionEntry(); stamp = regionEntry.getVersionStamp(); assertEquals( "Time stamp did NOT get updated by UPDATE_VERSION operation on LocalRegion", time, stamp.getVersionTimeStamp()); assertEquals(entryVersion + 1, stamp.getEntryVersion()); assertEquals(dsid, stamp.getDistributedSystemId()); return stamp.asVersionTag(); } }); VersionTag remoteTag = (VersionTag) vm3.invoke(new SerializableCallable("Get timestamp from remote site") { @Override public Object call() throws Exception { Cache cache = CacheFactory.getAnyInstance(); final Region region = cache.getRegion(regionName); // wait for entry to be received WaitCriterion wc = new WaitCriterion() { public boolean done() { return (region.getEntry(key) != null); } public String description() { return "Expected key-1 to be received on remote WAN site"; } }; Wait.waitForCriterion(wc, 30000, 500, true); wc = new WaitCriterion() { public boolean done() { Entry entry = region.getEntry(key); assertTrue(entry instanceof NonTXEntry); RegionEntry regionEntry = ((NonTXEntry) entry).getRegionEntry(); return regionEntry.getVersionStamp().getVersionTimeStamp() == tag .getVersionTimeStamp(); } public String description() { return "waiting for timestamp to be updated"; } }; Wait.waitForCriterion(wc, 30000, 500, true); Entry entry = region.getEntry(key); assertTrue(entry instanceof NonTXEntry); RegionEntry regionEntry = ((NonTXEntry) entry).getRegionEntry(); VersionStamp stamp = regionEntry.getVersionStamp(); return stamp.asVersionTag(); } }); assertEquals("Local and remote site have different timestamps", tag.getVersionTimeStamp(), remoteTag.getVersionTimeStamp()); } @Test public void testUpdateVersionAfterCreateWithParallelSender() { Host host = Host.getHost(0); VM vm0 = host.getVM(0); // server1 site1 VM vm1 = host.getVM(1); // server2 site1 VM vm2 = host.getVM(2); // server1 site2 VM vm3 = host.getVM(3); // server2 site2 // Site 1 Integer lnPort = (Integer) vm0.invoke(() -> UpdateVersionDUnitTest.createFirstLocatorWithDSId(1)); final String key = "key-1"; vm0.invoke(() -> UpdateVersionDUnitTest.createCache(lnPort)); vm0.invoke( () -> UpdateVersionDUnitTest.createSender("ln1", 2, true, 10, 1, false, false, null, true)); vm0.invoke(() -> UpdateVersionDUnitTest.createPartitionedRegion(regionName, "ln1", 1, 1)); vm0.invoke(() -> UpdateVersionDUnitTest.startSender("ln1")); vm0.invoke(() -> UpdateVersionDUnitTest.waitForSenderRunningState("ln1")); // Site 2 Integer nyPort = (Integer) vm2.invoke(() -> UpdateVersionDUnitTest.createFirstRemoteLocator(2, lnPort)); Integer nyRecPort = (Integer) vm2.invoke(() -> UpdateVersionDUnitTest.createReceiver(nyPort)); vm2.invoke(() -> UpdateVersionDUnitTest.createPartitionedRegion(regionName, "", 1, 1)); vm3.invoke(() -> UpdateVersionDUnitTest.createCache(nyPort)); vm3.invoke(() -> UpdateVersionDUnitTest.createPartitionedRegion(regionName, "", 1, 1)); final VersionTag tag = (VersionTag) vm0.invoke(new SerializableCallable("Put a single entry and get its version") { @Override public Object call() throws CacheException { Cache cache = CacheFactory.getAnyInstance(); Region region = cache.getRegion(regionName); assertTrue(region instanceof PartitionedRegion); region.put(key, "value-1"); region.put(key, "value-2"); Entry entry = region.getEntry(key); assertTrue(entry instanceof EntrySnapshot); RegionEntry regionEntry = ((EntrySnapshot) entry).getRegionEntry(); VersionStamp stamp = regionEntry.getVersionStamp(); // Create a duplicate entry version tag from stamp with newer // time-stamp. VersionSource memberId = (VersionSource) cache.getDistributedSystem().getDistributedMember(); VersionTag tag = VersionTag.create(memberId); int entryVersion = stamp.getEntryVersion() - 1; int dsid = stamp.getDistributedSystemId(); long time = System.currentTimeMillis(); tag.setEntryVersion(entryVersion); tag.setDistributedSystemId(dsid); tag.setVersionTimeStamp(time); tag.setIsRemoteForTesting(); EntryEventImpl event = createNewEvent((PartitionedRegion) region, tag, entry.getKey(), "value-3"); ((LocalRegion) region).basicUpdate(event, false, true, 0L, false); // Verify the new stamp entry = region.getEntry(key); assertTrue(entry instanceof EntrySnapshot); regionEntry = ((EntrySnapshot) entry).getRegionEntry(); stamp = regionEntry.getVersionStamp(); assertEquals( "Time stamp did NOT get updated by UPDATE_VERSION operation on LocalRegion", time, stamp.getVersionTimeStamp()); assertEquals(++entryVersion, stamp.getEntryVersion()); assertEquals(dsid, stamp.getDistributedSystemId()); return stamp.asVersionTag(); } }); VersionTag remoteTag = (VersionTag) vm3.invoke(new SerializableCallable("Get timestamp from remote site") { @Override public Object call() throws Exception { Cache cache = CacheFactory.getAnyInstance(); final PartitionedRegion region = (PartitionedRegion) cache.getRegion(regionName); // wait for entry to be received WaitCriterion wc = new WaitCriterion() { public boolean done() { Entry<?, ?> entry = null; try { entry = region.getDataStore().getEntryLocally(0, key, false, false); } catch (EntryNotFoundException e) { // expected } catch (ForceReattemptException e) { // expected } catch (PRLocallyDestroyedException e) { throw new RuntimeException("unexpected exception", e); } if (entry != null) { LogWriterUtils.getLogWriter().info("found entry " + entry); } return (entry != null); } public String description() { return "Expected key-1 to be received on remote WAN site"; } }; Wait.waitForCriterion(wc, 30000, 500, true); wc = new WaitCriterion() { public boolean done() { Entry entry = region.getEntry(key); assertTrue(entry instanceof EntrySnapshot); RegionEntry regionEntry = ((EntrySnapshot) entry).getRegionEntry(); return regionEntry.getVersionStamp().getVersionTimeStamp() == tag .getVersionTimeStamp(); } public String description() { return "waiting for timestamp to be updated"; } }; Wait.waitForCriterion(wc, 30000, 500, true); Entry entry = region.getEntry(key); assertTrue(entry instanceof EntrySnapshot); RegionEntry regionEntry = ((EntrySnapshot) entry).getRegionEntry(); VersionStamp stamp = regionEntry.getVersionStamp(); return stamp.asVersionTag(); } }); assertEquals("Local and remote site have different timestamps", tag.getVersionTimeStamp(), remoteTag.getVersionTimeStamp()); } @Test public void testUpdateVersionAfterCreateWithConcurrentSerialSender() { Host host = Host.getHost(0); VM vm0 = host.getVM(0); // server1 site1 VM vm1 = host.getVM(1); // server2 site1 VM vm2 = host.getVM(2); // server1 site2 VM vm3 = host.getVM(3); // server2 site2 // Site 1 Integer lnPort = (Integer) vm0.invoke(() -> UpdateVersionDUnitTest.createFirstLocatorWithDSId(1)); final String key = "key-1"; vm0.invoke(() -> UpdateVersionDUnitTest.createCache(lnPort)); vm0.invoke(() -> UpdateVersionDUnitTest.createConcurrentSender("ln1", 2, false, 10, 2, false, false, null, true, 2)); vm0.invoke(() -> UpdateVersionDUnitTest.createPartitionedRegion(regionName, "ln1", 1, 1)); vm0.invoke(() -> UpdateVersionDUnitTest.startSender("ln1")); vm0.invoke(() -> UpdateVersionDUnitTest.waitForSenderRunningState("ln1")); // Site 2 Integer nyPort = (Integer) vm2.invoke(() -> UpdateVersionDUnitTest.createFirstRemoteLocator(2, lnPort)); Integer nyRecPort = (Integer) vm2.invoke(() -> UpdateVersionDUnitTest.createReceiver(nyPort)); vm2.invoke(() -> UpdateVersionDUnitTest.createPartitionedRegion(regionName, "", 1, 1)); vm3.invoke(() -> UpdateVersionDUnitTest.createCache(nyPort)); vm3.invoke(() -> UpdateVersionDUnitTest.createPartitionedRegion(regionName, "", 1, 1)); final VersionTag tag = (VersionTag) vm0.invoke(new SerializableCallable("Put a single entry and get its version") { @Override public Object call() throws CacheException { Cache cache = CacheFactory.getAnyInstance(); Region region = cache.getRegion(regionName); assertTrue(region instanceof PartitionedRegion); region.put(key, "value-1"); region.put(key, "value-2"); Entry entry = region.getEntry(key); assertTrue(entry instanceof EntrySnapshot); RegionEntry regionEntry = ((EntrySnapshot) entry).getRegionEntry(); VersionStamp stamp = regionEntry.getVersionStamp(); // Create a duplicate entry version tag from stamp with newer // time-stamp. VersionSource memberId = (VersionSource) cache.getDistributedSystem().getDistributedMember(); VersionTag tag = VersionTag.create(memberId); int entryVersion = stamp.getEntryVersion() - 1; int dsid = stamp.getDistributedSystemId(); long time = System.currentTimeMillis(); tag.setEntryVersion(entryVersion); tag.setDistributedSystemId(dsid); tag.setVersionTimeStamp(time); tag.setIsRemoteForTesting(); EntryEventImpl event = createNewEvent((PartitionedRegion) region, tag, entry.getKey(), "value-3"); ((LocalRegion) region).basicUpdate(event, false, true, 0L, false); // Verify the new stamp entry = region.getEntry(key); assertTrue(entry instanceof EntrySnapshot); regionEntry = ((EntrySnapshot) entry).getRegionEntry(); stamp = regionEntry.getVersionStamp(); assertEquals( "Time stamp did NOT get updated by UPDATE_VERSION operation on LocalRegion", time, stamp.getVersionTimeStamp()); assertEquals(++entryVersion, stamp.getEntryVersion()); assertEquals(dsid, stamp.getDistributedSystemId()); return stamp.asVersionTag(); } }); VersionTag remoteTag = (VersionTag) vm3.invoke(new SerializableCallable("Get timestamp from remote site") { @Override public Object call() throws Exception { Cache cache = CacheFactory.getAnyInstance(); final PartitionedRegion region = (PartitionedRegion) cache.getRegion(regionName); // wait for entry to be received WaitCriterion wc = new WaitCriterion() { public boolean done() { Entry<?, ?> entry = null; try { entry = region.getDataStore().getEntryLocally(0, key, false, false); } catch (EntryNotFoundException e) { // expected } catch (ForceReattemptException e) { // expected } catch (PRLocallyDestroyedException e) { throw new RuntimeException("unexpected exception", e); } if (entry != null) { LogWriterUtils.getLogWriter().info("found entry " + entry); } return (entry != null); } public String description() { return "Expected key-1 to be received on remote WAN site"; } }; Wait.waitForCriterion(wc, 30000, 500, true); wc = new WaitCriterion() { public boolean done() { Entry entry = region.getEntry(key); assertTrue(entry instanceof EntrySnapshot); RegionEntry regionEntry = ((EntrySnapshot) entry).getRegionEntry(); return regionEntry.getVersionStamp().getVersionTimeStamp() == tag .getVersionTimeStamp(); } public String description() { return "waiting for timestamp to be updated"; } }; Wait.waitForCriterion(wc, 30000, 500, true); Entry entry = region.getEntry(key); assertTrue(entry instanceof EntrySnapshot); RegionEntry regionEntry = ((EntrySnapshot) entry).getRegionEntry(); VersionStamp stamp = regionEntry.getVersionStamp(); return stamp.asVersionTag(); } }); assertEquals("Local and remote site have different timestamps", tag.getVersionTimeStamp(), remoteTag.getVersionTimeStamp()); } private VersionTagHolder createNewEvent(LocalRegion region, VersionTag tag, Object key, Object value) { VersionTagHolder updateEvent = new VersionTagHolder(tag); updateEvent.setOperation(Operation.UPDATE); updateEvent.setRegion(region); if (region instanceof PartitionedRegion) { updateEvent.setKeyInfo(((PartitionedRegion) region).getKeyInfo(key)); } else { updateEvent.setKeyInfo(new KeyInfo(key, value, null)); } updateEvent.setNewValue(value); updateEvent.setGenerateCallbacks(true); updateEvent.distributedMember = region.getSystem().getDistributedMember(); updateEvent.setNewEventId(region.getSystem()); return updateEvent; } /* * Helper Methods */ private static void createCache(Integer locPort) { UpdateVersionDUnitTest test = new UpdateVersionDUnitTest(); Properties props = test.getDistributedSystemProperties(); props.setProperty(MCAST_PORT, "0"); props.setProperty(LOCATORS, "localhost[" + locPort + "]"); props.setProperty(LOG_LEVEL, LogWriterUtils.getDUnitLogLevel()); props.setProperty(ENABLE_CLUSTER_CONFIGURATION, "false"); props.setProperty(USE_CLUSTER_CONFIGURATION, "false"); InternalDistributedSystem ds = test.getSystem(props); cache = CacheFactory.create(ds); IgnoredException ex = new IgnoredException("could not get remote locator information for remote site"); cache.getLogger().info(ex.getAddMessage()); expectedExceptions.add(ex); ex = new IgnoredException("Pool ln1 is not available"); cache.getLogger().info(ex.getAddMessage()); expectedExceptions.add(ex); } private static void closeCache() { if (cache != null && !cache.isClosed()) { for (IgnoredException expectedException : expectedExceptions) { cache.getLogger().info(expectedException.getRemoveMessage()); } expectedExceptions.clear(); cache.getDistributedSystem().disconnect(); cache.close(); } cache = null; } public static void createSender(String dsName, int remoteDsId, boolean isParallel, Integer maxMemory, Integer batchSize, boolean isConflation, boolean isPersistent, GatewayEventFilter filter, boolean isManualStart) { File persistentDirectory = new File(dsName + "_disk_" + System.currentTimeMillis() + "_" + VM.getCurrentVMNum()); persistentDirectory.mkdir(); DiskStoreFactory dsf = cache.createDiskStoreFactory(); File[] dirs1 = new File[] {persistentDirectory}; if (isParallel) { GatewaySenderFactory gateway = cache.createGatewaySenderFactory(); gateway.setParallel(true); gateway.setMaximumQueueMemory(maxMemory); gateway.setBatchSize(batchSize); gateway.setManualStart(isManualStart); ((InternalGatewaySenderFactory) gateway).setLocatorDiscoveryCallback(new MyLocatorCallback()); if (filter != null) { gateway.addGatewayEventFilter(filter); } if (isPersistent) { gateway.setPersistenceEnabled(true); gateway.setDiskStoreName(dsf.setDiskDirs(dirs1).create(dsName).getName()); } else { DiskStore store = dsf.setDiskDirs(dirs1).create(dsName); gateway.setDiskStoreName(store.getName()); } gateway.setBatchConflationEnabled(isConflation); gateway.create(dsName, remoteDsId); } else { GatewaySenderFactory gateway = cache.createGatewaySenderFactory(); gateway.setMaximumQueueMemory(maxMemory); gateway.setBatchSize(batchSize); gateway.setManualStart(isManualStart); ((InternalGatewaySenderFactory) gateway).setLocatorDiscoveryCallback(new MyLocatorCallback()); if (filter != null) { gateway.addGatewayEventFilter(filter); } gateway.setBatchConflationEnabled(isConflation); if (isPersistent) { gateway.setPersistenceEnabled(true); gateway.setDiskStoreName(dsf.setDiskDirs(dirs1).create(dsName).getName()); } else { DiskStore store = dsf.setDiskDirs(dirs1).create(dsName); gateway.setDiskStoreName(store.getName()); } gateway.create(dsName, remoteDsId); } } public static void createPartitionedRegion(String regionName, String senderIds, Integer redundantCopies, Integer totalNumBuckets) { AttributesFactory fact = new AttributesFactory(); if (senderIds != null) { StringTokenizer tokenizer = new StringTokenizer(senderIds, ","); while (tokenizer.hasMoreTokens()) { String senderId = tokenizer.nextToken(); fact.addGatewaySenderId(senderId); } } PartitionAttributesFactory pFact = new PartitionAttributesFactory(); pFact.setTotalNumBuckets(totalNumBuckets); pFact.setRedundantCopies(redundantCopies); pFact.setRecoveryDelay(0); fact.setPartitionAttributes(pFact.create()); Region r = cache.createRegionFactory(fact.create()).create(regionName); assertNotNull(r); } public static void createReplicatedRegion(String regionName, String senderIds) { AttributesFactory fact = new AttributesFactory(); if (senderIds != null) { StringTokenizer tokenizer = new StringTokenizer(senderIds, ","); while (tokenizer.hasMoreTokens()) { String senderId = tokenizer.nextToken(); fact.addGatewaySenderId(senderId); } } fact.setDataPolicy(DataPolicy.REPLICATE); fact.setScope(Scope.DISTRIBUTED_ACK); Region r = cache.createRegionFactory(fact.create()).create(regionName); assertNotNull(r); } public static void waitForSenderRunningState(String senderId) { Set<GatewaySender> senders = cache.getGatewaySenders(); final GatewaySender sender = getGatewaySenderById(senders, senderId); WaitCriterion wc = new WaitCriterion() { public boolean done() { if (sender != null && sender.isRunning()) { return true; } return false; } public String description() { return "Expected sender isRunning state to be true but is false"; } }; Wait.waitForCriterion(wc, 300000, 500, true); } public static Integer createFirstRemoteLocator(int dsId, int remoteLocPort) { UpdateVersionDUnitTest test = new UpdateVersionDUnitTest(); int port = AvailablePortHelper.getRandomAvailablePortForDUnitSite(); Properties props = test.getDistributedSystemProperties(); props.setProperty(MCAST_PORT, "0"); props.setProperty(DISTRIBUTED_SYSTEM_ID, "" + dsId); props.setProperty(LOCATORS, "localhost[" + port + "]"); props.setProperty(START_LOCATOR, "localhost[" + port + "],server=true,peer=true,hostname-for-clients=localhost"); props.setProperty(REMOTE_LOCATORS, "localhost[" + remoteLocPort + "]"); props.setProperty(USE_CLUSTER_CONFIGURATION, "false"); props.setProperty(ENABLE_CLUSTER_CONFIGURATION, "false"); test.getSystem(props); return port; } public static void createConcurrentSender(String dsName, int remoteDsId, boolean isParallel, Integer maxMemory, Integer batchSize, boolean isConflation, boolean isPersistent, GatewayEventFilter filter, boolean isManualStart, int concurrencyLevel) { File persistentDirectory = new File(dsName + "_disk_" + System.currentTimeMillis() + "_" + VM.getCurrentVMNum()); persistentDirectory.mkdir(); DiskStoreFactory dsf = cache.createDiskStoreFactory(); File[] dirs1 = new File[] {persistentDirectory}; if (isParallel) { GatewaySenderFactory gateway = cache.createGatewaySenderFactory(); gateway.setParallel(true); gateway.setMaximumQueueMemory(maxMemory); gateway.setBatchSize(batchSize); gateway.setManualStart(isManualStart); ((InternalGatewaySenderFactory) gateway).setLocatorDiscoveryCallback(new MyLocatorCallback()); if (filter != null) { gateway.addGatewayEventFilter(filter); } if (isPersistent) { gateway.setPersistenceEnabled(true); gateway.setDiskStoreName(dsf.setDiskDirs(dirs1).create(dsName).getName()); } else { DiskStore store = dsf.setDiskDirs(dirs1).create(dsName); gateway.setDiskStoreName(store.getName()); } gateway.setBatchConflationEnabled(isConflation); gateway.create(dsName, remoteDsId); } else { GatewaySenderFactory gateway = cache.createGatewaySenderFactory(); gateway.setMaximumQueueMemory(maxMemory); gateway.setBatchSize(batchSize); gateway.setManualStart(isManualStart); ((InternalGatewaySenderFactory) gateway).setLocatorDiscoveryCallback(new MyLocatorCallback()); if (filter != null) { gateway.addGatewayEventFilter(filter); } gateway.setBatchConflationEnabled(isConflation); if (isPersistent) { gateway.setPersistenceEnabled(true); gateway.setDiskStoreName(dsf.setDiskDirs(dirs1).create(dsName).getName()); } else { DiskStore store = dsf.setDiskDirs(dirs1).create(dsName); gateway.setDiskStoreName(store.getName()); } gateway.setDispatcherThreads(concurrencyLevel); gateway.create(dsName, remoteDsId); } } public static int createReceiver(int locPort) { UpdateVersionDUnitTest test = new UpdateVersionDUnitTest(); Properties props = test.getDistributedSystemProperties(); props.setProperty(MCAST_PORT, "0"); props.setProperty(LOCATORS, "localhost[" + locPort + "]"); InternalDistributedSystem ds = test.getSystem(props); cache = CacheFactory.create(ds); GatewayReceiverFactory fact = cache.createGatewayReceiverFactory(); int port = AvailablePortHelper.getRandomAvailablePortForDUnitSite(); fact.setStartPort(port); fact.setEndPort(port); GatewayReceiver receiver = fact.create(); try { receiver.start(); } catch (IOException e) { e.printStackTrace(); fail("Test " + test.getName() + " failed to start GatewayReceiver on port " + port); } return port; } public static void startSender(String senderId) { Set<GatewaySender> senders = cache.getGatewaySenders(); GatewaySender sender = null; for (GatewaySender s : senders) { if (s.getId().equals(senderId)) { sender = s; break; } } sender.start(); } protected static class MyLocatorCallback extends LocatorDiscoveryCallbackAdapter { private final Set discoveredLocators = new HashSet(); private final Set removedLocators = new HashSet(); @Override public synchronized void locatorsDiscovered(List locators) { discoveredLocators.addAll(locators); notifyAll(); } @Override public synchronized void locatorsRemoved(List locators) { removedLocators.addAll(locators); notifyAll(); } public boolean waitForDiscovery(InetSocketAddress locator, long time) throws InterruptedException { return waitFor(discoveredLocators, locator, time); } public boolean waitForRemove(InetSocketAddress locator, long time) throws InterruptedException { return waitFor(removedLocators, locator, time); } private synchronized boolean waitFor(Set set, InetSocketAddress locator, long time) throws InterruptedException { long remaining = time; long endTime = System.currentTimeMillis() + time; while (!set.contains(locator) && remaining >= 0) { wait(remaining); remaining = endTime - System.currentTimeMillis(); } return set.contains(locator); } public synchronized Set getDiscovered() { return new HashSet(discoveredLocators); } public synchronized Set getRemoved() { return new HashSet(removedLocators); } } private static GatewaySender getGatewaySenderById(Set<GatewaySender> senders, String senderId) { for (GatewaySender s : senders) { if (s.getId().equals(senderId)) { return s; } } // if none of the senders matches with the supplied senderId, return null return null; } public static Integer createFirstLocatorWithDSId(int dsId) { UpdateVersionDUnitTest test = new UpdateVersionDUnitTest(); int port = AvailablePortHelper.getRandomAvailablePortForDUnitSite(); Properties props = test.getDistributedSystemProperties(); props.setProperty(MCAST_PORT, "0"); props.setProperty(DISTRIBUTED_SYSTEM_ID, "" + dsId); props.setProperty(LOCATORS, "localhost[" + port + "]"); props.setProperty(ENABLE_CLUSTER_CONFIGURATION, "false"); props.setProperty(USE_CLUSTER_CONFIGURATION, "false"); props.setProperty(START_LOCATOR, "localhost[" + port + "],server=true,peer=true,hostname-for-clients=localhost"); test.getSystem(props); return port; } }