| /* |
| * 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. |
| */ |
| |
| #include <fstream> |
| #include <iostream> |
| #include <list> |
| |
| #include <boost/process.hpp> |
| #include <boost/regex.hpp> |
| |
| #include <geode/SystemProperties.hpp> |
| #include <geode/PoolManager.hpp> |
| #include <geode/internal/chrono/duration.hpp> |
| #include <geode/RegionShortcut.hpp> |
| #include <geode/RegionFactory.hpp> |
| |
| #include "framework/GfshExecute.h" |
| |
| #include "CacheRegionHelper.hpp" |
| #include "DistributedSystemImpl.hpp" |
| #include "TimeBomb.hpp" |
| #include "Utils.hpp" |
| #include "CacheImpl.hpp" |
| |
| #include "CacheHelper.hpp" |
| #define __DUNIT_NO_MAIN__ |
| #include "fw_dunit.hpp" |
| |
| #include <chrono> |
| #include <thread> |
| |
| #include <boost/asio.hpp> |
| |
| #ifndef ROOT_NAME |
| #define ROOT_NAME "Root" |
| #endif |
| |
| #ifndef ROOT_SCOPE |
| #define ROOT_SCOPE LOCAL |
| #endif |
| |
| #if defined(WIN32) |
| #define COPY_COMMAND "copy /y" |
| #define PATH_SEP "\\" |
| #else |
| #define PATH_SEP "/" |
| #endif |
| |
| extern ClientCleanup gClientCleanup; |
| |
| namespace apache { |
| namespace geode { |
| namespace client { |
| |
| #define RANDOM_NUMBER_OFFSET 14000 |
| #define RANDOM_NUMBER_DIVIDER 15000 |
| std::shared_ptr<Cache> CacheHelper::getCache() { return cachePtr; } |
| |
| CacheHelper &CacheHelper::getHelper() { |
| if (singleton == nullptr) { |
| singleton = new CacheHelper(); |
| } |
| return *singleton; |
| } |
| |
| void CacheHelper::resetHelper() { |
| if (singleton != nullptr) { |
| delete singleton; |
| singleton = nullptr; |
| } |
| } |
| |
| CacheHelper::CacheHelper(const char *, |
| const std::shared_ptr<Properties> &configPtr, |
| const bool noRootRegion) { |
| auto pp = configPtr; |
| if (pp == nullptr) { |
| pp = Properties::create(); |
| } |
| |
| auto cacheFactory = CacheFactory(pp); |
| cachePtr = std::make_shared<Cache>(cacheFactory.create()); |
| |
| if (noRootRegion) return; |
| |
| try { |
| auto regionFactory = |
| cachePtr->createRegionFactory(RegionShortcut::CACHING_PROXY); |
| rootRegionPtr = regionFactory.create(ROOT_NAME); |
| } catch (const RegionExistsException &) { |
| rootRegionPtr = cachePtr->getRegion(ROOT_NAME); |
| } |
| |
| showRegionAttributes(rootRegionPtr->getAttributes()); |
| } |
| |
| /** rootRegionPtr will still be null... */ |
| CacheHelper::CacheHelper(const char *, const std::string &cachexml, |
| const std::shared_ptr<Properties> &configPtr) { |
| auto pp = configPtr; |
| if (pp == nullptr) { |
| pp = Properties::create(); |
| } |
| if (!cachexml.empty()) { |
| auto newFile = CacheHelper::createDuplicateXMLFile(cachexml); |
| pp->insert("cache-xml-file", newFile.c_str()); |
| } |
| auto cacheFactory = CacheFactory(pp); |
| cachePtr = std::make_shared<Cache>(cacheFactory.create()); |
| } |
| |
| CacheHelper::CacheHelper(const std::shared_ptr<Properties> &configPtr, |
| const bool noRootRegion) { |
| auto pp = configPtr; |
| if (pp == nullptr) { |
| pp = Properties::create(); |
| } |
| |
| auto cacheFactory = CacheFactory(pp); |
| cachePtr = std::make_shared<Cache>(cacheFactory.create()); |
| |
| auto poolFactory = cachePtr->getPoolManager().createFactory(); |
| addServerLocatorEPs("localhost:40404", poolFactory); |
| poolFactory.create("__CACHE_HELPER_POOL__"); |
| |
| if (noRootRegion) return; |
| |
| try { |
| auto regionFactory = |
| cachePtr->createRegionFactory(RegionShortcut::CACHING_PROXY); |
| rootRegionPtr = regionFactory.create(ROOT_NAME); |
| } catch (const RegionExistsException &) { |
| rootRegionPtr = cachePtr->getRegion(ROOT_NAME); |
| } |
| |
| showRegionAttributes(rootRegionPtr->getAttributes()); |
| } |
| |
| CacheHelper::CacheHelper(const bool, |
| const std::shared_ptr<AuthInitialize> &authInitialize, |
| const std::shared_ptr<Properties> &configPtr) { |
| auto pp = configPtr; |
| if (pp == nullptr) { |
| pp = Properties::create(); |
| } |
| try { |
| LOG(" in cachehelper before createCacheFactory"); |
| auto cacheFactory = CacheFactory(pp).setAuthInitialize(authInitialize); |
| cachePtr = std::make_shared<Cache>(cacheFactory.create()); |
| } catch (const Exception &excp) { |
| LOG("Geode exception while creating cache, logged in following line"); |
| LOG(excp.what()); |
| } catch (...) { |
| LOG("Throwing exception while creating cache...."); |
| } |
| } |
| |
| CacheHelper::CacheHelper(const bool, |
| const std::shared_ptr<Properties> &configPtr, |
| const bool) { |
| auto pp = configPtr; |
| if (pp == nullptr) { |
| pp = Properties::create(); |
| } |
| LOG(" in cachehelper before createCacheFactory"); |
| auto cacheFactory = CacheFactory(pp); |
| cachePtr = std::make_shared<Cache>(cacheFactory.create()); |
| } |
| |
| CacheHelper::CacheHelper(const bool, bool pdxIgnoreUnreadFields, |
| bool pdxReadSerialized, |
| const std::shared_ptr<Properties> &configPtr, |
| const bool) { |
| auto pp = configPtr; |
| if (pp == nullptr) { |
| pp = Properties::create(); |
| } |
| try { |
| auto cfPtr = CacheFactory(pp); |
| LOGINFO("pdxReadSerialized = %d ", pdxReadSerialized); |
| LOGINFO("pdxIgnoreUnreadFields = %d ", pdxIgnoreUnreadFields); |
| cfPtr.setPdxReadSerialized(pdxReadSerialized); |
| cfPtr.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields); |
| cachePtr = std::make_shared<Cache>(cfPtr.create()); |
| } catch (const Exception &excp) { |
| LOG("Geode exception while creating cache, logged in following line"); |
| LOG(excp.what()); |
| } catch (...) { |
| LOG("Throwing exception while creating cache...."); |
| } |
| } |
| |
| CacheHelper::CacheHelper(const bool, const char *poolName, |
| const std::string &locators, const char *serverGroup, |
| const std::shared_ptr<Properties> &configPtr, |
| int redundancy, bool clientNotification, |
| int subscriptionAckInterval, int connections, |
| int loadConditioningInterval, bool isMultiuserMode, |
| bool prSingleHop, bool threadLocal) { |
| auto pp = configPtr; |
| if (pp == nullptr) { |
| pp = Properties::create(); |
| } |
| |
| try { |
| auto cacheFac = CacheFactory(pp); |
| cachePtr = std::make_shared<Cache>(cacheFac.create()); |
| |
| auto poolFactory = cachePtr->getPoolManager().createFactory(); |
| |
| poolFactory.setPRSingleHopEnabled(prSingleHop); |
| poolFactory.setThreadLocalConnections(threadLocal); |
| std::cout << " Setting pr-single-hop to prSingleHop = " << prSingleHop |
| << "\n"; |
| std::cout << "Setting threadLocal to " << threadLocal << "\n"; |
| if (!locators.empty()) { |
| addServerLocatorEPs(locators, poolFactory); |
| if (serverGroup) { |
| poolFactory.setServerGroup(serverGroup); |
| } |
| } |
| poolFactory.setSubscriptionRedundancy(redundancy); |
| poolFactory.setSubscriptionEnabled(clientNotification); |
| poolFactory.setMultiuserAuthentication(isMultiuserMode); |
| if (loadConditioningInterval > 0) { |
| poolFactory.setLoadConditioningInterval( |
| std::chrono::milliseconds(loadConditioningInterval)); |
| } |
| std::cout << "Setting connections to " << connections << "\n"; |
| if (connections >= 0) { |
| poolFactory.setMinConnections(connections); |
| poolFactory.setMaxConnections(connections); |
| } |
| if (subscriptionAckInterval != -1) { |
| poolFactory.setSubscriptionAckInterval( |
| std::chrono::milliseconds(subscriptionAckInterval)); |
| } |
| |
| poolFactory.create(poolName); |
| |
| } catch (const Exception &excp) { |
| LOG("Geode exception while creating cache, logged in following line"); |
| LOG(excp.what()); |
| } catch (...) { |
| LOG("Throwing exception while creating cache...."); |
| } |
| } |
| |
| CacheHelper::CacheHelper(const int, |
| const std::shared_ptr<Properties> &configPtr) { |
| auto pp = configPtr; |
| if (pp == nullptr) { |
| pp = Properties::create(); |
| } |
| |
| auto cacheFac = CacheFactory(pp); |
| cachePtr = std::make_shared<Cache>(cacheFac.create()); |
| } |
| |
| CacheHelper::~CacheHelper() { |
| // CacheHelper::cleanupTmpConfigFiles(); |
| disconnect(); |
| } |
| |
| void CacheHelper::disconnect(bool keepalive) { |
| if (cachePtr == nullptr) { |
| return; |
| } |
| |
| LOG("Beginning cleanup after CacheHelper."); |
| |
| // rootRegionPtr->localDestroyRegion(); |
| rootRegionPtr = nullptr; |
| LOG("Destroyed root region."); |
| try { |
| LOG("Closing cache."); |
| if (cachePtr != nullptr) { |
| cachePtr->close(keepalive); |
| } |
| LOG("Closing cache complete."); |
| } catch (Exception &ex) { |
| LOG("Exception thrown while closing cache: "); |
| LOG(ex.what()); |
| } catch (...) { |
| LOG("exception throw while closing cache"); |
| } |
| |
| LOG("Closed cache."); |
| cachePtr = nullptr; |
| singleton = nullptr; |
| LOG("Finished cleanup after CacheHelper."); |
| } |
| |
| void CacheHelper::createPlainRegion(const char *regionName, |
| std::shared_ptr<Region> ®ionPtr) { |
| createPlainRegion(regionName, regionPtr, 10); |
| } |
| |
| void CacheHelper::createPlainRegion(const char *regionName, |
| std::shared_ptr<Region> ®ionPtr, |
| uint32_t size) { |
| RegionAttributesFactory regionAttributesFactory; |
| // set lru attributes... |
| regionAttributesFactory.setLruEntriesLimit(0); // no limit. |
| regionAttributesFactory.setInitialCapacity(size); // no limit. |
| // then... |
| auto regionAttributes = regionAttributesFactory.create(); |
| showRegionAttributes(regionAttributes); |
| // This is using subregions (deprecated) so not placing the new cache API here |
| regionPtr = rootRegionPtr->createSubregion(regionName, regionAttributes); |
| ASSERT(regionPtr != nullptr, "failed to create region."); |
| } |
| |
| void CacheHelper::createLRURegion(const char *regionName, |
| std::shared_ptr<Region> ®ionPtr) { |
| createLRURegion(regionName, regionPtr, 10); |
| } |
| void CacheHelper::createLRURegion(const char *regionName, |
| std::shared_ptr<Region> ®ionPtr, |
| uint32_t size) { |
| RegionAttributesFactory regionAttributesFactory; |
| // set lru attributes... |
| regionAttributesFactory.setLruEntriesLimit(size); |
| regionAttributesFactory.setInitialCapacity(size); |
| // then... |
| auto regionAttributes = regionAttributesFactory.create(); |
| showRegionAttributes(regionAttributes); |
| // This is using subregions (deprecated) so not placing the new cache API here |
| regionPtr = rootRegionPtr->createSubregion(regionName, regionAttributes); |
| ASSERT(regionPtr != nullptr, "failed to create region."); |
| } |
| |
| void CacheHelper::createDistRegion(const char *regionName, |
| std::shared_ptr<Region> ®ionPtr, |
| uint32_t size) { |
| RegionAttributesFactory regionAttributesFactory; |
| // set lru attributes... |
| regionAttributesFactory.setLruEntriesLimit(0); // no limit. |
| regionAttributesFactory.setInitialCapacity(size); // no limit. |
| // then... |
| auto regionAttributes = regionAttributesFactory.create(); |
| showRegionAttributes(regionAttributes); |
| // This is using subregions (deprecated) so not placing the new cache API here |
| regionPtr = rootRegionPtr->createSubregion(regionName, regionAttributes); |
| ASSERT(regionPtr != nullptr, "failed to create region."); |
| } |
| std::shared_ptr<Region> CacheHelper::getRegion(const std::string &name) { |
| return cachePtr->getRegion(name); |
| } |
| std::shared_ptr<Region> CacheHelper::createRegion( |
| const std::string &name, bool, bool caching, |
| const std::shared_ptr<CacheListener> &listener, bool, bool, |
| bool concurrencyCheckEnabled, int32_t) { |
| RegionAttributesFactory regionAttributeFactory; |
| regionAttributeFactory.setCachingEnabled(caching); |
| if (listener != nullptr) { |
| regionAttributeFactory.setCacheListener(listener); |
| } |
| if (concurrencyCheckEnabled) { |
| regionAttributeFactory.setConcurrencyChecksEnabled(concurrencyCheckEnabled); |
| } |
| |
| auto regionAttributes = regionAttributeFactory.create(); |
| |
| CacheImpl *cacheImpl = CacheRegionHelper::getCacheImpl(cachePtr.get()); |
| std::shared_ptr<Region> regionPtr; |
| cacheImpl->createRegion(name, regionAttributes, regionPtr); |
| return regionPtr; |
| } |
| std::shared_ptr<Region> CacheHelper::createRegion( |
| const std::string &name, bool, bool caching, |
| const std::chrono::seconds &ettl, const std::chrono::seconds &eit, |
| const std::chrono::seconds &rttl, const std::chrono::seconds &rit, int lel, |
| ExpirationAction action, const std::string &, bool) { |
| RegionAttributesFactory regionAttributeFactory; |
| regionAttributeFactory.setCachingEnabled(caching); |
| regionAttributeFactory.setLruEntriesLimit(lel); |
| regionAttributeFactory.setEntryIdleTimeout(action, eit); |
| regionAttributeFactory.setEntryTimeToLive(action, ettl); |
| regionAttributeFactory.setRegionIdleTimeout(action, rit); |
| regionAttributeFactory.setRegionTimeToLive(action, rttl); |
| |
| auto regionAttributes = regionAttributeFactory.create(); |
| |
| CacheImpl *cacheImpl = CacheRegionHelper::getCacheImpl(cachePtr.get()); |
| std::shared_ptr<Region> regionPtr; |
| cacheImpl->createRegion(name, regionAttributes, regionPtr); |
| return regionPtr; |
| } |
| std::shared_ptr<Pool> CacheHelper::createPool( |
| const std::string &poolName, const std::string &locators, |
| const std::string &serverGroup, int redundancy, bool clientNotification, |
| std::chrono::milliseconds subscriptionAckInterval, int connections, |
| int loadConditioningInterval, bool isMultiuserMode) { |
| auto poolFac = getCache()->getPoolManager().createFactory(); |
| |
| addServerLocatorEPs(locators, poolFac); |
| if (!serverGroup.empty()) { |
| poolFac.setServerGroup(serverGroup); |
| } |
| |
| poolFac.setSubscriptionRedundancy(redundancy); |
| poolFac.setSubscriptionEnabled(clientNotification); |
| poolFac.setMultiuserAuthentication(isMultiuserMode); |
| // poolFac.setStatisticInterval(1000); |
| if (loadConditioningInterval > 0) { |
| poolFac.setLoadConditioningInterval( |
| std::chrono::milliseconds(loadConditioningInterval)); |
| } |
| |
| if (connections >= 0) { |
| poolFac.setMinConnections(connections); |
| poolFac.setMaxConnections(connections); |
| } |
| if (subscriptionAckInterval > std::chrono::milliseconds::zero()) { |
| poolFac.setSubscriptionAckInterval(subscriptionAckInterval); |
| } |
| |
| return poolFac.create(poolName); |
| } |
| |
| // this will create pool even endpoints and locatorhost has been not defined |
| std::shared_ptr<Pool> CacheHelper::createPool2( |
| const std::string &poolName, const std::string &locators, |
| const std::string &serverGroup, const std::string &servers, int redundancy, |
| bool clientNotification, int subscriptionAckInterval, int connections) { |
| auto poolFac = getCache()->getPoolManager().createFactory(); |
| |
| if (!servers.empty()) { |
| addServerLocatorEPs(servers, poolFac, false); |
| // do region creation with end |
| } else if (!locators.empty()) { |
| addServerLocatorEPs(locators, poolFac); |
| if (!serverGroup.empty()) { |
| poolFac.setServerGroup(serverGroup); |
| } |
| } |
| |
| poolFac.setSubscriptionRedundancy(redundancy); |
| poolFac.setSubscriptionEnabled(clientNotification); |
| if (connections >= 0) { |
| poolFac.setMinConnections(connections); |
| poolFac.setMaxConnections(connections); |
| } |
| if (subscriptionAckInterval != -1) { |
| poolFac.setSubscriptionAckInterval( |
| std::chrono::milliseconds(subscriptionAckInterval)); |
| } |
| |
| return poolFac.create(poolName); |
| } |
| |
| void CacheHelper::logPoolAttributes(std::shared_ptr<Pool> &pool) { |
| using apache::geode::internal::chrono::duration::to_string; |
| |
| LOG("logPoolAttributes() entered"); |
| LOGINFO("CPPTEST: Pool attributes for pool %s are as follows" + |
| pool->getName()); |
| LOGINFO("getFreeConnectionTimeout: " + |
| to_string(pool->getFreeConnectionTimeout())); |
| LOGINFO("getLoadConditioningInterval: " + |
| to_string(pool->getLoadConditioningInterval())); |
| LOGINFO("getSocketBufferSize: %d", pool->getSocketBufferSize()); |
| LOGINFO("getReadTimeout: " + to_string(pool->getReadTimeout())); |
| LOGINFO("getMinConnections: %d", pool->getMinConnections()); |
| LOGINFO("getMaxConnections: %d", pool->getMaxConnections()); |
| LOGINFO("getIdleTimeout: " + to_string(pool->getIdleTimeout())); |
| LOGINFO("getPingInterval: " + to_string(pool->getPingInterval())); |
| LOGINFO("getStatisticInterval: " + to_string(pool->getStatisticInterval())); |
| LOGINFO("getRetryAttempts: %d", pool->getRetryAttempts()); |
| LOGINFO("getSubscriptionEnabled: %s", |
| pool->getSubscriptionEnabled() ? "true" : "false"); |
| LOGINFO("getSubscriptionRedundancy: %d", pool->getSubscriptionRedundancy()); |
| LOGINFO("getSubscriptionMessageTrackingTimeout: " + |
| to_string(pool->getSubscriptionMessageTrackingTimeout())); |
| LOGINFO("getSubscriptionAckInterval: " + |
| to_string(pool->getSubscriptionAckInterval())); |
| LOGINFO("getServerGroup: " + pool->getServerGroup()); |
| LOGINFO("getThreadLocalConnections: %s", |
| pool->getThreadLocalConnections() ? "true" : "false"); |
| LOGINFO("getPRSingleHopEnabled: %s", |
| pool->getPRSingleHopEnabled() ? "true" : "false"); |
| } |
| |
| void CacheHelper::createPoolWithLocators( |
| const std::string &name, const std::string &locators, |
| bool clientNotificationEnabled, int subscriptionRedundancy, |
| std::chrono::milliseconds subscriptionAckInterval, int connections, |
| bool isMultiuserMode, const std::string &serverGroup) { |
| LOG("createPool() entered."); |
| std::cout << " in createPoolWithLocators isMultiuserMode = " |
| << isMultiuserMode << "\n"; |
| auto poolPtr = createPool(name, locators, serverGroup, subscriptionRedundancy, |
| clientNotificationEnabled, subscriptionAckInterval, |
| connections, -1, isMultiuserMode); |
| ASSERT(poolPtr != nullptr, "Failed to create pool."); |
| logPoolAttributes(poolPtr); |
| LOG("Pool created."); |
| } |
| std::shared_ptr<Region> CacheHelper::createRegionAndAttachPool( |
| const std::string &name, bool, const std::string &poolName, bool caching, |
| const std::chrono::seconds &ettl, const std::chrono::seconds &eit, |
| const std::chrono::seconds &rttl, const std::chrono::seconds &rit, int lel, |
| ExpirationAction action) { |
| RegionShortcut preDefRA = RegionShortcut::PROXY; |
| if (caching) { |
| preDefRA = RegionShortcut::CACHING_PROXY; |
| } |
| if (lel > 0) { |
| preDefRA = RegionShortcut::CACHING_PROXY_ENTRY_LRU; |
| } |
| auto regionFactory = cachePtr->createRegionFactory(preDefRA); |
| regionFactory.setLruEntriesLimit(lel); |
| regionFactory.setEntryIdleTimeout(action, eit); |
| regionFactory.setEntryTimeToLive(action, ettl); |
| regionFactory.setRegionIdleTimeout(action, rit); |
| regionFactory.setRegionTimeToLive(action, rttl); |
| if (!poolName.empty()) { |
| regionFactory.setPoolName(poolName); |
| } |
| return regionFactory.create(name); |
| } |
| std::shared_ptr<Region> CacheHelper::createRegionAndAttachPool2( |
| const char *name, bool, const char *poolName, |
| const std::shared_ptr<PartitionResolver> &aResolver, bool caching, |
| const std::chrono::seconds &ettl, const std::chrono::seconds &eit, |
| const std::chrono::seconds &rttl, const std::chrono::seconds &rit, int lel, |
| ExpirationAction action) { |
| RegionShortcut preDefRA = RegionShortcut::PROXY; |
| if (caching) { |
| preDefRA = RegionShortcut::CACHING_PROXY; |
| } |
| if (lel > 0) { |
| preDefRA = RegionShortcut::CACHING_PROXY_ENTRY_LRU; |
| } |
| auto regionFactory = cachePtr->createRegionFactory(preDefRA); |
| regionFactory.setLruEntriesLimit(lel); |
| regionFactory.setEntryIdleTimeout(action, eit); |
| regionFactory.setEntryTimeToLive(action, ettl); |
| regionFactory.setRegionIdleTimeout(action, rit); |
| regionFactory.setRegionTimeToLive(action, rttl); |
| regionFactory.setPoolName(poolName); |
| regionFactory.setPartitionResolver(aResolver); |
| return regionFactory.create(name); |
| } |
| |
| void CacheHelper::addServerLocatorEPs(const std::string &epList, |
| PoolFactory &pf, bool poolLocators) { |
| std::unordered_set<std::string> endpointNames; |
| Utils::parseEndpointNamesString(epList, endpointNames); |
| for (const auto &endpointName : endpointNames) { |
| auto position = endpointName.find_first_of(":"); |
| if (position != std::string::npos) { |
| auto hostname = endpointName.substr(0, position); |
| auto portnumber = std::stoi(endpointName.substr(position + 1)); |
| if (poolLocators) { |
| pf.addLocator(hostname, portnumber); |
| } else { |
| pf.addServer(hostname, portnumber); |
| } |
| } |
| } |
| } |
| |
| std::shared_ptr<Region> CacheHelper::createPooledRegion( |
| const std::string &name, bool, const std::string &locators, |
| const std::string &poolName, bool caching, bool clientNotificationEnabled, |
| const std::chrono::seconds &ettl, const std::chrono::seconds &eit, |
| const std::chrono::seconds &rttl, const std::chrono::seconds &rit, int lel, |
| const std::shared_ptr<CacheListener> &cacheListener, |
| ExpirationAction action) { |
| auto poolFac = getCache()->getPoolManager().createFactory(); |
| poolFac.setSubscriptionEnabled(clientNotificationEnabled); |
| |
| if (!locators.empty()) { |
| LOG("adding pool locators"); |
| addServerLocatorEPs(locators, poolFac); |
| } |
| |
| if ((getCache()->getPoolManager().find(poolName)) == |
| nullptr) { // Pool does not exist with the same name. |
| auto pptr = poolFac.create(poolName); |
| } |
| |
| RegionShortcut preDefRA = RegionShortcut::PROXY; |
| if (caching) { |
| preDefRA = RegionShortcut::CACHING_PROXY; |
| } |
| if (lel > 0) { |
| preDefRA = RegionShortcut::CACHING_PROXY_ENTRY_LRU; |
| } |
| auto regionFactory = cachePtr->createRegionFactory(preDefRA); |
| regionFactory.setLruEntriesLimit(lel); |
| regionFactory.setEntryIdleTimeout(action, eit); |
| regionFactory.setEntryTimeToLive(action, ettl); |
| regionFactory.setRegionIdleTimeout(action, rit); |
| regionFactory.setRegionTimeToLive(action, rttl); |
| regionFactory.setPoolName(poolName); |
| if (cacheListener != nullptr) { |
| regionFactory.setCacheListener(cacheListener); |
| } |
| return regionFactory.create(name); |
| } |
| std::shared_ptr<Region> CacheHelper::createPooledRegionConcurrencyCheckDisabled( |
| const std::string &name, bool, const std::string &locators, |
| const std::string &poolName, bool caching, bool clientNotificationEnabled, |
| bool concurrencyCheckEnabled, const std::chrono::seconds &ettl, |
| const std::chrono::seconds &eit, const std::chrono::seconds &rttl, |
| const std::chrono::seconds &rit, int lel, |
| const std::shared_ptr<CacheListener> &cacheListener, |
| ExpirationAction action) { |
| auto poolFac = getCache()->getPoolManager().createFactory(); |
| poolFac.setSubscriptionEnabled(clientNotificationEnabled); |
| |
| LOG("adding pool locators"); |
| addServerLocatorEPs(locators, poolFac); |
| |
| if ((getCache()->getPoolManager().find(poolName)) == |
| nullptr) { // Pool does not exist with the same name. |
| auto pptr = poolFac.create(poolName); |
| } |
| |
| RegionShortcut preDefRA = RegionShortcut::PROXY; |
| if (caching) { |
| preDefRA = RegionShortcut::CACHING_PROXY; |
| } |
| if (lel > 0) { |
| preDefRA = RegionShortcut::CACHING_PROXY_ENTRY_LRU; |
| } |
| auto regionFactory = cachePtr->createRegionFactory(preDefRA); |
| regionFactory.setLruEntriesLimit(lel); |
| regionFactory.setEntryIdleTimeout(action, eit); |
| regionFactory.setEntryTimeToLive(action, ettl); |
| regionFactory.setRegionIdleTimeout(action, rit); |
| regionFactory.setRegionTimeToLive(action, rttl); |
| regionFactory.setConcurrencyChecksEnabled(concurrencyCheckEnabled); |
| regionFactory.setPoolName(poolName); |
| if (cacheListener != nullptr) { |
| regionFactory.setCacheListener(cacheListener); |
| } |
| return regionFactory.create(name); |
| } |
| std::shared_ptr<Region> CacheHelper::createRegionDiscOverFlow( |
| const std::string &name, bool caching, bool, |
| const std::chrono::seconds &ettl, const std::chrono::seconds &eit, |
| const std::chrono::seconds &rttl, const std::chrono::seconds &rit, int lel, |
| ExpirationAction action) { |
| RegionAttributesFactory regionAttributeFactory; |
| regionAttributeFactory.setCachingEnabled(caching); |
| regionAttributeFactory.setLruEntriesLimit(lel); |
| regionAttributeFactory.setEntryIdleTimeout(action, eit); |
| regionAttributeFactory.setEntryTimeToLive(action, ettl); |
| regionAttributeFactory.setRegionIdleTimeout(action, rit); |
| regionAttributeFactory.setRegionTimeToLive(action, rttl); |
| regionAttributeFactory.setCloningEnabled(true); |
| if (lel > 0) { |
| regionAttributeFactory.setDiskPolicy(DiskPolicyType::OVERFLOWS); |
| auto sqLiteProps = Properties::create(); |
| sqLiteProps->insert("PageSize", "65536"); |
| sqLiteProps->insert("MaxPageCount", "1073741823"); |
| std::string sqlite_dir = |
| "SqLiteRegionData" + std::to_string(boost::this_process::get_id()); |
| sqLiteProps->insert("PersistenceDirectory", sqlite_dir.c_str()); |
| regionAttributeFactory.setPersistenceManager( |
| "SqLiteImpl", "createSqLiteInstance", sqLiteProps); |
| } |
| |
| auto regionAttributes = regionAttributeFactory.create(); |
| CacheImpl *cacheImpl = CacheRegionHelper::getCacheImpl(cachePtr.get()); |
| std::shared_ptr<Region> regionPtr; |
| cacheImpl->createRegion(name, regionAttributes, regionPtr); |
| return regionPtr; |
| } |
| std::shared_ptr<Region> CacheHelper::createPooledRegionDiscOverFlow( |
| const std::string &name, bool, const std::string &locators, |
| const std::string &poolName, bool caching, bool clientNotificationEnabled, |
| const std::chrono::seconds &ettl, const std::chrono::seconds &eit, |
| const std::chrono::seconds &rttl, const std::chrono::seconds &rit, int lel, |
| const std::shared_ptr<CacheListener> &cacheListener, |
| ExpirationAction action) { |
| auto poolFac = getCache()->getPoolManager().createFactory(); |
| poolFac.setSubscriptionEnabled(clientNotificationEnabled); |
| |
| if (!locators.empty()) // with locator |
| { |
| LOG("adding pool locators"); |
| addServerLocatorEPs(locators, poolFac); |
| } |
| if ((getCache()->getPoolManager().find(poolName)) == |
| nullptr) { // Pool does not exist with the same name. |
| auto pptr = poolFac.create(poolName); |
| } |
| |
| if (!caching) { |
| LOG("createPooledRegionDiscOverFlow: setting caching=false does not make " |
| "sense"); |
| FAIL( |
| "createPooledRegionDiscOverFlow: setting caching=false does not make " |
| "sense"); |
| } |
| RegionShortcut preDefRA = RegionShortcut::CACHING_PROXY; |
| if (lel > 0) { |
| preDefRA = RegionShortcut::CACHING_PROXY_ENTRY_LRU; |
| } |
| auto regionFactory = cachePtr->createRegionFactory(preDefRA); |
| regionFactory.setLruEntriesLimit(lel); |
| regionFactory.setEntryIdleTimeout(action, eit); |
| regionFactory.setEntryTimeToLive(action, ettl); |
| regionFactory.setRegionIdleTimeout(action, rit); |
| regionFactory.setRegionTimeToLive(action, rttl); |
| regionFactory.setPoolName(poolName); |
| regionFactory.setCloningEnabled(true); |
| if (lel > 0) { |
| regionFactory.setDiskPolicy(DiskPolicyType::OVERFLOWS); |
| auto sqLiteProps = Properties::create(); |
| sqLiteProps->insert("PageSize", "65536"); |
| sqLiteProps->insert("MaxPageCount", "1073741823"); |
| std::string sqlite_dir = |
| "SqLiteRegionData" + std::to_string(boost::this_process::get_id()); |
| sqLiteProps->insert("PersistenceDirectory", sqlite_dir.c_str()); |
| regionFactory.setPersistenceManager("SqLiteImpl", "createSqLiteInstance", |
| sqLiteProps); |
| } |
| if (cacheListener != nullptr) { |
| regionFactory.setCacheListener(cacheListener); |
| } |
| return regionFactory.create(name); |
| } |
| |
| std::shared_ptr<Region> CacheHelper::createPooledRegionSticky( |
| const std::string &name, bool, const std::string &locators, |
| const std::string &poolName, bool caching, bool clientNotificationEnabled, |
| const std::chrono::seconds &ettl, const std::chrono::seconds &eit, |
| const std::chrono::seconds &rttl, const std::chrono::seconds &rit, int lel, |
| const std::shared_ptr<CacheListener> &cacheListener, |
| ExpirationAction action) { |
| auto poolFac = getCache()->getPoolManager().createFactory(); |
| poolFac.setSubscriptionEnabled(clientNotificationEnabled); |
| poolFac.setThreadLocalConnections(true); |
| poolFac.setPRSingleHopEnabled(false); |
| |
| LOG("adding pool locators"); |
| addServerLocatorEPs(locators, poolFac); |
| |
| if ((getCache()->getPoolManager().find(poolName)) == |
| nullptr) { // Pool does not exist with the same name. |
| auto pptr = poolFac.create(poolName); |
| LOG("createPooledRegionSticky logPoolAttributes"); |
| logPoolAttributes(pptr); |
| } |
| |
| RegionShortcut preDefRA = RegionShortcut::PROXY; |
| if (caching) { |
| preDefRA = RegionShortcut::CACHING_PROXY; |
| } |
| if (lel > 0) { |
| preDefRA = RegionShortcut::CACHING_PROXY_ENTRY_LRU; |
| } |
| auto regionFactory = cachePtr->createRegionFactory(preDefRA); |
| regionFactory.setLruEntriesLimit(lel); |
| regionFactory.setEntryIdleTimeout(action, eit); |
| regionFactory.setEntryTimeToLive(action, ettl); |
| regionFactory.setRegionIdleTimeout(action, rit); |
| regionFactory.setRegionTimeToLive(action, rttl); |
| regionFactory.setPoolName(poolName); |
| if (cacheListener != nullptr) { |
| regionFactory.setCacheListener(cacheListener); |
| } |
| return regionFactory.create(name); |
| } |
| std::shared_ptr<Region> CacheHelper::createPooledRegionStickySingleHop( |
| const std::string &name, bool, const std::string &locators, |
| const std::string &poolName, bool caching, bool clientNotificationEnabled, |
| const std::chrono::seconds &ettl, const std::chrono::seconds &eit, |
| const std::chrono::seconds &rttl, const std::chrono::seconds &rit, int lel, |
| const std::shared_ptr<CacheListener> &cacheListener, |
| ExpirationAction action) { |
| LOG("createPooledRegionStickySingleHop"); |
| auto poolFac = getCache()->getPoolManager().createFactory(); |
| poolFac.setSubscriptionEnabled(clientNotificationEnabled); |
| poolFac.setThreadLocalConnections(true); |
| poolFac.setPRSingleHopEnabled(true); |
| LOG("adding pool locators"); |
| addServerLocatorEPs(locators, poolFac); |
| |
| if ((getCache()->getPoolManager().find(poolName)) == |
| nullptr) { // Pool does not exist with the same name. |
| auto pptr = poolFac.create(poolName); |
| LOG("createPooledRegionStickySingleHop logPoolAttributes"); |
| logPoolAttributes(pptr); |
| } |
| |
| RegionShortcut preDefRA = RegionShortcut::PROXY; |
| if (caching) { |
| preDefRA = RegionShortcut::CACHING_PROXY; |
| } |
| if (lel > 0) { |
| preDefRA = RegionShortcut::CACHING_PROXY_ENTRY_LRU; |
| } |
| auto regionFactory = cachePtr->createRegionFactory(preDefRA); |
| regionFactory.setLruEntriesLimit(lel); |
| regionFactory.setEntryIdleTimeout(action, eit); |
| regionFactory.setEntryTimeToLive(action, ettl); |
| regionFactory.setRegionIdleTimeout(action, rit); |
| regionFactory.setRegionTimeToLive(action, rttl); |
| regionFactory.setPoolName(poolName); |
| if (cacheListener != nullptr) { |
| regionFactory.setCacheListener(cacheListener); |
| } |
| return regionFactory.create(name); |
| } |
| std::shared_ptr<Region> CacheHelper::createSubregion( |
| std::shared_ptr<Region> &parent, const char *name, bool, bool caching, |
| const std::shared_ptr<CacheListener> &listener) { |
| RegionAttributesFactory regionAttributeFactory; |
| regionAttributeFactory.setCachingEnabled(caching); |
| if (listener != nullptr) { |
| regionAttributeFactory.setCacheListener(listener); |
| } |
| auto regionAttributes = regionAttributeFactory.create(); |
| |
| return parent->createSubregion(name, regionAttributes); |
| } |
| std::shared_ptr<CacheableString> CacheHelper::createCacheable( |
| const char *value) { |
| return CacheableString::create(value); |
| } |
| |
| void CacheHelper::showKeys( |
| std::vector<std::shared_ptr<CacheableKey>> &vecKeys) { |
| std::cout << "vecKeys.size() = " << vecKeys.size() << "\n"; |
| for (size_t i = 0; i < vecKeys.size(); i++) { |
| std::cout << "key[" << i << "] -" << vecKeys.at(i)->toString() << "\n"; |
| } |
| std::cout << std::flush; |
| } |
| |
| void CacheHelper::showRegionAttributes(RegionAttributes attributes) { |
| std::cout << "caching=" << (attributes.getCachingEnabled() ? "true" : "false") |
| << "\n"; |
| std::cout << "Entry Time To Live = " |
| << to_string(attributes.getEntryTimeToLive()) << "\n"; |
| std::cout << "Entry Idle Timeout = " |
| << to_string(attributes.getEntryIdleTimeout()) << "\n"; |
| std::cout << "Region Time To Live = " |
| << to_string(attributes.getRegionTimeToLive()) << "\n"; |
| std::cout << "Region Idle Timeout = " |
| << to_string(attributes.getRegionIdleTimeout()) << "\n"; |
| std::cout << "Initial Capacity = " << attributes.getInitialCapacity() << "\n"; |
| std::cout << "Load Factor = " << attributes.getLoadFactor() << "\n"; |
| std::cout << "End Points = " << attributes.getEndpoints() << "\n"; |
| } |
| |
| std::shared_ptr<QueryService> CacheHelper::getQueryService() { |
| return cachePtr->getQueryService(); |
| } |
| |
| const std::string CacheHelper::getTcrEndpoints(bool &isLocalServer, |
| int numberOfServers) { |
| static bool gflocalserver = false; |
| static const auto gfjavaenv = Utils::getEnv("GFJAVA"); |
| |
| ASSERT(!gfjavaenv.empty(), |
| "Environment variable GFJAVA for java build directory is not set."); |
| |
| std::string gfendpoints; |
| if (gfjavaenv.find(PATH_SEP) != std::string::npos) { |
| gflocalserver = true; |
| /* Support for multiple servers Max = 10*/ |
| switch (numberOfServers) { |
| case 1: |
| // gfendpoints = "localhost:24680"; |
| { |
| gfendpoints = "localhost:"; |
| gfendpoints += std::to_string(CacheHelper::staticHostPort1); |
| } |
| break; |
| case 2: |
| // gfendpoints = "localhost:24680,localhost:24681"; |
| { |
| gfendpoints = "localhost:"; |
| gfendpoints += std::to_string(CacheHelper::staticHostPort1); |
| gfendpoints += ",localhost:"; |
| gfendpoints += std::to_string(CacheHelper::staticHostPort2); |
| } |
| break; |
| case 3: |
| // gfendpoints = "localhost:24680,localhost:24681,localhost:24682"; |
| { |
| gfendpoints = "localhost:"; |
| gfendpoints += std::to_string(CacheHelper::staticHostPort1); |
| gfendpoints += ",localhost:"; |
| gfendpoints += std::to_string(CacheHelper::staticHostPort2); |
| gfendpoints += ",localhost:"; |
| gfendpoints += std::to_string(CacheHelper::staticHostPort3); |
| } |
| break; |
| default: |
| // ASSERT( ( numberOfServers <= 10 )," More than 10 servers not |
| // supported"); |
| // TODO: need to support more servers, need to generate random ports |
| // here |
| ASSERT((numberOfServers <= 4), " More than 4 servers not supported"); |
| gfendpoints = "localhost:"; |
| gfendpoints += std::to_string(CacheHelper::staticHostPort1); |
| gfendpoints += ",localhost:"; |
| gfendpoints += std::to_string(CacheHelper::staticHostPort2); |
| gfendpoints += ",localhost:"; |
| gfendpoints += std::to_string(CacheHelper::staticHostPort3); |
| gfendpoints += ",localhost:"; |
| gfendpoints += std::to_string(CacheHelper::staticHostPort4); |
| break; |
| } |
| } else { |
| gfendpoints = gfjavaenv; |
| } |
| |
| isLocalServer = gflocalserver; |
| std::cout << "getHostPort :: " << gfendpoints << "\n"; |
| |
| return gfendpoints; |
| } |
| |
| std::string CacheHelper::getstaticLocatorHostPort1() { |
| return getLocatorHostPort(staticLocatorHostPort1); |
| } |
| |
| std::string CacheHelper::getstaticLocatorHostPort2() { |
| return getLocatorHostPort(staticLocatorHostPort2); |
| } |
| |
| std::string CacheHelper::getLocatorHostPort(int locPort) { |
| return "localhost:" + std::to_string(locPort); |
| } |
| |
| std::string CacheHelper::getLocatorHostPort(bool &isLocator, |
| bool &isLocalServer, |
| int numberOfLocators) { |
| static const auto gfjavaenv = Utils::getEnv("GFJAVA"); |
| static bool gflocator = false; |
| static bool gflocalserver = false; |
| |
| ASSERT(!gfjavaenv.empty(), |
| "Environment variable GFJAVA for java build directory is not set."); |
| |
| std::string gflchostport; |
| if (gfjavaenv.find(PATH_SEP) != std::string::npos) { |
| gflocator = true; |
| gflocalserver = true; |
| switch (numberOfLocators) { |
| case 1: |
| // gflchostport = "localhost:34756"; |
| { |
| gflchostport = "localhost:"; |
| gflchostport += std::to_string(CacheHelper::staticLocatorHostPort1); |
| } |
| break; |
| case 2: |
| // gflchostport = "localhost:34756,localhost:34757"; |
| { |
| gflchostport = "localhost:"; |
| gflchostport += std::to_string(CacheHelper::staticLocatorHostPort1); |
| gflchostport += ",localhost:"; |
| gflchostport += std::to_string(CacheHelper::staticLocatorHostPort2); |
| } |
| break; |
| default: |
| // gflchostport = "localhost:34756,localhost:34757,localhost:34758"; |
| { |
| gflchostport = "localhost:"; |
| gflchostport += std::to_string(CacheHelper::staticLocatorHostPort1); |
| gflchostport += ",localhost:"; |
| gflchostport += std::to_string(CacheHelper::staticLocatorHostPort2); |
| gflchostport += ",localhost:"; |
| gflchostport += std::to_string(CacheHelper::staticLocatorHostPort3); |
| } |
| break; |
| } |
| } |
| |
| isLocator = gflocator; |
| isLocalServer = gflocalserver; |
| std::cout << "getLocatorHostPort :: " << gflchostport << "\n"; |
| |
| return gflchostport; |
| } |
| |
| void CacheHelper::cleanupServerInstances() { |
| CacheHelper::cleanupTmpConfigFiles(); |
| if (staticServerInstanceList.size() > 0) { |
| while (staticServerInstanceList.size() > 0) { |
| int instance = staticServerInstanceList.front(); |
| |
| staticServerInstanceList.remove(instance); // for safety |
| closeServer(instance); |
| } |
| } |
| } |
| void CacheHelper::initServer(int instance, const std::string &xml, |
| const std::string &locHostport, |
| const char * /*unused*/, bool ssl, |
| bool enableDelta, bool, bool testServerGC, |
| bool untrustedCert, bool useSecurityManager) { |
| if (!isServerCleanupCallbackRegistered) { |
| isServerCleanupCallbackRegistered = true; |
| gClientCleanup.registerCallback( |
| []() { CacheHelper::cleanupServerInstances(); }); |
| |
| std::cout << "TimeBomb registered server cleanupcallback \n"; |
| } |
| |
| std::cout << "Inside initServer added\n"; |
| |
| static const auto gfjavaenv = Utils::getEnv("GFJAVA"); |
| static auto gfLogLevel = Utils::getEnv("GFE_LOGLEVEL"); |
| static auto gfSecLogLevel = Utils::getEnv("GFE_SECLOGLEVEL"); |
| static const auto path = Utils::getEnv("TESTSRC"); |
| static const auto classpath = Utils::getEnv("GF_CLASSPATH"); |
| |
| int portNum = 0; |
| std::string currDir = boost::filesystem::current_path().string(); |
| |
| ASSERT(!gfjavaenv.empty(), |
| "Environment variable GFJAVA for java build directory is not set."); |
| ASSERT(!path.empty(), |
| "Environment variable TESTSRC for test source directory is not set."); |
| |
| if (gfLogLevel.empty()) { |
| gfLogLevel = "config"; |
| } |
| |
| if (gfSecLogLevel.empty()) { |
| gfSecLogLevel = "config"; |
| } |
| |
| if (gfjavaenv.find(PATH_SEP) == std::string::npos) { |
| return; |
| } |
| |
| std::string xmlFile = ""; |
| std::string sname = "GFECS"; |
| currDir += PATH_SEP; |
| |
| switch (instance) { |
| case 0: |
| // note: this need to take for multiple tests run |
| xmlFile += "cacheserver.xml"; |
| break; |
| case 1: |
| xmlFile += "cacheserver.xml"; |
| portNum = CacheHelper::staticHostPort1; |
| break; |
| case 2: |
| xmlFile += "cacheserver2.xml"; |
| portNum = CacheHelper::staticHostPort2; |
| break; |
| case 3: |
| xmlFile += "cacheserver3.xml"; |
| portNum = CacheHelper::staticHostPort3; |
| break; |
| case 4: |
| xmlFile += "cacheserver4.xml"; |
| portNum = CacheHelper::staticHostPort4; |
| break; |
| default: /* Support for any number of servers Max 10*/ |
| ASSERT((instance <= 10), " More than 10 servers not supported"); |
| ASSERT(!xml.empty(), |
| "xml == nullptr : For server instance > 3 xml file is must"); |
| portNum = CacheHelper::staticHostPort4; |
| break; |
| } |
| |
| sname += std::to_string(portNum); |
| currDir += sname; |
| |
| if (!xml.empty()) { |
| xmlFile = xml; |
| } |
| |
| std::string xmlFile_new; |
| std::cout << " xml file name = " << xmlFile << "\n"; |
| xmlFile = CacheHelper::createDuplicateXMLFile(xmlFile); |
| |
| std::cout << " creating dir = " << sname << "\n"; |
| boost::filesystem::create_directory(sname); |
| |
| int64_t defaultTombstone_timeout = 600000; |
| int64_t defaultTombstone_gc_threshold = 100000; |
| int64_t userTombstone_timeout = 1000; |
| int64_t userTombstone_gc_threshold = 10; |
| if (testServerGC) { |
| boost::filesystem::create_directory("backupDirectory1"); |
| boost::filesystem::create_directory("backupDirectory2"); |
| boost::filesystem::create_directory("backupDirectory3"); |
| boost::filesystem::create_directory("backupDirectory4"); |
| } |
| |
| GfshExecute gfsh; |
| auto server = |
| gfsh.start() |
| .server() |
| .withClasspath(classpath) |
| .withName(sname) |
| .withCacheXMLFile(xmlFile) |
| .withDir(currDir) |
| .withPort(portNum) |
| .withLogLevel(gfLogLevel) |
| .withMaxHeap("1g") |
| .withSystemProperty( |
| "gemfire.tombstone-timeout", |
| std::to_string(testServerGC ? userTombstone_timeout |
| : defaultTombstone_timeout)) |
| .withSystemProperty( |
| "gemfire.tombstone-gc-threshold", |
| std::to_string(testServerGC ? userTombstone_gc_threshold |
| : defaultTombstone_gc_threshold)) |
| .withSystemProperty("gemfire.security-log-level", gfSecLogLevel); |
| |
| if (useSecurityManager) { |
| server.withUser("root").withPassword("root-password"); |
| } |
| |
| if (!locHostport.empty()) { |
| server.withPropertiesFile(generateGeodeProperties( |
| currDir, ssl, -1, 0, untrustedCert, useSecurityManager)); |
| } |
| |
| if (!enableDelta) { |
| server.withSystemProperty("gemfire.delta-propagation", "false"); |
| } |
| |
| server.execute(); |
| |
| staticServerInstanceList.push_back(instance); |
| std::cout << "added server instance " << instance << "\n"; |
| } |
| |
| std::string CacheHelper::createDuplicateXMLFile(const std::string &source, |
| int hostport1, int hostport2, |
| int locport1, int locport2) { |
| std::string dest = boost::filesystem::current_path().string(); |
| dest += PATH_SEP; |
| dest += boost::filesystem::path{source}.filename().stem().string(); |
| dest += '.'; |
| dest += std::to_string(hostport1); |
| dest += ".xml"; |
| |
| std::string src = Utils::getEnv("TESTSRC"); |
| src += PATH_SEP; |
| src += "resources"; |
| src += PATH_SEP; |
| src += source; |
| |
| replacePortsInFile(hostport1, hostport2, CacheHelper::staticHostPort3, |
| CacheHelper::staticHostPort4, locport1, locport2, src, |
| dest); |
| |
| CacheHelper::staticConfigFileList.push_back(dest); |
| std::cout << "createDuplicateXMLFile added file " << dest.c_str() << " " |
| << CacheHelper::staticConfigFileList.size() << "\n"; |
| |
| return dest; |
| } |
| |
| // Need to avoid regex usage in Solaris Studio 12.4. |
| #ifdef _SOLARIS |
| // @Solaris 12.4 compiler is missing support for C++11 regex |
| void CacheHelper::replacePortsInFile(int hostPort1, int hostPort2, |
| int hostPort3, int hostPort4, int locPort1, |
| int locPort2, const std::string &inFile, |
| const std::string &outFile) { |
| std::ifstream in(inFile, std::ios::in | std::ios::binary); |
| if (in) { |
| std::string contents; |
| contents.assign(std::istreambuf_iterator<char>(in), |
| std::istreambuf_iterator<char>()); |
| in.close(); |
| |
| replaceInPlace(contents, "HOST_PORT1", std::to_string(hostPort1)); |
| replaceInPlace(contents, "HOST_PORT2", std::to_string(hostPort2)); |
| replaceInPlace(contents, "HOST_PORT3", std::to_string(hostPort3)); |
| replaceInPlace(contents, "HOST_PORT4", std::to_string(hostPort4)); |
| replaceInPlace(contents, "LOC_PORT1", std::to_string(locPort1)); |
| replaceInPlace(contents, "LOC_PORT2", std::to_string(locPort2)); |
| |
| std::ofstream out(outFile, std::ios::out); |
| out << contents; |
| out.close(); |
| } |
| } |
| |
| void CacheHelper::replaceInPlace(std::string &searchStr, |
| const std::string &matchStr, |
| const std::string &replaceStr) { |
| size_t pos = 0; |
| while ((pos = searchStr.find(matchStr, pos)) != std::string::npos) { |
| searchStr.replace(pos, matchStr.length(), replaceStr); |
| pos += replaceStr.length(); |
| } |
| } |
| #else |
| void CacheHelper::replacePortsInFile(int hostPort1, int hostPort2, |
| int hostPort3, int hostPort4, int locPort1, |
| int locPort2, const std::string &inFile, |
| const std::string &outFile) { |
| std::ifstream in(inFile, std::ios::in); |
| if (in) { |
| std::string contents; |
| contents.assign(std::istreambuf_iterator<char>(in), |
| std::istreambuf_iterator<char>()); |
| in.close(); |
| |
| contents = boost::regex_replace(contents, boost::regex("HOST_PORT1"), |
| std::to_string(hostPort1)); |
| contents = boost::regex_replace(contents, boost::regex("HOST_PORT2"), |
| std::to_string(hostPort2)); |
| contents = boost::regex_replace(contents, boost::regex("HOST_PORT3"), |
| std::to_string(hostPort3)); |
| contents = boost::regex_replace(contents, boost::regex("HOST_PORT4"), |
| std::to_string(hostPort4)); |
| contents = boost::regex_replace(contents, boost::regex("LOC_PORT1"), |
| std::to_string(locPort1)); |
| contents = boost::regex_replace(contents, boost::regex("LOC_PORT2"), |
| std::to_string(locPort2)); |
| |
| std::ofstream out(outFile, std::ios::out); |
| out << contents; |
| out.close(); |
| } |
| } |
| #endif |
| |
| std::string CacheHelper::createDuplicateXMLFile(const std::string &source) { |
| return CacheHelper::createDuplicateXMLFile( |
| source, CacheHelper::staticHostPort1, CacheHelper::staticHostPort2, |
| CacheHelper::staticLocatorHostPort1, CacheHelper::staticLocatorHostPort2); |
| } |
| |
| void CacheHelper::closeServer(int instance) { |
| static const auto gfjavaenv = Utils::getEnv("GFJAVA"); |
| std::string currDir = boost::filesystem::current_path().string(); |
| |
| ASSERT(!gfjavaenv.empty(), |
| "Environment variable GFJAVA for java build directory is not set."); |
| ASSERT(!currDir.empty(), |
| "Current working directory could not be determined."); |
| |
| if (gfjavaenv.find(PATH_SEP) == std::string::npos) { |
| return; |
| } |
| |
| currDir += "/GFECS"; |
| switch (instance) { |
| case 0: |
| currDir += "0"; |
| break; |
| case 1: |
| currDir += std::to_string(CacheHelper::staticHostPort1); |
| break; |
| case 2: |
| currDir += std::to_string(CacheHelper::staticHostPort2); |
| break; |
| case 3: |
| currDir += std::to_string(CacheHelper::staticHostPort3); |
| break; |
| default: /* Support for any number of servers Max 10*/ |
| // ASSERT( ( instance <= 10 )," More than 10 servers not supported"); |
| // TODO: need to support more then three servers |
| ASSERT((instance <= 4), " More than 4 servers not supported"); |
| currDir += std::to_string(CacheHelper::staticHostPort4); |
| break; |
| } |
| |
| try { |
| GfshExecute gfsh; |
| gfsh.stop().server().withDir(currDir).execute(); |
| } catch (const GfshExecuteException &) { |
| } |
| |
| terminate_process_file(currDir + "/vf.gf.server.pid", |
| std::chrono::seconds(10)); |
| |
| staticServerInstanceList.remove(instance); |
| } |
| // closing locator |
| void CacheHelper::closeLocator(int instance, bool) { |
| static const auto gfjavaenv = Utils::getEnv("GFJAVA"); |
| static const auto testsrcenv = Utils::getEnv("TESTSRC"); |
| |
| auto currDir = boost::filesystem::current_path().string(); |
| |
| ASSERT(!gfjavaenv.empty(), |
| "Environment variable GFJAVA for java build directory is not set."); |
| ASSERT(!testsrcenv.empty(), |
| "Environment variable TESTSRC for test source directory is not set."); |
| |
| std::string keystore = testsrcenv + "/keystore"; |
| if (gfjavaenv.find(PATH_SEP) == std::string::npos) { |
| return; |
| } |
| |
| currDir += PATH_SEP; |
| currDir += "GFELOC"; |
| |
| switch (instance) { |
| case 1: |
| currDir += std::to_string(CacheHelper::staticLocatorHostPort1); |
| break; |
| case 2: |
| currDir += std::to_string(CacheHelper::staticLocatorHostPort2); |
| break; |
| case 3: |
| currDir += std::to_string(CacheHelper::staticLocatorHostPort3); |
| break; |
| default: /* Support for any number of Locator Max 10*/ |
| // TODO:// |
| ASSERT((instance <= 3), " More than 3 servers not supported"); |
| currDir += std::to_string(instance); |
| break; |
| } |
| |
| try { |
| GfshExecute gfsh; |
| gfsh.stop().locator().withDir(currDir).execute(); |
| } catch (const GfshExecuteException &) { |
| } |
| |
| terminate_process_file(currDir + "/vf.gf.locator.pid", |
| std::chrono::seconds(10)); |
| |
| std::remove("test.geode.properties"); |
| staticLocatorInstanceList.remove(instance); |
| } |
| |
| template <class Rep, class Period> |
| void CacheHelper::terminate_process_file( |
| const std::string &pidFileName, |
| const std::chrono::duration<Rep, Period> &duration) { |
| auto timeout = std::chrono::system_clock::now() + duration; |
| |
| std::string pid; |
| read_single_line(pidFileName, pid); |
| if (pid.empty()) { |
| return; |
| } |
| |
| LOG("CacheHelper::terminate_process_file: process running. pidFileName=" + |
| pidFileName + ", pid=" + pid); |
| |
| // Wait for process to terminate or timeout |
| auto start = std::chrono::system_clock::now(); |
| while (std::chrono::system_clock::now() < timeout) { |
| if (!file_exists(pidFileName)) { |
| auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>( |
| std::chrono::system_clock::now() - start); |
| LOG("CacheHelper::terminate_process_file: process exited. " |
| "pidFileName=" + |
| pidFileName + ", pid=" + pid + |
| ", elapsed=" + std::to_string(elapsed.count()) + "ms"); |
| return; |
| } |
| std::this_thread::yield(); |
| } |
| LOG("CacheHelper::terminate_process_file: timeout. pidFileName=" + |
| pidFileName + ", pid=" + pid); |
| |
| // Didn't exit on its own, kill it. |
| LOG("terminate_process: pid=" + pid); |
| |
| boost::process::pid_t id = |
| static_cast<boost::process::pid_t>(std::stoul(pid)); |
| boost::process::child process{id}; |
| process.terminate(); |
| } |
| |
| bool CacheHelper::file_exists(const std::string &fileName) { |
| std::ifstream file(fileName); |
| return file.is_open(); |
| } |
| |
| void CacheHelper::read_single_line(const std::string &fileName, |
| std::string &str) { |
| std::ifstream f(fileName); |
| std::getline(f, str); |
| } |
| |
| void CacheHelper::cleanupTmpConfigFiles() { |
| for (auto its = CacheHelper::staticConfigFileList.begin(); |
| its != CacheHelper::staticConfigFileList.end(); ++its) { |
| try { |
| std::remove(its->c_str()); |
| } catch (...) { |
| } |
| } |
| } |
| |
| void CacheHelper::cleanupLocatorInstances() { |
| CacheHelper::cleanupTmpConfigFiles(); |
| if (staticLocatorInstanceList.size() > 0) { |
| while (staticLocatorInstanceList.size() > 0) { |
| int instance = staticLocatorInstanceList.front(); |
| |
| staticLocatorInstanceList.remove(instance); // for safety |
| closeLocator(instance); // this will also remove |
| } |
| } |
| } |
| |
| // starting locator |
| void CacheHelper::initLocator(int instance, bool ssl, bool, int dsId, |
| int remoteLocator, bool untrustedCert, |
| bool useSecurityManager) { |
| static const auto gfjavaenv = Utils::getEnv("GFJAVA"); |
| |
| if (!isLocatorCleanupCallbackRegistered) { |
| isLocatorCleanupCallbackRegistered = true; |
| |
| gClientCleanup.registerCallback( |
| []() { CacheHelper::cleanupLocatorInstances(); }); |
| } |
| |
| std::string currDir = boost::filesystem::current_path().string(); |
| |
| ASSERT(!gfjavaenv.empty(), |
| "Environment variable GFJAVA for java build directory is not set."); |
| |
| if (gfjavaenv.find(PATH_SEP) == std::string::npos) { |
| return; |
| } |
| |
| int portnum = 0; |
| std::string locDirname = "GFELOC"; |
| |
| currDir += PATH_SEP; |
| |
| switch (instance) { |
| case 1: |
| portnum = CacheHelper::staticLocatorHostPort1; |
| break; |
| case 2: |
| portnum = CacheHelper::staticLocatorHostPort2; |
| break; |
| default: |
| portnum = CacheHelper::staticLocatorHostPort3; |
| break; |
| } |
| |
| locDirname += std::to_string(portnum); |
| |
| int jmxManagerPort = CacheHelper::staticJmxManagerPort; |
| |
| currDir += locDirname; |
| boost::filesystem::create_directory(locDirname); |
| |
| std::string geodeFile = generateGeodeProperties( |
| currDir, ssl, dsId, remoteLocator, untrustedCert, useSecurityManager); |
| |
| auto classpath = Utils::getEnv("GF_CLASSPATH"); |
| |
| GfshExecute gfsh; |
| auto locator = gfsh.start() |
| .locator() |
| .withName(locDirname) |
| .withPort(portnum) |
| .withDir(currDir) |
| .withClasspath(classpath) |
| .withHttpServicePort(0) |
| .withJmxManagerPort(jmxManagerPort) |
| .withMaxHeap("256m"); |
| if (useSecurityManager) { |
| locator.withSecurityPropertiesFile(geodeFile); |
| } else { |
| locator.withPropertiesFile(geodeFile); |
| } |
| locator.execute(); |
| |
| staticLocatorInstanceList.push_back(instance); |
| } |
| |
| void CacheHelper::setJavaConnectionPoolSize(uint32_t size) { |
| CacheHelper::getHelper() |
| .getCache() |
| ->getSystemProperties() |
| .setjavaConnectionPoolSize(size); |
| } |
| |
| bool CacheHelper::setSeed() { |
| static const auto testnameenv = Utils::getEnv("TESTNAME"); |
| ASSERT(!testnameenv.empty(), |
| "Environment variable TESTNAME for test name is not set."); |
| |
| int seed = std::hash<std::string>{}(testnameenv); |
| std::cout << "seed for process " << seed << "\n"; |
| // The integration tests rely on the pseudo-random |
| // number generator being seeded with a very particular |
| // value specific to the test by way of the test name. |
| // Whilst this approach is pessimal, it can not be |
| // remedied as the test depend upon it. |
| std::srand(seed); |
| return true; |
| } |
| |
| int CacheHelper::hashcode(char *str) { |
| if (str == nullptr) { |
| return 0; |
| } |
| int localHash = 0; |
| |
| int prime = 31; |
| char *data = str; |
| for (int i = 0; i < 50 && (data[i] != '\0'); i++) { |
| localHash = prime * localHash + data[i]; |
| } |
| if (localHash > 0) return localHash; |
| return -1 * localHash; |
| } |
| |
| int CacheHelper::getRandomNumber() { |
| return (std::rand() % RANDOM_NUMBER_DIVIDER) + RANDOM_NUMBER_OFFSET; |
| } |
| |
| int CacheHelper::getRandomAvailablePort() { |
| using boost::asio::io_service; |
| using boost::asio::ip::tcp; |
| namespace bip = boost::asio::ip; |
| |
| io_service service; |
| bip::tcp::acceptor acceptor(service, bip::tcp::v4()); |
| |
| int result = 0; |
| while (result == 0) { |
| uint16_t port = getRandomNumber(); |
| bip::tcp::endpoint ep{bip::address_v4::loopback(), port}; |
| |
| try { |
| acceptor.bind(ep); |
| acceptor.listen(); |
| result = port; |
| } catch (boost::system::system_error &e) { |
| std::clog << "Error: " << e.what() << std::endl; |
| } |
| } |
| |
| return result; |
| } |
| |
| std::string CacheHelper::unitTestOutputFile() { |
| static const auto testnameenv = Utils::getEnv("TESTNAME"); |
| |
| ASSERT(!testnameenv.empty(), |
| "Environment variable TESTNAME for test name is not set."); |
| |
| std::string outputFile = boost::filesystem::current_path().string(); |
| outputFile += PATH_SEP; |
| outputFile += testnameenv; |
| outputFile += ".log"; |
| |
| return outputFile; |
| } |
| |
| int CacheHelper::getNumLocatorListUpdates(const std::string &search) { |
| std::string testFile = CacheHelper::unitTestOutputFile(); |
| |
| std::ifstream file{testFile}; |
| ASSERT(!file.fail(), "Failed to open log file."); |
| |
| std::string line; |
| int numMatched = 0; |
| while (std::getline(file, line)) { |
| if (line.find(search) != std::string::npos) { |
| ++numMatched; |
| } |
| } |
| |
| return numMatched; |
| } |
| |
| std::string CacheHelper::generateGeodeProperties( |
| const std::string &path, const bool ssl, const int dsId, |
| const int remoteLocator, const bool untrustedCert, |
| const bool useSecurityManager) { |
| static const auto testnameenv = Utils::getEnv("TESTNAME"); |
| |
| ASSERT(!testnameenv.empty(), |
| "Environment variable TESTNAME for test name is not set."); |
| |
| std::string keystore = testnameenv + "/keystore"; |
| |
| std::string geodeFile = path; |
| geodeFile += "/test.geode.properties"; |
| |
| std::ofstream file{geodeFile}; |
| |
| file << "locators=localhost[" << CacheHelper::staticLocatorHostPort1 |
| << "],localhost[" << CacheHelper::staticLocatorHostPort2 |
| << "],localhost[" << CacheHelper::staticLocatorHostPort3 << "]" |
| << std::endl; |
| |
| file << "log-level=config" << std::endl; |
| file << "mcast-port=0" << std::endl; |
| file << "enable-network-partition-detection=false" << std::endl; |
| |
| if (useSecurityManager) { |
| file << "security-manager=javaobject.SimpleSecurityManager" << std::endl; |
| } |
| |
| std::string serverKeystore; |
| std::string serverTruststore; |
| std::string password; |
| |
| if (ssl) { |
| if (untrustedCert) { |
| serverKeystore += "untrusted_server_keystore.jks"; |
| serverTruststore += "untrusted_server_truststore.jks"; |
| password += "secret"; |
| } else { |
| serverKeystore += "server_keystore_chained.jks"; |
| serverTruststore += "server_truststore_chained_root.jks"; |
| password += "apachegeode"; |
| } |
| file << "jmx-manager-ssl-enabled=false" << std::endl; |
| file << "cluster-ssl-enabled=true" << std::endl; |
| file << "cluster-ssl-require-authentication=false" << std::endl; |
| file << "cluster-ssl-ciphers=TLS_RSA_WITH_AES_128_CBC_SHA" << std::endl; |
| file << "cluster-ssl-keystore-type=jks" << std::endl; |
| file << "cluster-ssl-keystore=" + keystore + PATH_SEP + serverKeystore |
| << std::endl; |
| file << "cluster-ssl-keystore-password=" + password + "" << std::endl; |
| file << "cluster-ssl-truststore=" + keystore + PATH_SEP + |
| serverTruststore.c_str() + "" |
| << std::endl; |
| file << "cluster-ssl-truststore-password=" + password + "" << std::endl; |
| file << "security-username=xxxx" << std::endl; |
| file << "security-userPassword=yyyy " << std::endl; |
| } |
| |
| file << "distributed-system-id=" << dsId << std::endl; |
| |
| if (remoteLocator != 0) { |
| file << "remote-locators=localhost[" << remoteLocator << "]"; |
| } |
| |
| file.close(); |
| |
| LOG(geodeFile); |
| return geodeFile; |
| } |
| |
| } // namespace client |
| } // namespace geode |
| } // namespace apache |