/* * 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.LOCATORS; import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import com.jayway.awaitility.Awaitility; import org.apache.geode.cache.AttributesFactory; import org.apache.geode.cache.Cache; import org.apache.geode.cache.CacheClosedException; import org.apache.geode.cache.CacheFactory; import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.PartitionAttributesFactory; import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionAttributes; import org.apache.geode.cache.Scope; import org.apache.geode.cache.client.Pool; import org.apache.geode.cache.client.PoolManager; import org.apache.geode.cache.client.internal.ClientMetadataService; import org.apache.geode.cache.client.internal.ClientPartitionAdvisor; import org.apache.geode.cache.server.CacheServer; import org.apache.geode.distributed.DistributedSystem; import org.apache.geode.internal.cache.execute.data.CustId; import org.apache.geode.internal.cache.execute.data.OrderId; import org.apache.geode.internal.cache.execute.data.ShipmentId; import org.apache.geode.internal.cache.tier.sockets.CacheServerTestUtil; import org.apache.geode.test.dunit.Assert; import org.apache.geode.test.dunit.DistributedTestUtils; import org.apache.geode.test.dunit.Host; import org.apache.geode.test.dunit.LogWriterUtils; import org.apache.geode.test.dunit.VM; import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase; import org.apache.geode.test.junit.categories.DistributedTest; import org.junit.Test; import org.junit.experimental.categories.Category; import java.io.IOException; import java.util.Map; import java.util.Properties; import java.util.concurrent.TimeUnit; @Category(DistributedTest.class) public class SingleHopStatsDUnitTest extends JUnit4CacheTestCase { private static final String Region_Name = "42010"; private static final String ORDER_REGION_NAME = "ORDER"; private static final String SHIPMENT_REGION_NAME = "SHIPMENT"; private static final String CUSTOMER_REGION_NAME = "CUSTOMER"; private VM member0 = null; private VM member1 = null; private VM member2 = null; private VM member3 = null; private static long metaDataRefreshCount; private static long metaDataRefreshCount_Customer; private static long metaDataRefreshCount_Order; private static long metaDataRefreshCount_Shipment; @Override public final void postSetUp() throws Exception { Host host = Host.getHost(0); member0 = host.getVM(0); member1 = host.getVM(1); member2 = host.getVM(2); member3 = host.getVM(3); } @Override public final void preTearDownCacheTestCase() throws Exception { // close the clients first member0.invoke(this::closeCacheAndDisconnect); member1.invoke(this::closeCacheAndDisconnect); member2.invoke(this::closeCacheAndDisconnect); member3.invoke(this::closeCacheAndDisconnect); closeCacheAndDisconnect(); } @Override public final void postTearDownCacheTestCase() throws Exception { try { member0 = null; member1 = null; member2 = null; member3 = null; } finally { DistributedTestUtils.unregisterAllDataSerializersFromAllVms(); } } private void closeCacheAndDisconnect() { try { Cache cache = CacheFactory.getAnyInstance(); if (cache != null && !cache.isClosed()) { cache.close(); cache.getDistributedSystem().disconnect(); } } catch (CacheClosedException e) { } } @Test public void testClientStatsPR() { Integer port0 = member0.invoke(() -> createServerForStats(0, 113, false)); Integer port1 = member1.invoke(() -> createServerForStats(0, 113, false)); Integer port2 = member2.invoke(() -> createServerForStats(0, 113, false)); member3.invoke("createClient", () -> createClient(port0, port1, port2, false)); createClient(port0, port1, port2, false); member3.invoke("createPR", () -> createPR("FirstClient", false)); createPR("SecondClient", false); member3.invoke("getPR", () -> getPR("FirstClient", false)); getPR("SecondClient", false); member3.invoke("updatePR", () -> updatePR("FirstClient", false)); } @Test public void testClientStatsColocationPR() { Integer port0 = member0.invoke(() -> createServerForStats(0, 4, true)); Integer port1 = member1.invoke(() -> createServerForStats(0, 4, true)); Integer port2 = member2.invoke(() -> createServerForStats(0, 4, true)); member3.invoke(() -> createClient(port0, port1, port2, true)); createClient(port0, port1, port2, true); member3.invoke(() -> createPR("FirstClient", true)); member3.invoke(() -> getPR("FirstClient", true)); } private void createClient(int port0, int port1, int port2, boolean colocated) { Properties props = new Properties(); props.setProperty(MCAST_PORT, "0"); props.setProperty(LOCATORS, ""); DistributedSystem distributedSystem = getSystem(props); Cache cache = CacheFactory.create(distributedSystem); assertNotNull(cache); CacheServerTestUtil.disableShufflingOfEndpoints(); Pool pool; try { pool = PoolManager.createFactory().addServer("localhost", port0).addServer("localhost", port1) .addServer("localhost", port2).setRetryAttempts(5).setMinConnections(1) .setMaxConnections(-1).setSubscriptionEnabled(false).create(Region_Name); } finally { CacheServerTestUtil.enableShufflingOfEndpoints(); } createRegionInClientCache(pool.getName(), colocated, cache); } private int createServerForStats(int redundantCopies, int totalNoOfBuckets, boolean colocated) { Cache cache = getCache(); CacheServer server = cache.addCacheServer(); server.setPort(0); server.setHostnameForClients("localhost"); try { server.start(); } catch (IOException e) { Assert.fail("Failed to start server ", e); } Region region = null; if (!colocated) { if (totalNoOfBuckets == 0) { // DR AttributesFactory attr = new AttributesFactory(); attr.setScope(Scope.DISTRIBUTED_ACK); attr.setDataPolicy(DataPolicy.REPLICATE); region = cache.createRegion(Region_Name, attr.create()); assertNotNull(region); LogWriterUtils.getLogWriter().info( "Distributed Region " + Region_Name + " created Successfully :" + region.toString()); } else { PartitionAttributesFactory paf = new PartitionAttributesFactory(); paf.setRedundantCopies(redundantCopies).setTotalNumBuckets(totalNoOfBuckets); AttributesFactory attr = new AttributesFactory(); attr.setPartitionAttributes(paf.create()); region = cache.createRegion(Region_Name, attr.create()); assertNotNull(region); LogWriterUtils.getLogWriter().info( "Partitioned Region " + Region_Name + " created Successfully :" + region.toString()); } } else { PartitionAttributesFactory paf = new PartitionAttributesFactory(); paf.setRedundantCopies(redundantCopies).setTotalNumBuckets(totalNoOfBuckets) .setPartitionResolver( new CustomerIDPartitionResolver("CustomerIDPartitio" + "nResolver")); AttributesFactory attr = new AttributesFactory(); attr.setPartitionAttributes(paf.create()); Region customerRegion = cache.createRegion(CUSTOMER_REGION_NAME, attr.create()); assertNotNull(customerRegion); LogWriterUtils.getLogWriter() .info("Partitioned Region CUSTOMER created Successfully :" + customerRegion.toString()); paf = new PartitionAttributesFactory(); paf.setRedundantCopies(redundantCopies).setTotalNumBuckets(totalNoOfBuckets) .setColocatedWith(CUSTOMER_REGION_NAME) .setPartitionResolver(new CustomerIDPartitionResolver("CustomerIDPartitionResolver")); attr = new AttributesFactory(); attr.setPartitionAttributes(paf.create()); Region orderRegion = cache.createRegion(ORDER_REGION_NAME, attr.create()); assertNotNull(orderRegion); LogWriterUtils.getLogWriter() .info("Partitioned Region ORDER created Successfully :" + orderRegion.toString()); paf = new PartitionAttributesFactory(); paf.setRedundantCopies(redundantCopies).setTotalNumBuckets(totalNoOfBuckets) .setColocatedWith(ORDER_REGION_NAME) .setPartitionResolver(new CustomerIDPartitionResolver("CustomerIDPartitionResolver")); attr = new AttributesFactory(); attr.setPartitionAttributes(paf.create()); Region shipmentRegion = cache.createRegion(SHIPMENT_REGION_NAME, attr.create()); assertNotNull(shipmentRegion); LogWriterUtils.getLogWriter() .info("Partitioned Region SHIPMENT created Successfully :" + shipmentRegion.toString()); } return server.getPort(); } private void createRegionInClientCache(String poolName, boolean colocated, Cache cache) { Region region; if (!colocated) { AttributesFactory factory = new AttributesFactory(); factory.setPoolName(poolName); factory.setDataPolicy(DataPolicy.EMPTY); RegionAttributes attrs = factory.create(); region = cache.createRegion(Region_Name, attrs); assertNotNull(region); LogWriterUtils.getLogWriter() .info("Region " + Region_Name + " created Successfully :" + region.toString()); } else { AttributesFactory factory = new AttributesFactory(); factory.setPoolName(poolName); RegionAttributes attrs = factory.create(); Region customerRegion = cache.createRegion(CUSTOMER_REGION_NAME, attrs); assertNotNull(customerRegion); LogWriterUtils.getLogWriter() .info("Partitioned Region CUSTOMER created Successfully :" + customerRegion.toString()); factory = new AttributesFactory(); factory.setPoolName(poolName); attrs = factory.create(); Region orderRegion = cache.createRegion(ORDER_REGION_NAME, attrs); assertNotNull(orderRegion); LogWriterUtils.getLogWriter() .info("Partitioned Region ORDER created Successfully :" + orderRegion.toString()); factory = new AttributesFactory(); factory.setPoolName(poolName); attrs = factory.create(); Region shipmentRegion = cache.createRegion("SHIPMENT", attrs); assertNotNull(shipmentRegion); LogWriterUtils.getLogWriter() .info("Partitioned Region SHIPMENT created Successfully :" + shipmentRegion.toString()); } } private void createPR(String fromClient, boolean colocated) { GemFireCacheImpl cache = (GemFireCacheImpl) CacheFactory.getAnyInstance(); Region region = cache.getRegion(Region_Name); if (!colocated) { if (fromClient.equals("FirstClient")) { System.out.println("first pass..."); for (int i = 0; i < 113; i++) { region.create(i, "create" + i); } ClientMetadataService cms = cache.getClientMetadataService(); final Map<String, ClientPartitionAdvisor> regionMetaData = cms.getClientPRMetadata_TEST_ONLY(); assertEquals(0, regionMetaData.size()); System.out.println("second pass..."); for (int i = 113; i < 226; i++) { region.create(i, "create" + i); } cms = ((GemFireCacheImpl) cache).getClientMetadataService(); // since PR metadata is fetched in a background executor thread // we need to wait for it to arrive for a bit Awaitility.await().timeout(120, TimeUnit.SECONDS).pollDelay(100, TimeUnit.MILLISECONDS) .pollInterval(500, TimeUnit.MILLISECONDS).until(() -> regionMetaData.size() == 1); assertTrue(regionMetaData.containsKey(region.getFullPath())); regionMetaData.get(region.getFullPath()); metaDataRefreshCount = ((LocalRegion) region).getCachePerfStats().getMetaDataRefreshCount(); assertTrue(metaDataRefreshCount != 0); // hops are not predictable System.out.println("metadata refresh count after second pass is " + metaDataRefreshCount); } else { System.out.println("creating keys in second client"); for (int i = 0; i < 226; i++) { region.create(i, "create" + i); } ClientMetadataService cms = cache.getClientMetadataService(); Map<String, ClientPartitionAdvisor> regionMetaData = cms.getClientPRMetadata_TEST_ONLY(); assertEquals(1, regionMetaData.size()); assertTrue(regionMetaData.containsKey(region.getFullPath())); regionMetaData.get(region.getFullPath()); metaDataRefreshCount = ((LocalRegion) region).getCachePerfStats().getMetaDataRefreshCount(); assertTrue(metaDataRefreshCount != 0); // hops are not predictable System.out.println("metadata refresh count in second client is " + metaDataRefreshCount); } } else { createdColocatedPRData(cache); } } private void createdColocatedPRData(GemFireCacheImpl cache) { Region customerRegion = cache.getRegion(CUSTOMER_REGION_NAME); Region orderRegion = cache.getRegion(ORDER_REGION_NAME); Region shipmentRegion = cache.getRegion(SHIPMENT_REGION_NAME); for (int i = 0; i <= 20; i++) { CustId custid = new CustId(i); Customer customer = new Customer("name" + i, "Address" + i); customerRegion.put(custid, customer); for (int j = 1; j <= 10; j++) { int oid = (i * 10) + j; OrderId orderId = new OrderId(oid, custid); Order order = new Order(ORDER_REGION_NAME + oid); orderRegion.put(orderId, order); for (int k = 1; k <= 10; k++) { int sid = (oid * 10) + k; ShipmentId shipmentId = new ShipmentId(sid, orderId); Shipment shipment = new Shipment("Shipment" + sid); shipmentRegion.put(shipmentId, shipment); } } } ClientMetadataService cms = cache.getClientMetadataService(); Map<String, ClientPartitionAdvisor> regionMetaData = cms.getClientPRMetadata_TEST_ONLY(); assertEquals(3, regionMetaData.size()); assertTrue(regionMetaData.containsKey(customerRegion.getFullPath())); regionMetaData.get(customerRegion.getFullPath()); metaDataRefreshCount_Customer = ((LocalRegion) customerRegion).getCachePerfStats().getMetaDataRefreshCount(); assertTrue(metaDataRefreshCount_Customer != 0); // hops are not predictable regionMetaData.get(orderRegion.getFullPath()); metaDataRefreshCount_Order = ((LocalRegion) orderRegion).getCachePerfStats().getMetaDataRefreshCount(); assertTrue(metaDataRefreshCount_Order == 0); regionMetaData.get(shipmentRegion.getFullPath()); metaDataRefreshCount_Shipment = ((LocalRegion) shipmentRegion).getCachePerfStats().getMetaDataRefreshCount(); assertTrue(metaDataRefreshCount_Shipment == 0); } private void getPR(String FromClient, boolean colocated) { Cache cache = CacheFactory.getAnyInstance(); Region region = cache.getRegion(Region_Name); Region customerRegion = cache.getRegion(CUSTOMER_REGION_NAME); Region orderRegion = cache.getRegion(ORDER_REGION_NAME); Region shipmentRegion = cache.getRegion("SHIPMENT"); if (!colocated) { for (int i = 0; i < 226; i++) { region.get(i); } ClientMetadataService cms = ((GemFireCacheImpl) cache).getClientMetadataService(); Map<String, ClientPartitionAdvisor> regionMetaData = cms.getClientPRMetadata_TEST_ONLY(); assertEquals(1, regionMetaData.size()); regionMetaData.get(region.getFullPath()); assertEquals(metaDataRefreshCount, ((LocalRegion) region).getCachePerfStats().getMetaDataRefreshCount()); } else { for (int i = 0; i <= 20; i++) { CustId custid = new CustId(i); customerRegion.get(custid); for (int j = 1; j <= 10; j++) { int oid = (i * 10) + j; OrderId orderId = new OrderId(oid, custid); orderRegion.get(orderId); for (int k = 1; k <= 10; k++) { int sid = (oid * 10) + k; ShipmentId shipmentId = new ShipmentId(sid, orderId); shipmentRegion.get(shipmentId); } } } ClientMetadataService cms = ((GemFireCacheImpl) cache).getClientMetadataService(); Map<String, ClientPartitionAdvisor> regionMetaData = cms.getClientPRMetadata_TEST_ONLY(); assertEquals(3, regionMetaData.size()); assertTrue(regionMetaData.containsKey(customerRegion.getFullPath())); regionMetaData.get(customerRegion.getFullPath()); assertEquals(metaDataRefreshCount_Customer, ((LocalRegion) customerRegion).getCachePerfStats().getMetaDataRefreshCount()); regionMetaData.get(orderRegion.getFullPath()); assertEquals(metaDataRefreshCount_Order, ((LocalRegion) orderRegion).getCachePerfStats().getMetaDataRefreshCount()); regionMetaData.get(shipmentRegion.getFullPath()); assertEquals(metaDataRefreshCount_Shipment, ((LocalRegion) shipmentRegion).getCachePerfStats().getMetaDataRefreshCount()); } } private void updatePR(String FromClient, boolean colocated) { Cache cache = CacheFactory.getAnyInstance(); Region region = cache.getRegion(Region_Name); if (!colocated) { if (FromClient.equals("FirstClient")) { for (int i = 0; i < 226; i++) { region.put(i, "Update" + i); } ClientMetadataService cms = ((GemFireCacheImpl) cache).getClientMetadataService(); Map<String, ClientPartitionAdvisor> regionMetaData = cms.getClientPRMetadata_TEST_ONLY(); assertEquals(1, regionMetaData.size()); regionMetaData.get(region.getFullPath()); assertEquals(metaDataRefreshCount, ((LocalRegion) region).getCachePerfStats().getMetaDataRefreshCount()); } } } }