/* * 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.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.Properties; import java.util.Set; import org.junit.Ignore; 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.CacheExistsException; import org.apache.geode.cache.CacheFactory; import org.apache.geode.cache.MirrorType; import org.apache.geode.cache.PartitionAttributes; import org.apache.geode.cache.PartitionAttributesFactory; import org.apache.geode.cache.PartitionedRegionStorageException; import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionAttributes; import org.apache.geode.cache.Scope; import org.apache.geode.cache30.CacheSerializableRunnable; import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.InternalDistributedSystem; import org.apache.geode.internal.cache.PartitionedRegionDataStore.BucketVisitor; import org.apache.geode.test.dunit.Assert; import org.apache.geode.test.dunit.AsyncInvocation; import org.apache.geode.test.dunit.Host; import org.apache.geode.test.dunit.Invoke; import org.apache.geode.test.dunit.LogWriterUtils; import org.apache.geode.test.dunit.SerializableRunnable; import org.apache.geode.test.dunit.ThreadUtils; import org.apache.geode.test.dunit.VM; import org.apache.geode.test.junit.categories.DistributedTest; /** * This class tests bucket Creation and distribution for the multiple Partition regions. */ @Category(DistributedTest.class) public class PartitionedRegionBucketCreationDistributionDUnitTest extends PartitionedRegionDUnitTestCase { /** Prefix is used in name of Partition Region */ protected static String prPrefix = null; /** Maximum number of regions * */ static final int MAX_REGIONS = 2; /** redundancy used for the creation of the partition region */ final int redundancy = 0; /** local maxmemory used for the creation of the partition region */ int localMaxMemory = 200; /** max number of buckets */ int totalBucketNumProperty = 11; /** to store references of 4 vms */ VM vm[] = new VM[4]; /** * This test performs following operations <br> * 1. Validate bucket2Node region of the partition regions.</br> * <br> * (a) bucket2Node Region should not be null.</br> * <br> * (b) Scope of the bucket2Node region should be DISTRIBUTED_ACK.</br> * <br> * (c) Size of bucket2Node region should be 0 before any put() operation. </br> * <br> * (d) Parent region of the bucket2Node region should be root i.e. region with name "PRRoot".</br> * <br> * 2. Do put() operation from the different VMs so that buckets gets generated.</br> * <br> * 3. Validate bucket regions of multiple partition Regions</br> * <br> * (a) Size of bucket2Node region should be > 0.</br> * <br> * (b) In case of the partition regions with redundancy > 0 scope of the bucket regions should be * scope of the partition regions.</br> * <br> * (c) In case of the partition regions with redundancy > 0 no two bucket regions with same * bucketId should not be present on the same node.</br> */ @Test public void testBucketCreationInMultiplePartitionRegion() throws Throwable { Host host = Host.getHost(0); /** creating 4 VMs */ createVMs(host); /** Prefix will be used for naming the partititon Region */ prPrefix = getUniqueName(); /** these indices represents range of partition regions present in each VM */ int startIndexForRegion = 0; int endIndexForRegion = MAX_REGIONS; /** Start index for key */ int startIndexForKey = 0; /** End index for key */ int endIndexForKey = 50; // creating partition regions createMultiplePR(startIndexForRegion, endIndexForRegion); // validating bucket2Node of multiple partition regions before doing any // put(). validateBucket2NodeBeforePutInMultiplePartitionedRegion(startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter().info( "testBucketCerationInMultiPlePartitionRegion() - Bucket2Node region of partition regions before any put() successfully validated "); // doing put() operation on multiple partition region putInMultiplePartitionedRegion(startIndexForRegion, endIndexForRegion, startIndexForKey, endIndexForKey); LogWriterUtils.getLogWriter().info( "testBucketCerationInMultiPlePartitionRegion() - Put() operation successfully in partition regions"); // validating bucket regions of multiple partition regions. validateBucketsAfterPutInMultiplePartitionRegion(startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter().info( "testBucketCerationInMultiPlePartitionRegion() - Bucket regions of partition regions successfully validated"); LogWriterUtils.getLogWriter() .info("testBucketCerationInMultiPlePartitionRegion() Successfully completed"); } /** * This test performs following operations <br> * 1.Creates multiple partition regions in 4 vms</br> * <br> * 2. Performs Put() operation from vm0 for the keys 0 to 111.</br> * <br> * 3. Validates bucket distribution over all the nodes for multiple partition regions.</br> */ @Test public void testBucketCreationInPRPutFromOneNode() throws Throwable { Host host = Host.getHost(0); /** creating 4 VMs */ createVMs(host); /** Prefix will be used for naming the partititon Region */ prPrefix = "testBucketCreationInPRFromOneNode"; /** these indices represents range of partition regions present in each VM */ final int startIndexForRegion = 0; final int endIndexForRegion = MAX_REGIONS; /** Start index for key */ final long startIndexForKey = 0; /** End index for key */ final long endIndexForKey = totalBucketNumProperty; final int startIndexForNode = 0; final int endIndexForNode = 4; List vmList; // creating multiple partition regions on 3 nodes localMaxMemory=200 redundancy = 0 // int midIndexForRegion = (endIndexForRegion - startIndexForRegion) / 2; vmList = addNodeToList(startIndexForNode, endIndexForNode); localMaxMemory = 200; // redundancy = 0; createPartitionRegion(vmList, startIndexForRegion, endIndexForRegion, localMaxMemory, redundancy); LogWriterUtils.getLogWriter().info( "testBucketCerationInMultiPlePartitionRegion() - Partition Regions successfully created "); // doing put() operation from vm0 only putInMultiplePartitionRegionFromOneVm(vm[0], startIndexForRegion, endIndexForRegion, startIndexForKey, endIndexForKey); LogWriterUtils.getLogWriter().info( "testBucketCerationInMultiPlePartitionRegion() - Put() Opereration done only from one VM "); // validating bucket distribution ovar all the nodes int noBucketsExpectedOnEachNode = getNoBucketsExpectedOnEachNode(); validateBucketsDistributionInMultiplePartitionRegion(startIndexForRegion, endIndexForRegion, noBucketsExpectedOnEachNode); LogWriterUtils.getLogWriter().info( "testBucketCerationInMultiPlePartitionRegion() - Bucket regions are equally distributed"); LogWriterUtils.getLogWriter() .info("testBucketCerationInMultiPlePartitionRegion() successfully completed"); } /** * This test performs following operations <br> * 1. Creates multiple partition regions in 4 vms with scope DISTRIBUTED_ACK and * DISTRIBUTED_NO_ACK.</br> * <br> * 2. Performs Put() operation from all the vms for the keys 0 to 111.</br> * <br> * 3. Validates bucket distribution over all the nodes for multiple partition regions.</br> */ @Test public void testBucketCreationInMultiplePartitionRegionFromAllNodes() throws Throwable { Host host = Host.getHost(0); /** creating 4 VMs */ createVMs(host); /** Prefix will be used for naming the partititon Region */ prPrefix = "testBucketCreationInMultiplePartitionRegionFromAllNodes"; /** these indices represents range of partition regions present in each VM */ int startIndexForRegion = 0; int endIndexForRegion = MAX_REGIONS; /** Start index for key */ long startIndexForKey = 0; /** End index for key */ long endIndexForKey = totalBucketNumProperty; int startIndexForNode = 0; int endIndexForNode = 4; List vmList; // creating multiple partition regions on 3 nodes with scope = // DISTRIBUTED_ACK localMaxMemory=200 redundancy = 0 vmList = addNodeToList(startIndexForNode, endIndexForNode); localMaxMemory = 200; // redundancy = 0; // creating multiple partition regions on 3 nodes with localMaxMemory=200 redundancy = 0 createPartitionRegion(vmList, startIndexForRegion, endIndexForRegion, localMaxMemory, redundancy); LogWriterUtils.getLogWriter().info( "testBucketCerationInMultiPlePartitionRegion() - Partition Regions successfully created "); // doing put() operation from all vms putInMultiplePartitionedRegionFromAllVms(startIndexForRegion, endIndexForRegion, startIndexForKey, endIndexForKey); LogWriterUtils.getLogWriter().info( "testBucketCerationInMultiPlePartitionRegion() - Put() Opereration done only from one VM "); // validating bucket distribution ovar all the nodes int noBucketsExpectedOnEachNode = getNoBucketsExpectedOnEachNode() - 4; validateBucketsDistributionInMultiplePartitionRegion(startIndexForRegion, endIndexForRegion, noBucketsExpectedOnEachNode); LogWriterUtils.getLogWriter().info( "testBucketCerationInMultiPlePartitionRegion() - Bucket regions are equally distributed"); LogWriterUtils.getLogWriter() .info("testBucketCerationInMultiPlePartitionRegion() successfully created"); } /** * This test performs following operations <br> * 1. Creates multiple partition regions in 3 vms with scope DISTRIBUTED_ACK and * DISTRIBUTED_NO_ACK.</br> * <br> * 2. Performs Put() operation from 3 the vms for the keys startIndexForRgion to * enIndexForRegion.</br> * <br> * 3. Creates partition region on new node</br> * <br> * 4. Performs Put() operation from 3 the vms for the keys startIndexForRgion to * enIndexForRegion.</br> * <br> * 5. Validate bucket creation on new node.</br> */ @Test public void testBucketDistributionAfterNodeAdditionInPR() throws Throwable { Host host = Host.getHost(0); /** creating 4 VMs */ createVMs(host); /** Prefix will be used for naming the partititon Region */ prPrefix = "testBucketDistributionAfterNodeAdditionInPR"; /** these indices represents range of partition regions present in each VM */ int startIndexForRegion = 0; int endIndexForRegion = MAX_REGIONS; /** Start index for key */ int startIndexForKey = 0; /** End index for key */ int endIndexForKey = 5; int startIndexForNode = 0; int endIndexForNode = 4; // creating partition regions on 4 nodes out of which partition regions on // one node are only accessors. // partition regions on vm3 are only accessors. List vmList = new ArrayList(); // creating multiple partition regions on 3 nodes with scope = // DISTRIBUTED_ACK localMaxMemory=200 redundancy = 0 startIndexForNode = 0; endIndexForNode = 3; vmList = addNodeToList(startIndexForNode, endIndexForNode); localMaxMemory = 200; // redundancy = 0; createPartitionRegion(vmList, startIndexForRegion, endIndexForRegion, localMaxMemory, redundancy); startIndexForNode = 0; endIndexForNode = 3; vmList = addNodeToList(startIndexForNode, endIndexForNode); // doing put() in multiple partition regions from 3 nodes. putInMultiplePartitionedRegionFrom3Nodes(startIndexForRegion, endIndexForRegion, startIndexForKey, endIndexForKey); LogWriterUtils.getLogWriter().info( "testBucketDistributionAfterNodeAdditionInPR() - Put() operation successfully in partition regions on 3 Nodes"); // creating multiple partition regions on 3 nodes with localMaxMemory=200 redundancy = 0 startIndexForNode = 3; endIndexForNode = 4; vmList = addNodeToList(startIndexForNode, endIndexForNode); localMaxMemory = 200; // redundancy = 0; createPartitionRegion(vmList, startIndexForRegion, endIndexForKey, localMaxMemory, redundancy); startIndexForKey = 5; endIndexForKey = totalBucketNumProperty; // doing put() in multiple partition regions from 3 nodes. putInMultiplePartitionedRegionFrom3Nodes(startIndexForRegion, endIndexForRegion, startIndexForKey, endIndexForKey); LogWriterUtils.getLogWriter().info( "testBucketDistributionAfterNodeAdditionInPR() - Put() operation successfully in partition regions on 4th node"); // validating bucket creation in the 4th node validateBucketsOnAllNodes(startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter().info( "testBucketDistributionAfterNodeAdditionInPR() - buckets on all the nodes are validated"); LogWriterUtils.getLogWriter() .info("testBucketDistributionAfterNodeAdditionInPR() successfully created"); } /** * this is to test global property TOTAL_BUCKETS_NUM_PROPERTY. 1.create partition region with * scope = DISTRIBUTED_ACK redundancy = 3 on 4 vms 2.set global property * TOTAL_BUCKETS_NUM_PROPERTY = 11 3.perform put() operation for the keys in the range 0 to 100 * 4.test number of buckets created. It should be = 11 */ @Test public void testTotalNumBucketProperty() throws Throwable { Host host = Host.getHost(0); /** creating 4 VMs */ createVMs(host); /** Prefix will be used for naming the partititon Region */ prPrefix = "testTotalNumBucketProperty"; /** these indices represents range of partition regions present in each VM */ int startIndexForRegion = 0; int endIndexForRegion = 1; /** Start index for key */ int startIndexForKey = 0; /** End index for key */ int endIndexForKey = 20; int startIndexForNode = 0; int endIndexForNode = 4; List vmList = addNodeToList(startIndexForNode, endIndexForNode); localMaxMemory = 200; final int localRedundancy = 1; createPRWithTotalNumPropSetList(vmList, startIndexForRegion, endIndexForRegion, localMaxMemory, localRedundancy); putInMultiplePartitionRegionFromOneVm(vm[0], startIndexForRegion, endIndexForRegion, startIndexForKey, endIndexForKey); int expectedNumBuckets = 11; validateTotalNumBuckets(prPrefix, vmList, startIndexForRegion, endIndexForRegion, expectedNumBuckets); startIndexForKey = 200; endIndexForKey = 400; putInMultiplePartitionedRegionFromAllVms(startIndexForRegion, endIndexForRegion, startIndexForKey, endIndexForKey); validateTotalNumBuckets(prPrefix, vmList, startIndexForRegion, endIndexForRegion, expectedNumBuckets); LogWriterUtils.getLogWriter().info("testTotalNumBucketProperty() completed successfully"); } /** * This is to test LOCAL_MAX_MEMORY property 1. create partitione region with scope = * DISTRIBUTED_ACK localMaxMemory = 1MB and redundancy = 0 on all vms 2. do put() operations so * that size of the objects that were put > localMaxMemory of partition region */ @Ignore("TODO") @Test public void testLocalMaxMemoryInPartitionedRegion() throws Throwable { Host host = Host.getHost(0); /** creating 4 VMs */ createVMs(host); /** Prefix will be used for naming the partititon Region */ prPrefix = getUniqueName(); /** these indices represents range of partition regions present in each VM */ int startIndexForRegion = 0; int endIndexForRegion = 1; /** Start index for key */ // int startIndexForKey = 0; /** End index for key */ // int endIndexForKey = 4000000; int startIndexForNode = 0; int endIndexForNode = 4; List vmList = addNodeToList(startIndexForNode, endIndexForNode); localMaxMemory = 1; // redundancy = 0; createPartitionRegion(vmList, startIndexForRegion, endIndexForRegion, localMaxMemory, redundancy); // doing put() operation on multiple partition region putForLocalMaxMemoryInMultiplePR(prPrefix + 0); } /** * Ensure that all buckets can be allocated for a PR with different levels of redundancy. This is * important given that bucket creation may fail due to VMs that refuse bucket allocation. VMs may * refuse for different reasons, in this case VMs may refuse because they are above their maximum. */ @Test public void testCompleteBucketAllocation() throws Exception { final String regionName = getUniqueName(); final int maxBuckets = 23; Host host = Host.getHost(0); createVMs(host); Invoke.invokeInEveryVM(new SerializableRunnable("Create PR") { public void run() { getCache().createRegion(regionName, createRegionAttrs(0, 10, maxBuckets)); } }); this.vm[0].invoke(new SerializableRunnable("Create keys") { public void run() { Cache c = getCache(); PartitionedRegion r = (PartitionedRegion) c.getRegion(regionName); int i = 0; // Create all the buckets for (;;) { r.put(new Integer(i), "v-" + Integer.toString(i)); i++; if (((i % 10) == 0) && r.getRegionAdvisor().getBucketSet().size() >= maxBuckets) { break; } } } }); // final int bucketPerHost = (int) Math.ceil(((double) maxBuckets / Host.getHostCount())); // invokeInEveryVM(new SerializableRunnable("") { // // } } /** * Added for defect #47181. Use below combination to reproduce the issue: mcast-port = 0 Locators * should be empty enforce-unique-host = true redundancy-zone = "zone" */ @Test public void testEnforceUniqueHostForLonerDistributedSystem() { Cache myCache = createLonerCacheWithEnforceUniqueHost(); try { AttributesFactory attr = new AttributesFactory(); PartitionAttributesFactory paf = new PartitionAttributesFactory(); PartitionAttributes prAttr = paf.create(); attr.setPartitionAttributes(prAttr); RegionAttributes regionAttribs = attr.create(); Region region = myCache.createRegion("PR1", regionAttribs); for (int i = 0; i < 113; i++) { region.put("Key_" + i, new Integer(i)); } // verify region size assertEquals(113, region.size()); } finally { myCache.close(); myCache.getDistributedSystem().disconnect(); } } /** * Creates the <code>Cache</code> for this test that is not connected to other members. * * <p> * Used by test {@link #testEnforceUniqueHostForLonerDistributedSystem()}. Moved from * DistributedTestCase to this test is the exclusive caller. * * <p> * Added specifically to test scenario of defect #47181. */ private final Cache createLonerCacheWithEnforceUniqueHost() { Cache myCache = null; try { System.setProperty(DistributionConfig.GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE", "true"); myCache = CacheFactory.create(getLonerSystemWithEnforceUniqueHost()); } catch (CacheExistsException e) { Assert.fail("the cache already exists", e); } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { Assert.fail("Checked exception while initializing cache??", ex); } finally { System.clearProperty( DistributionConfig.GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE"); } return myCache; } /** * Returns a loner distributed system in combination with enforceUniqueHost and redundancyZone * properties. * * <p> * Used by test {@link #testEnforceUniqueHostForLonerDistributedSystem()}. Moved from * DistributedTestCase to this test is the exclusive caller. * * <p> * Added specifically to test scenario of defect #47181. */ private final InternalDistributedSystem getLonerSystemWithEnforceUniqueHost() { Properties props = getDistributedSystemProperties(); props.put(MCAST_PORT, "0"); props.put(LOCATORS, ""); props.put(ENFORCE_UNIQUE_HOST, "true"); props.put(REDUNDANCY_ZONE, "zone1"); return getSystem(props); } /** * This function performs destroy(key) operations in multiple Partiton Regions. The range of keys * to be destroyed is from 100 to 200. Each Vm destroys different set of the keys. * * @param startIndexForRegion * @param endIndexForRegion * @param startIndexForDestroy * @param endIndexForDestroy * @throws Throwable */ private void destroyInMultiplePartitionedRegion(int startIndexForRegion, int endIndexForRegion, int startIndexForDestroy, int endIndexForDestroy) throws Throwable { prPrefix = "testMemoryOfPartitionRegion"; int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; int delta = (endIndexForDestroy - startIndexForDestroy) / 4; async[0] = vm[0].invokeAsync(destroyInMultiplePartitionRegion(prPrefix, startIndexForDestroy, startIndexForDestroy + 1 * delta, startIndexForRegion, endIndexForRegion)); async[1] = vm[1] .invokeAsync(destroyInMultiplePartitionRegion(prPrefix, startIndexForDestroy + 1 * delta, startIndexForDestroy + 2 * delta, startIndexForRegion, endIndexForRegion)); async[2] = vm[2] .invokeAsync(destroyInMultiplePartitionRegion(prPrefix, startIndexForDestroy + 2 * delta, startIndexForDestroy + 3 * delta, startIndexForRegion, endIndexForRegion)); async[3] = vm[3] .invokeAsync(destroyInMultiplePartitionRegion(prPrefix, startIndexForDestroy + 3 * delta, endIndexForDestroy, startIndexForRegion, endIndexForRegion)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { Assert.fail("Exception during " + count, async[count].getException()); } } } /** * This function performs destroy(key) operations in multiple Partiton Regions. The range of keys * to be destroyed is from 100 to 200. Each Vm destroys different set of the keys. * * @param startIndexForRegion * @param endIndexForRegion * @param startIndexForInvalidate * @param endIndexForInvalidate */ private void invalidateInMultiplePartitionedRegion(int startIndexForRegion, int endIndexForRegion, int startIndexForInvalidate, int endIndexForInvalidate) throws Throwable { prPrefix = "testMemoryOfPartitionRegion"; int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; int delta = (endIndexForInvalidate - startIndexForInvalidate) / 4; async[0] = vm[0].invokeAsync(invalidatesInMultiplePartitionRegion(prPrefix, startIndexForInvalidate, startIndexForInvalidate + 1 * delta, startIndexForRegion, endIndexForRegion)); async[1] = vm[1].invokeAsync( invalidatesInMultiplePartitionRegion(prPrefix, startIndexForInvalidate + 1 * delta, startIndexForInvalidate + 2 * delta, startIndexForRegion, endIndexForRegion)); async[2] = vm[2].invokeAsync( invalidatesInMultiplePartitionRegion(prPrefix, startIndexForInvalidate + 2 * delta, startIndexForInvalidate + 3 * delta, startIndexForRegion, endIndexForRegion)); async[3] = vm[3].invokeAsync( invalidatesInMultiplePartitionRegion(prPrefix, startIndexForInvalidate + 3 * delta, endIndexForInvalidate, startIndexForRegion, endIndexForRegion)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { Assert.fail("Exception during " + count, async[count].getException()); } } } /** * This function performs put() operations in multiple Partition Regions. Range of the keys which * are put is startIndexForKey to endIndexForKey. Each Vm puts different set of keys. */ private void putInMultiplePartitionedRegionFrom3Nodes(int startIndexForRegion, int endIndexForRegion, int startIndexForKey, int endIndexForKey) throws Throwable { int AsyncInvocationArrSize = 3; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; int delta = (endIndexForKey - startIndexForKey) / 3; async[0] = vm[0].invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForKey, startIndexForKey + 1 * delta, startIndexForRegion, endIndexForRegion)); async[1] = vm[1].invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForKey + 1 * delta, startIndexForKey + 2 * delta, startIndexForRegion, endIndexForRegion)); async[2] = vm[2].invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForKey + 2 * delta, endIndexForKey, startIndexForRegion, endIndexForRegion)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { Assert.fail("exception during" + count, async[count].getException()); } } } /** * This function performs put() operation from the single vm in multiple partition regions. * * @param vm0 * @param startIndexForRegion * @param endIndexForRegion * @param startIndexForKey * @param endIndexForKey */ private void putInMultiplePartitionRegionFromOneVm(VM vm0, final int startIndexForRegion, final int endIndexForRegion, final long startIndexForKey, final long endIndexForKey) throws Throwable { int AsyncInvocationArrSize = 3; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; async[0] = vm0.invokeAsync( putFromOneVm(startIndexForKey, endIndexForKey, startIndexForRegion, endIndexForRegion)); async[1] = vm0.invokeAsync(putFromOneVm(startIndexForKey + totalBucketNumProperty, endIndexForKey + totalBucketNumProperty, startIndexForRegion, endIndexForRegion)); async[2] = vm0.invokeAsync(putFromOneVm(startIndexForKey + 2 * totalBucketNumProperty, endIndexForKey + 2 * totalBucketNumProperty, startIndexForRegion, endIndexForRegion)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { Assert.fail("exception during " + count, async[count].getException()); } } } /** * This function performs put() in multiple partition regions for the given node. * * @param startIndexForKey * @param endIndexForKey * @param startIndexForRegion * @param endIndexForRegion * @return */ private CacheSerializableRunnable putFromOneVm(final long startIndexForKey, final long endIndexForKey, final int startIndexForRegion, final int endIndexForRegion) { CacheSerializableRunnable putFromVm = new CacheSerializableRunnable("putFromOneVm") { String innerPrPrefix = prPrefix; public void run2() { Cache cache = getCache(); for (int i = startIndexForRegion; i < endIndexForRegion; i++) { PartitionedRegion pr = (PartitionedRegion) cache.getRegion(Region.SEPARATOR + innerPrPrefix + (i)); assertNotNull(pr); for (long k = startIndexForKey; k < endIndexForKey; k++) { Long key = new Long(k); pr.put(key, innerPrPrefix + k); } } } }; return putFromVm; } /** * This function performs put() operations in multiple Partition Regions. Range of the keys which * are put is startIndexForKey to endIndexForKey. Each Vm puts different set of keys. */ private void putInMultiplePartitionedRegion(int startIndexForRegion, int endIndexForRegion, int startIndexForKey, int endIndexForKey) throws Throwable { int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; int delta = (endIndexForKey - startIndexForKey) / 4; async[0] = vm[0].invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForKey, startIndexForKey + 1 * delta, startIndexForRegion, endIndexForRegion)); async[1] = vm[1].invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForKey + 1 * delta, startIndexForKey + 2 * delta, startIndexForRegion, endIndexForRegion)); async[2] = vm[2].invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForKey + 2 * delta, startIndexForKey + 3 * delta, startIndexForRegion, endIndexForRegion)); async[3] = vm[3].invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForKey + 3 * delta, endIndexForKey, startIndexForRegion, endIndexForRegion)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { Assert.fail("exception during " + count, async[count].getException()); } } } /** * This function performs put() operations in multiple Partition Regions. Range of the keys which * are put is startIndexForKey to edIndexForKey. Each Vm puts different set of keys */ private void putInMultiplePartitionedRegionFromAllVms(int startIndexForRegion, int endIndexForRegion, long startIndexForKey, long endIndexForKey) throws Throwable { int AsyncInvocationArrSize = 8; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; long delta = (endIndexForKey - startIndexForKey) / 4; async[0] = vm[0].invokeAsync(putFromOneVm(startIndexForKey, startIndexForKey + 1 * delta, startIndexForRegion, endIndexForRegion)); async[1] = vm[1].invokeAsync(putFromOneVm(startIndexForKey + 1 * delta, startIndexForKey + 2 * delta, startIndexForRegion, endIndexForRegion)); async[2] = vm[2].invokeAsync(putFromOneVm(startIndexForKey + 2 * delta, startIndexForKey + 3 * delta, startIndexForRegion, endIndexForRegion)); async[3] = vm[3].invokeAsync(putFromOneVm(startIndexForKey + 3 * delta, endIndexForKey, startIndexForRegion, endIndexForRegion)); startIndexForKey += totalBucketNumProperty; endIndexForKey += totalBucketNumProperty; delta = (endIndexForKey - startIndexForKey) / 4; async[4] = vm[0].invokeAsync(putFromOneVm(startIndexForKey, startIndexForKey + 1 * delta, startIndexForRegion, endIndexForRegion)); async[5] = vm[1].invokeAsync(putFromOneVm(startIndexForKey + 1 * delta, startIndexForKey + 2 * delta, startIndexForRegion, endIndexForRegion)); async[6] = vm[2].invokeAsync(putFromOneVm(startIndexForKey + 2 * delta, startIndexForKey + 3 * delta, startIndexForRegion, endIndexForRegion)); async[7] = vm[3].invokeAsync(putFromOneVm(startIndexForKey + 3 * delta, endIndexForKey, startIndexForRegion, endIndexForRegion)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { Assert.fail("exception during " + count, async[count].getException()); } } } /** * This function performs validation of bucket2Node region of multiple partition regions on 4 VMs. */ private void validateBucket2NodeBeforePutInMultiplePartitionedRegion(int startIndexForRegion, int endIndexForRegion) throws Throwable { int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; async[0] = vm[0].invokeAsync(validateBucket2NodeBeforePut(startIndexForRegion, endIndexForRegion)); async[1] = vm[1].invokeAsync(validateBucket2NodeBeforePut(startIndexForRegion, endIndexForRegion)); async[2] = vm[2].invokeAsync(validateBucket2NodeBeforePut(startIndexForRegion, endIndexForRegion)); async[3] = vm[3].invokeAsync(validateBucket2NodeBeforePut(startIndexForRegion, endIndexForRegion)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { LogWriterUtils.getLogWriter().warning("Failure in async invocation on vm " + vm[count] + " with exception " + async[count].getException()); throw async[count].getException(); // fail("exception during " + count, async[count].getException()); } } } /** * This function performs validation of bucket regions of multiple partition regions on 4 VMs. */ private void validateBucketsAfterPutInMultiplePartitionRegion(final int startIndexForRegion, final int endIndexForRegion) throws Throwable { int AsyncInvocationArrSize = 8; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; // validation of bucket regions creation async[0] = vm[0].invokeAsync(validateBucketCreationAfterPut(startIndexForRegion, endIndexForRegion)); async[1] = vm[1].invokeAsync(validateBucketCreationAfterPut(startIndexForRegion, endIndexForRegion)); async[2] = vm[2].invokeAsync(validateBucketCreationAfterPut(startIndexForRegion, endIndexForRegion)); async[3] = vm[3].invokeAsync( validateBucketCreationAfterPutForNode3(startIndexForRegion, endIndexForRegion)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < 4; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < 4; count++) { if (async[count].exceptionOccurred()) { Assert.fail("got exception on " + count, async[count].getException()); } } // validating scope of buckets async[4] = vm[0].invokeAsync(validateBucketScopeAfterPut(startIndexForRegion, endIndexForRegion)); async[5] = vm[1].invokeAsync(validateBucketScopeAfterPut(startIndexForRegion, endIndexForRegion)); async[6] = vm[2].invokeAsync(validateBucketScopeAfterPut(startIndexForRegion, endIndexForRegion)); async[7] = vm[3].invokeAsync( validateBucketCreationAfterPutForNode3(startIndexForRegion, endIndexForRegion)); /** main thread is waiting for the other threads to complete */ for (int count = 4; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 4; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { LogWriterUtils.getLogWriter().warning("Failure of async invocation on VM " + this.vm[count] + " exception thrown " + async[count].getException()); throw async[count].getException(); } } } /** * This function performs validation of bucket regions of multiple partition regions on 4 VMs. */ private void validateBucketsDistributionInMultiplePartitionRegion(final int startIndexForRegion, final int endIndexForRegion, int noBucketsExpectedOnEachNode) throws Throwable { int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; async[0] = vm[0].invokeAsync(validateBucketsDistribution(startIndexForRegion, endIndexForRegion, noBucketsExpectedOnEachNode)); async[1] = vm[1].invokeAsync(validateBucketsDistribution(startIndexForRegion, endIndexForRegion, noBucketsExpectedOnEachNode)); async[2] = vm[2].invokeAsync(validateBucketsDistribution(startIndexForRegion, endIndexForRegion, noBucketsExpectedOnEachNode)); async[3] = vm[3].invokeAsync(validateBucketsDistribution(startIndexForRegion, endIndexForRegion, noBucketsExpectedOnEachNode)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { Assert.fail("Validation of bucket distribution failed on " + count, async[count].getException()); } } } /** * This function is used for the validation of bucket on all the region. */ private void validateBucketsOnAllNodes(final int startIndexForRegion, final int endIndexForRegion) { CacheSerializableRunnable validateAllNodes = new CacheSerializableRunnable("validateBucketsOnAllNodes") { int innerStartIndexForRegion = startIndexForRegion; int innerEndIndexForRegion = endIndexForRegion; String innerPrPrefix = prPrefix; public void run2() { Cache cache = getCache(); int threshold = 0; for (int i = innerStartIndexForRegion; i < innerEndIndexForRegion; i++) { PartitionedRegion pr = (PartitionedRegion) cache.getRegion(Region.SEPARATOR + innerPrPrefix + i); assertNotNull(pr); assertNotNull(pr.getDataStore()); assertTrue(pr.getDataStore().localBucket2RegionMap.size() > threshold); } } }; vm[0].invoke(validateAllNodes); vm[1].invoke(validateAllNodes); vm[2].invoke(validateAllNodes); vm[3].invoke(validateAllNodes); } private void validateRedundancy(VM vm0, final int startIndexForRegion, final int endIndexForRegion, final int redundancyManageFlag) { vm0.invoke(new CacheSerializableRunnable("validateRedundancy") { int innerStartIndexForRegion = startIndexForRegion; int innerEndIndexForRegion = endIndexForRegion; String innerPrPrefix = prPrefix; public void run2() { Cache cache = getCache(); for (int i = innerStartIndexForRegion; i < endIndexForRegion; i++) { PartitionedRegion pr = (PartitionedRegion) cache.getRegion(Region.SEPARATOR + innerPrPrefix + i); assertNotNull(pr); Set bucketIds = pr.getDataStore().localBucket2RegionMap.keySet(); Iterator buckteIdItr = bucketIds.iterator(); while (buckteIdItr.hasNext()) { Integer bucketId = (Integer) buckteIdItr.next(); if (redundancyManageFlag == 0) { // checking redundancy if (pr.getRegionAdvisor().getBucketRedundancy(bucketId.intValue()) >= redundancy) { fail("Redundancy satisfied for the partition region " + pr.getName()); } } else { if (pr.getRegionAdvisor().getBucketRedundancy(bucketId.intValue()) < redundancy) { fail("Redundancy not satisfied for the partition region " + pr.getName()); } } } if (redundancyManageFlag == 0) { LogWriterUtils.getLogWriter() .info("validateRedundancy() - Redundancy not satisfied for the partition region : " + pr.getName()); } else { LogWriterUtils.getLogWriter() .info("validateRedundancy() - Redundancy satisfied for the partition region : " + pr.getName()); } } } }); } /** * This functions performs following validations on the partitions regiions <br> * (1) Size of bucket2Node region should be > 0.</br> * <br> * (3) In case of the partition regions with redundancy > 0 scope of the bucket regions should be * scope of the partition regions.</br> * <br> * (4) In case of the partition regions with redundancy > 0 no two bucket regions with same * bucketId should be generated on the same node.</br> * * @param startIndexForRegion * @param endIndexForRegion * @return */ private CacheSerializableRunnable validateBucketCreationAfterPut(final int startIndexForRegion, final int endIndexForRegion) { CacheSerializableRunnable validateAfterPut = new CacheSerializableRunnable("validateAfterPut") { int innerStartIndexForRegion = startIndexForRegion; int innerEndIndexForRegion = endIndexForRegion; String innerPrPrefix = prPrefix; int innerMidIndexForRegion = innerStartIndexForRegion + (endIndexForRegion - startIndexForRegion) / 2; int innerQuarterIndex = innerStartIndexForRegion + (endIndexForRegion - startIndexForRegion) / 4; public void run2() { Cache cache = getCache(); Region root = cache.getRegion(PartitionedRegionHelper.PR_ROOT_REGION_NAME); assertNotNull("Root regions is null", root); for (int i = innerStartIndexForRegion; i < innerEndIndexForRegion; i++) { PartitionedRegion pr = (PartitionedRegion) cache.getRegion(Region.SEPARATOR + innerPrPrefix + i); assertTrue(pr.getRegionAdvisor().getBucketSet().size() > 0); assertTrue("Size of local region map should be > 0 for region: " + pr.getFullPath(), pr.getDataStore().localBucket2RegionMap.size() > 0); // taking the buckets which are local to the node and not all the // available buckets. Set bucketIds = pr.getDataStore().localBucket2RegionMap.keySet(); Iterator buckteIdItr = bucketIds.iterator(); while (buckteIdItr.hasNext()) { Integer key = (Integer) buckteIdItr.next(); BucketRegion val = (BucketRegion) pr.getDataStore().localBucket2RegionMap.get(key); Region bucketRegion = root.getSubregion(pr.getBucketName(key.intValue())); assertTrue(bucketRegion.getFullPath().equals(val.getFullPath())); // Bucket region should not be null assertNotNull("Bucket region cannot be null", bucketRegion); // Parent region of the bucket region should be root assertEquals("Parent region is not root", root, bucketRegion.getParentRegion()); } } } }; return validateAfterPut; } private CacheSerializableRunnable validateBucketCreationAfterPutForNode3( final int startIndexForRegion, final int endIndexForRegion) { CacheSerializableRunnable validateAfterPut = new CacheSerializableRunnable("validateBucketCreationAfterPutForNode3") { int innerStartIndexForRegion = startIndexForRegion; int innerEndIndexForRegion = endIndexForRegion; String innerPrPrefix = prPrefix; public void run2() { Cache cache = getCache(); for (int i = innerStartIndexForRegion; i < innerEndIndexForRegion; i++) { PartitionedRegion pr = (PartitionedRegion) cache.getRegion(Region.SEPARATOR + innerPrPrefix + i); assertNotNull("This Partition Region is null " + pr.getName(), pr); assertNull("DataStore should be null", pr.getDataStore()); } } }; return validateAfterPut; } private CacheSerializableRunnable validateBucketScopeAfterPut(final int startIndexForRegion, final int endIndexForRegion) { CacheSerializableRunnable validateAfterPut = new CacheSerializableRunnable("validateBucketScopeAfterPut") { int innerStartIndexForRegion = startIndexForRegion; int innerEndIndexForRegion = endIndexForRegion; String innerPrPrefix = prPrefix; int innerMidIndexForRegion = innerStartIndexForRegion + (endIndexForRegion - startIndexForRegion) / 2; int innerQuarterIndex = innerStartIndexForRegion + (endIndexForRegion - startIndexForRegion) / 4; public void run2() { Cache cache = getCache(); Region root = cache.getRegion(PartitionedRegionHelper.PR_ROOT_REGION_NAME); assertNotNull("Root regions is null", root); for (int i = innerStartIndexForRegion; i < innerEndIndexForRegion; i++) { PartitionedRegion pr = (PartitionedRegion) cache.getRegion(Region.SEPARATOR + innerPrPrefix + i); assertTrue(pr.getRegionAdvisor().getBucketSet().size() > 0); // taking the buckets which are local to the node and not all the // available buckets. Set bucketIds = pr.getDataStore().localBucket2RegionMap.keySet(); Iterator buckteIdItr = bucketIds.iterator(); while (buckteIdItr.hasNext()) { Integer key = (Integer) buckteIdItr.next(); Region bucketRegion = root.getSubregion(pr.getBucketName(key.intValue())); assertNotNull("Bucket region cannot be null", bucketRegion); assertEquals(Scope.DISTRIBUTED_ACK, bucketRegion.getAttributes().getScope()); } // while } } }; return validateAfterPut; } /** * <br> * This function validates bucket2Node region of the Partition regiion before any put() * operations.</br> * <br> * It performs following validatioons <br> * (1) bucket2Node Region should not be null.</br> * <br> * (2) Scope of the bucket2Node region should be DISTRIBUTED_ACK.</br> * <br> * (3) Size of bucket2Node region should be 0.</br> * <br> * (4) Parent region of the bucket2Node region shoud be root i.e. region with name "PRRoot".</br> * * @param startIndexForRegion * @param endIndexForRegion * @return */ private CacheSerializableRunnable validateBucket2NodeBeforePut(final int startIndexForRegion, final int endIndexForRegion) { CacheSerializableRunnable validateBucketBeforePut = new CacheSerializableRunnable("Bucket2NodeValidation") { int innerStartIndexForRegion = startIndexForRegion; int innerEndIndexForRegion = endIndexForRegion; String innerPrPrefix = prPrefix; public void run2() { Cache cache = getCache(); Region root = cache.getRegion(PartitionedRegionHelper.PR_ROOT_REGION_NAME); assertNotNull("Root regions is null", root); for (int i = innerStartIndexForRegion; i < innerEndIndexForRegion; i++) { PartitionedRegion pr = (PartitionedRegion) cache.getRegion(Region.SEPARATOR + innerPrPrefix + i); assertNotNull(pr); assertTrue(pr.getRegionAdvisor().getNumProfiles() > 0); assertTrue(pr.getRegionAdvisor().getNumDataStores() > 0); final int bucketSetSize = pr.getRegionAdvisor().getCreatedBucketsCount(); LogWriterUtils.getLogWriter().info("BucketSet size " + bucketSetSize); if (bucketSetSize != 0) { Set buckets = pr.getRegionAdvisor().getBucketSet(); Iterator it = buckets.iterator(); int numBucketsWithStorage = 0; try { while (true) { Integer bucketId = (Integer) it.next(); pr.getRegionAdvisor().getBucket(bucketId.intValue()).getBucketAdvisor() .dumpProfiles("Bucket owners for bucket " + pr.bucketStringForLogs(bucketId.intValue())); numBucketsWithStorage++; } } catch (NoSuchElementException end) { LogWriterUtils.getLogWriter() .info("BucketSet iterations " + numBucketsWithStorage); } fail("There should be no buckets assigned"); } } } }; return validateBucketBeforePut; } private CacheSerializableRunnable validateBucketsDistribution(final int startIndexForRegion, final int endIndexForRegion, final int noBucketsExpectedOnEachNode) { CacheSerializableRunnable validateBucketDist = new CacheSerializableRunnable("validateBucketsDistribution") { String innerPrPrefix = prPrefix; public void run2() { Cache cache = getCache(); final Region root = cache.getRegion(PartitionedRegionHelper.PR_ROOT_REGION_NAME); assertNotNull("Root regions is null", root); for (int i = startIndexForRegion; i < endIndexForRegion; i++) { final PartitionedRegion pr = (PartitionedRegion) cache.getRegion(Region.SEPARATOR + innerPrPrefix + i); assertNotNull("This region can not be null" + pr.getName(), pr); assertNotNull(pr.getDataStore()); final int localBSize = pr.getDataStore().getBucketsManaged(); LogWriterUtils.getLogWriter() .info("validateBucketsDistribution() - Number of bukctes for " + pr.getName() + " : " + localBSize); assertTrue("Bucket Distribution for region = " + pr.getFullPath() + " is not correct for member " + pr.getDistributionManager().getId() + " existing size " + localBSize + " smaller than expected " + noBucketsExpectedOnEachNode, localBSize >= noBucketsExpectedOnEachNode); pr.getDataStore().visitBuckets(new BucketVisitor() { public void visit(Integer bucketId, Region r) { Region bucketRegion = root.getSubregion(pr.getBucketName(bucketId.intValue())); assertEquals(bucketRegion.getFullPath(), r.getFullPath()); } }); } } }; return validateBucketDist; } /** this function creates vms in given host */ private void createVMs(Host host) { for (int i = 0; i < 4; i++) { vm[i] = host.getVM(i); } } /** * This function createas multiple partition regions on nodes specified in the vmList */ private void createPartitionRegion(List vmList, int startIndexForRegion, int endIndexForRegion, int localMaxMemory, int redundancy) { Iterator nodeIterator = vmList.iterator(); while (nodeIterator.hasNext()) { VM vm = (VM) nodeIterator.next(); vm.invoke(createMultiplePRWithTotalNumBucketPropSet(prPrefix, startIndexForRegion, endIndexForRegion, redundancy, localMaxMemory, 11)); } } /** * This function creates a partition region with TOTAL_BUCKETS_NUM_PROPERTY set to 11. */ private void createPRWithTotalNumPropSetList(List vmList, int startIndexForRegion, int endIndexForRegion, int localMaxMemory, int redundancy) { Iterator nodeIterator = vmList.iterator(); while (nodeIterator.hasNext()) { VM vm = (VM) nodeIterator.next(); vm.invoke(createMultiplePRWithTotalNumBucketPropSet(prPrefix, startIndexForRegion, endIndexForRegion, redundancy, localMaxMemory, 11)); } } CacheSerializableRunnable createMultiplePRWithTotalNumBucketPropSet(final String prPrefix, final int startIndexForRegion, final int endIndexForRegion, final int redundancy, final int localMaxMem, final int numBuckets) { CacheSerializableRunnable createPRWithTotalNumBucketPropSet = new CacheSerializableRunnable("createPRWithTotalNumBucketPropSet") { public void run2() throws CacheException { Cache cache = getCache(); for (int i = startIndexForRegion; i < endIndexForRegion; i++) { cache.createRegion(prPrefix + i, createRegionAttrs(redundancy, localMaxMem, numBuckets)); } LogWriterUtils.getLogWriter().info( "createMultiplePartitionRegion() - Partition Regions Successfully Completed "); } }; return createPRWithTotalNumBucketPropSet; } private void validateTotalNumBuckets(String prPrefix, List vmList, int startIndexForRegion, int endIndexForRegion, int expectedNumBuckets) { Iterator nodeIterator = vmList.iterator(); while (nodeIterator.hasNext()) { VM vm = (VM) nodeIterator.next(); vm.invoke(validateTotalNumberOfBuckets(prPrefix, expectedNumBuckets, startIndexForRegion, endIndexForRegion)); } } /** * This function validates total number of buckets from bucket2NodeRegion of partition region. */ CacheSerializableRunnable validateTotalNumberOfBuckets(final String prPrefix, final int expectedNumBuckets, final int startIndexForRegion, final int endIndexForRegion) { CacheSerializableRunnable validateTotNumBuckets = new CacheSerializableRunnable("validateTotNumBuckets") { String innerPrPrefix = prPrefix; int innerStartIndexForRegion = startIndexForRegion; int innerEndIndexForRegion = endIndexForRegion; public void run2() throws CacheException { Cache cache = getCache(); for (int i = innerStartIndexForRegion; i < innerEndIndexForRegion; i++) { PartitionedRegion pr = (PartitionedRegion) cache.getRegion(Region.SEPARATOR + innerPrPrefix + i); assertNotNull("This region is null " + pr.getName(), pr); Set bucketsWithStorage = pr.getRegionAdvisor().getBucketSet(); assertEquals(expectedNumBuckets, bucketsWithStorage.size()); } LogWriterUtils.getLogWriter() .info("Total Number of buckets validated in partition region"); } }; return validateTotNumBuckets; } /** This function adds nodes to node list */ private List addNodeToList(int startIndexForNode, int endIndexForNode) { List localvmList = new ArrayList(); for (int i = startIndexForNode; i < endIndexForNode; i++) { localvmList.add(vm[i]); } return localvmList; } /** * This function performs following 1. creates multiplePartition regions on different nodes with * vm3 node as accessor. 2. range of partition regions is specified by startIndexForRegion and * endIndexForRegion. 3. first quarter of total partition regions are of scope = DISTRIBUTED_ACK * and redundancy=0. 4. second quarter of total partition regions are of scope = DISTRIBUTED_ACK * and redundancy=2. 5. third quarter of total partition regions are of scope = DISTRIBUTED_NO_ACK * and redundancy=0. 4. fourth quarter of total partition regions are of scope = * DISTRIBUTED_NO_ACK and redundancy=2. * * @param startIndexForRegion * @param endIndexForRegion */ void createMultiplePR(int startIndexForRegion, int endIndexForRegion) { int startIndexForNode = 0; int endIndexForNode = 4; // creating partition regions on 4 nodes out of which partition regions on // one node are only accessors. // partition regions on vm3 are only accessors. int midIndexForRegion = (endIndexForRegion - startIndexForRegion) / 2; // creating multiple partition regions on 3 nodes with scope = // DISTRIBUTED_ACK localMaxMemory=200 redundancy = 0 startIndexForNode = 0; endIndexForNode = 3; List vmList = addNodeToList(startIndexForNode, endIndexForNode); localMaxMemory = 200; // redundancy = 0; createPartitionRegion(vmList, startIndexForRegion, midIndexForRegion, localMaxMemory, redundancy); // creating multiple partition regions on VM3 as only accessor startIndexForNode = 3; endIndexForNode = 4; vmList = addNodeToList(startIndexForNode, endIndexForNode); localMaxMemory = 0; createPartitionRegion(vmList, startIndexForRegion, midIndexForRegion, localMaxMemory, redundancy); // creating multiple partition regions on 3 nodes localMaxMemory=200 redundancy = 1 startIndexForNode = 0; endIndexForNode = 3; vmList = addNodeToList(startIndexForNode, endIndexForNode); localMaxMemory = 200; final int redundancyTwo = 1; createPartitionRegion(vmList, midIndexForRegion, endIndexForNode, localMaxMemory, redundancyTwo); // creating multiple partition regions on VM3 as only accessor startIndexForNode = 3; endIndexForNode = 4; vmList = addNodeToList(startIndexForNode, endIndexForNode); localMaxMemory = 0; createPartitionRegion(vmList, midIndexForRegion, endIndexForNode, localMaxMemory, redundancyTwo); LogWriterUtils.getLogWriter().info( "testBucketCerationInMultiPlePartitionRegion() - Partition Regions successfully created "); } /** * This function is used to calculate memory of partiton region at each node */ private void calculateTotalMemoryOfPartitionRegion() { for (int i = 0; i < 4; i++) { if (vm[i] == null) LogWriterUtils.getLogWriter().fine("VM is null" + vm[i]); vm[i].invoke(calculateMemoryOfPartitionRegion(i, i + 1)); } } /** * This function verifies memory of partition region calculated at each node. */ private void checkTotalMemoryOfPartitionRegion() { CacheSerializableRunnable testTotalMemory = new CacheSerializableRunnable("testTotalMemory") { int innerStartIndexForKey = 0; int innerEndIndexForKey = 4; String innerPrPrefix = prPrefix; List sizeList = new ArrayList(); public void run2() { Cache cache = getCache(); innerPrPrefix = "createPRForStrorage"; PartitionedRegion prForStorage = (PartitionedRegion) cache.getRegion(Region.SEPARATOR + innerPrPrefix + 0); for (int i = innerStartIndexForKey; i < innerEndIndexForKey; i++) { Object obj = prForStorage.get(new Long(i)); sizeList.add(obj); } Iterator sizeItr = sizeList.iterator(); Object objSize = sizeItr.next(); while (sizeItr.hasNext()) { assertEquals(sizeItr.next(), objSize); } LogWriterUtils.getLogWriter().info("Size of partition region on each node is equal"); } }; vm[0].invoke(testTotalMemory); } /** * This function calculates memory of partition region at each node and puts it in storage region. * * @param startIndexForKey * @param endIndexForKey * @return */ private CacheSerializableRunnable calculateMemoryOfPartitionRegion(final int startIndexForKey, final int endIndexForKey) { CacheSerializableRunnable calulateTotalMemory = new CacheSerializableRunnable("calulateTotalMemory") { int innerStartIndexForKey = startIndexForKey; int innerEndIndexForKey = endIndexForKey; String innerPrPrefix = prPrefix; public void run2() { Cache cache = getCache(); PartitionedRegion pr = (PartitionedRegion) cache .getRegion(Region.SEPARATOR + "testMemoryOfPartitionRegion" + 0); assertNotNull("pr can not be null", pr); assertNotNull("DataStore cannot be null", pr.getDataStore()); long prMemory = pr.getDataStore().currentAllocatedMemory(); innerPrPrefix = "createPRForStrorage"; PartitionedRegion prForStorage = (PartitionedRegion) cache.getRegion(Region.SEPARATOR + innerPrPrefix + 0); for (int i = innerStartIndexForKey; i < innerEndIndexForKey; i++) { prForStorage.put(new Long(i), new Long(prMemory)); } } }; return calulateTotalMemory; } private int getNoBucketsExpectedOnEachNode() { int noBucketsExpectedOnEachNode = (totalBucketNumProperty / 4) - 1; return noBucketsExpectedOnEachNode; } protected RegionAttributes createRegionAttrs(int red, int localMaxMem, int numBuckets) { AttributesFactory attr = new AttributesFactory(); attr.setMirrorType(MirrorType.NONE); PartitionAttributesFactory paf = new PartitionAttributesFactory(); PartitionAttributes prAttr = paf.setRedundantCopies(red).setLocalMaxMemory(localMaxMem) .setTotalNumBuckets(numBuckets).create(); attr.setPartitionAttributes(prAttr); return attr.create(); } private void putForLocalMaxMemoryInMultiplePR(String regionName) throws Throwable { final int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; async[0] = vm[0].invokeAsync(doPutForLocalMaxMemory(regionName, "vm0")); async[1] = vm[1].invokeAsync(doPutForLocalMaxMemory(regionName, "vm1")); async[2] = vm[2].invokeAsync(doPutForLocalMaxMemory(regionName, "vm2")); async[3] = vm[3].invokeAsync(doPutForLocalMaxMemory(regionName, "vm3")); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } /** testing whether exception occurred */ for (int count = 0; count < AsyncInvocationArrSize; count++) { assertTrue(async[count].exceptionOccurred()); assertTrue(async[count].getException() instanceof PartitionedRegionStorageException); } } private CacheSerializableRunnable doPutForLocalMaxMemory(final String regionName, final String key) throws Exception { CacheSerializableRunnable putForLocalMaxMemory = new CacheSerializableRunnable("putForLocalMaxMemory") { public void run2() { final int MAX_SIZE = 1024; Cache cache = getCache(); byte Obj[] = new byte[MAX_SIZE]; Arrays.fill(Obj, (byte) 'A'); PartitionedRegion pr = (PartitionedRegion) cache.getRegion(Region.SEPARATOR + regionName); for (int i = 0; i < MAX_SIZE * 2; i++) { pr.put(key + i, Obj); LogWriterUtils.getLogWriter().info("MAXSIZE : " + i); } LogWriterUtils.getLogWriter().info("Put successfully done for vm" + key); } }; return putForLocalMaxMemory; } }