blob: fda13a39d541e5bb2b0c07e2dc332fcdcbe82f10 [file] [log] [blame]
/*
* 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 <cstdlib>
#include <string>
#include <ace/DLL.h>
#include <ace/OS.h>
#include <geode/CacheableKey.hpp>
#include <geode/ExceptionTypes.hpp>
#include <geode/SystemProperties.hpp>
#include <geode/internal/chrono/duration.hpp>
#include <geode/internal/geode_globals.hpp>
#include "CppCacheLibrary.hpp"
#include "util/Log.hpp"
#if defined(_WIN32)
#include <windows.h>
#else
#include <dlfcn.h>
#endif
namespace {
const char StatisticsSampleInterval[] = "statistic-sample-rate";
const char StatisticsEnabled[] = "statistic-sampling-enabled";
const char StatisticsArchiveFile[] = "statistic-archive-file";
const char LogFilename[] = "log-file";
const char LogLevelProperty[] = "log-level";
const char Name[] = "name";
const char ConnectionPoolSize[] = "connection-pool-size";
const char CacheXMLFile[] = "cache-xml-file";
const char LogFileSizeLimit[] = "log-file-size-limit";
const char LogDiskSpaceLimit[] = "log-disk-space-limit";
const char StatsFileSizeLimit[] = "archive-file-size-limit";
const char StatsDiskSpaceLimit[] = "archive-disk-space-limit";
const char HeapLRULimit[] = "heap-lru-limit";
const char HeapLRUDelta[] = "heap-lru-delta";
const char MaxSocketBufferSize[] = "max-socket-buffer-size";
const char PingInterval[] = "ping-interval";
const char RedundancyMonitorInterval[] = "redundancy-monitor-interval";
const char DisableShufflingEndpoint[] = "disable-shuffling-of-endpoints";
const char NotifyAckInterval[] = "notify-ack-interval";
const char NotifyDupCheckLife[] = "notify-dupcheck-life";
const char DurableClientId[] = "durable-client-id";
const char DurableTimeout[] = "durable-timeout";
const char ConnectTimeout[] = "connect-timeout";
const char ConnectWaitTimeout[] = "connect-wait-timeout";
const char BucketWaitTimeout[] = "bucket-wait-timeout";
const char ConflateEvents[] = "conflate-events";
const char SecurityClientDhAlgo[] = "security-client-dhalgo";
const char SecurityClientKsPath[] = "security-client-kspath";
const char GridClient[] = "grid-client";
const char AutoReadyForEvents[] = "auto-ready-for-events";
const char SslEnabled[] = "ssl-enabled";
const char TimeStatisticsEnabled[] = "enable-time-statistics";
const char SslKeyStore[] = "ssl-keystore";
const char SslTrustStore[] = "ssl-truststore";
const char SslKeystorePassword[] = "ssl-keystore-password";
const char ThreadPoolSize[] = "max-fe-threads";
const char SuspendedTxTimeout[] = "suspended-tx-timeout";
const char EnableChunkHandlerThread[] = "enable-chunk-handler-thread";
const char OnClientDisconnectClearPdxTypeIds[] =
"on-client-disconnect-clear-pdxType-Ids";
const char TombstoneTimeoutInMSec[] = "tombstone-timeout";
const char DefaultConflateEvents[] = "server";
const char DefaultDurableClientId[] = "";
constexpr auto DefaultDurableTimeout = std::chrono::seconds(300);
constexpr auto DefaultConnectTimeout = std::chrono::seconds(59);
constexpr auto DefaultConnectWaitTimeout = std::chrono::seconds::zero();
constexpr auto DefaultBucketWaitTimeout = std::chrono::seconds::zero();
constexpr auto DefaultSamplingInterval = std::chrono::seconds(1);
const bool DefaultSamplingEnabled = true;
const char DefaultStatArchive[] = "statArchive.gfs";
const char DefaultLogFilename[] = ""; // stdout...
const apache::geode::client::LogLevel DefaultLogLevel =
apache::geode::client::LogLevel::Config;
const int DefaultConnectionPoolSize = 5;
const bool DefaultGridClient = false;
const bool DefaultAutoReadyForEvents = true;
const bool DefaultSslEnabled = false;
const bool DefaultTimeStatisticsEnabled = false; // or true;
const char DefaultSslKeyStore[] = "";
const char DefaultSslTrustStore[] = "";
const char DefaultSslKeystorePassword[] = "";
const char DefaultName[] = "";
const char DefaultCacheXMLFile[] = "";
const uint32_t DefaultLogFileSizeLimit = 0; // = unlimited
const uint32_t DefaultLogDiskSpaceLimit = 0; // = unlimited
const uint32_t DefaultStatsFileSizeLimit = 0; // = unlimited
const uint32_t DefaultStatsDiskSpaceLimit = 0; // = unlimited
const size_t DefaultHeapLRULimit = 0; // = unlimited, disabled when it is 0
const int32_t DefaultHeapLRUDelta = 10; // = unlimited, disabled when it is 0
const int32_t DefaultMaxSocketBufferSize = 65 * 1024;
constexpr auto DefaultPingInterval = std::chrono::seconds(10);
constexpr auto DefaultRedundancyMonitorInterval = std::chrono::seconds(10);
constexpr auto DefaultNotifyAckInterval = std::chrono::seconds(1);
constexpr auto DefaultNotifyDupCheckLife = std::chrono::seconds(300);
const char DefaultSecurityPrefix[] = "security-";
const uint32_t DefaultThreadPoolSize = ACE_OS::num_processors() * 2;
constexpr auto DefaultSuspendedTxTimeout = std::chrono::seconds(30);
constexpr auto DefaultTombstoneTimeout = std::chrono::seconds(480);
// not disable; all region api will use chunk handler thread
const bool DefaultEnableChunkHandlerThread = false;
const bool DefaultOnClientDisconnectClearPdxTypeIds = false;
} // namespace
namespace apache {
namespace geode {
namespace client {
namespace impl {
void* getFactoryFunc(const char* lib, const char* funcName);
} // namespace impl
SystemProperties::SystemProperties(
const std::shared_ptr<Properties>& propertiesPtr,
const std::string& configFile)
: m_statisticsSampleInterval(DefaultSamplingInterval),
m_statisticsEnabled(DefaultSamplingEnabled),
m_statisticsArchiveFile(DefaultStatArchive),
m_logFilename(DefaultLogFilename),
m_logLevel(DefaultLogLevel),
m_sessions(0 /* setup later in processProperty */),
m_name(DefaultName),
m_disableShufflingEndpoint(false),
m_cacheXMLFile(DefaultCacheXMLFile),
m_logFileSizeLimit(DefaultLogFileSizeLimit),
m_logDiskSpaceLimit(DefaultLogDiskSpaceLimit),
m_statsFileSizeLimit(DefaultStatsFileSizeLimit),
m_statsDiskSpaceLimit(DefaultStatsDiskSpaceLimit),
m_connectionPoolSize(DefaultConnectionPoolSize),
m_heapLRULimit(DefaultHeapLRULimit),
m_heapLRUDelta(DefaultHeapLRUDelta),
m_maxSocketBufferSize(DefaultMaxSocketBufferSize),
m_pingInterval(DefaultPingInterval),
m_redundancyMonitorInterval(DefaultRedundancyMonitorInterval),
m_notifyAckInterval(DefaultNotifyAckInterval),
m_notifyDupCheckLife(DefaultNotifyDupCheckLife),
m_securityClientDhAlgo(),
m_securityClientKsPath(),
m_durableClientId(DefaultDurableClientId),
m_durableTimeout(DefaultDurableTimeout),
m_connectTimeout(DefaultConnectTimeout),
m_connectWaitTimeout(DefaultConnectWaitTimeout),
m_bucketWaitTimeout(DefaultBucketWaitTimeout),
m_gridClient(DefaultGridClient),
m_autoReadyForEvents(DefaultAutoReadyForEvents),
m_sslEnabled(DefaultSslEnabled),
m_timestatisticsEnabled(DefaultTimeStatisticsEnabled),
m_sslKeyStore(DefaultSslKeyStore),
m_sslTrustStore(DefaultSslTrustStore),
m_sslKeystorePassword(DefaultSslKeystorePassword),
m_conflateEvents(DefaultConflateEvents),
m_threadPoolSize(DefaultThreadPoolSize),
m_suspendedTxTimeout(DefaultSuspendedTxTimeout),
m_tombstoneTimeout(DefaultTombstoneTimeout),
m_enableChunkHandlerThread(DefaultEnableChunkHandlerThread),
m_onClientDisconnectClearPdxTypeIds(
DefaultOnClientDisconnectClearPdxTypeIds) {
// now that defaults are set, consume files and override the defaults.
class ProcessPropsVisitor : public Properties::Visitor {
SystemProperties* m_sysProps;
public:
explicit ProcessPropsVisitor(SystemProperties* sysProps)
: m_sysProps(sysProps) {}
void visit(const std::shared_ptr<CacheableKey>& key,
const std::shared_ptr<Cacheable>& value) {
auto property = key->toString();
std::string val;
if (value != nullptr) {
val = value->toString();
}
m_sysProps->processProperty(property, val);
}
} processPropsVisitor(this);
m_securityPropertiesPtr = Properties::create();
auto givenConfigPtr = Properties::create();
// Load the file from product tree.
try {
std::string defaultSystemProperties =
CppCacheLibrary::getProductDir() + "/defaultSystem/geode.properties";
givenConfigPtr->load(defaultSystemProperties);
} catch (Exception&) {
LOGERROR(
"Unable to determine Product Directory. Please set the "
"GEODE_NATIVE_HOME environment variable.");
throw;
}
// Load the file from current directory.
if (configFile.empty()) {
givenConfigPtr->load("./geode.properties");
} else {
givenConfigPtr->load(configFile);
}
// process each loaded property.
givenConfigPtr->foreach (processPropsVisitor);
// Now consume any properties provided by the Properties object in code.
if (propertiesPtr != nullptr) {
propertiesPtr->foreach (processPropsVisitor);
}
}
SystemProperties::~SystemProperties() {}
void SystemProperties::throwError(const std::string& msg) {
LOGERROR(msg);
throw GeodeConfigException(msg);
}
bool SystemProperties::parseBooleanProperty(const std::string& property,
const std::string& value) {
if (value == "false") {
return false;
} else if (value == "true") {
return true;
}
throwError("SystemProperties: non-boolean " + property + "=" + value);
}
template <class _Rep, class _Period>
void SystemProperties::parseDurationProperty(
const std::string& property, const std::string& value,
std::chrono::duration<_Rep, _Period>& duration) {
using apache::geode::internal::chrono::duration::from_string;
try {
duration = from_string<std::chrono::duration<_Rep, _Period>>(value);
} catch (std::invalid_argument&) {
throwError(("SystemProperties: non-duration " + property + "=" + value));
}
}
void SystemProperties::processProperty(const std::string& property,
const std::string& value) {
if (property.compare(0, sizeof(DefaultSecurityPrefix) - 1,
DefaultSecurityPrefix) == 0) {
m_securityPropertiesPtr->insert(property, value);
if (property == SecurityClientDhAlgo) {
m_securityClientDhAlgo = value;
} else if (property == SecurityClientKsPath) {
m_securityClientKsPath = value;
}
return;
}
if (property == ThreadPoolSize) {
m_threadPoolSize = std::stoul(value);
} else if (property == MaxSocketBufferSize) {
m_maxSocketBufferSize = std::stol(value);
} else if (property == PingInterval) {
parseDurationProperty(property, std::string(value), m_pingInterval);
} else if (property == RedundancyMonitorInterval) {
parseDurationProperty(property, std::string(value),
m_redundancyMonitorInterval);
} else if (property == NotifyAckInterval) {
parseDurationProperty(property, std::string(value), m_notifyAckInterval);
} else if (property == NotifyDupCheckLife) {
parseDurationProperty(property, std::string(value), m_notifyDupCheckLife);
} else if (property == StatisticsSampleInterval) {
parseDurationProperty(property, std::string(value),
m_statisticsSampleInterval);
} else if (property == DurableTimeout) {
parseDurationProperty(property, std::string(value), m_durableTimeout);
} else if (property == ConnectTimeout) {
parseDurationProperty(property, std::string(value), m_connectTimeout);
} else if (property == ConnectWaitTimeout) {
parseDurationProperty(property, std::string(value), m_connectWaitTimeout);
} else if (property == BucketWaitTimeout) {
parseDurationProperty(property, std::string(value), m_bucketWaitTimeout);
} else if (property == DisableShufflingEndpoint) {
m_disableShufflingEndpoint = parseBooleanProperty(property, value);
} else if (property == GridClient) {
m_gridClient = parseBooleanProperty(property, value);
} else if (property == AutoReadyForEvents) {
m_autoReadyForEvents = parseBooleanProperty(property, value);
} else if (property == SslEnabled) {
m_sslEnabled = parseBooleanProperty(property, value);
} else if (property == TimeStatisticsEnabled) {
m_timestatisticsEnabled = parseBooleanProperty(property, value);
} else if (property == StatisticsEnabled) {
m_statisticsEnabled = parseBooleanProperty(property, value);
} else if (property == StatisticsArchiveFile) {
m_statisticsArchiveFile = value;
} else if (property == LogFilename) {
m_logFilename = value;
} else if (property == LogLevelProperty) {
try {
m_logLevel = Log::charsToLevel(value);
} catch (IllegalArgumentException&) {
throwError(
("SystemProperties: unknown log level " + property + "=" + value));
}
} else if (property == ConnectionPoolSize) {
m_connectionPoolSize = std::stol(value);
} else if (property == Name) {
m_name = value;
} else if (property == DurableClientId) {
m_durableClientId = value;
} else if (property == SslKeyStore) {
m_sslKeyStore = value;
} else if (property == SslTrustStore) {
m_sslTrustStore = value;
} else if (property == SslKeystorePassword) {
m_sslKeystorePassword = value;
} else if (property == ConflateEvents) {
m_conflateEvents = value;
} else if (property == CacheXMLFile) {
m_cacheXMLFile = value;
} else if (property == LogFileSizeLimit) {
m_logFileSizeLimit = std::stol(value);
} else if (property == LogDiskSpaceLimit) {
m_logDiskSpaceLimit = std::stol(value);
} else if (property == StatsFileSizeLimit) {
m_statsFileSizeLimit = std::stol(value);
} else if (property == StatsDiskSpaceLimit) {
m_statsDiskSpaceLimit = std::stol(value);
} else if (property == HeapLRULimit) {
m_heapLRULimit = std::stol(value);
} else if (property == HeapLRUDelta) {
m_heapLRUDelta = std::stol(value);
} else if (property == SuspendedTxTimeout) {
parseDurationProperty(property, std::string(value), m_suspendedTxTimeout);
} else if (property == TombstoneTimeoutInMSec) {
parseDurationProperty(property, std::string(value), m_tombstoneTimeout);
} else if (property == EnableChunkHandlerThread) {
m_enableChunkHandlerThread = parseBooleanProperty(property, value);
} else if (property == OnClientDisconnectClearPdxTypeIds) {
m_onClientDisconnectClearPdxTypeIds = parseBooleanProperty(property, value);
} else {
throwError("SystemProperties: unknown property: " + property + "=" + value);
}
}
void SystemProperties::logSettings() {
using apache::geode::internal::chrono::duration::to_string;
// *** PLEASE ADD IN ALPHABETICAL ORDER - USER VISIBLE ***
std::string settings = "Geode Native Client System Properties:";
settings += "\n archive-disk-space-limit = ";
settings += std::to_string(statsDiskSpaceLimit());
settings += "\n archive-file-size-limit = ";
settings += std::to_string(statsFileSizeLimit());
settings += "\n auto-ready-for-events = ";
settings += autoReadyForEvents() ? "true" : "false";
settings += "\n bucket-wait-timeout = ";
settings += to_string(bucketWaitTimeout());
settings += "\n cache-xml-file = ";
settings += cacheXMLFile();
settings += "\n conflate-events = ";
settings += conflateEvents();
settings += "\n connect-timeout = ";
settings += to_string(connectTimeout());
settings += "\n connection-pool-size = ";
settings += std::to_string(connectionPoolSize());
settings += "\n connect-wait-timeout = ";
settings += to_string(connectWaitTimeout());
settings += "\n enable-chunk-handler-thread = ";
settings += enableChunkHandlerThread() ? "true" : "false";
settings += "\n disable-shuffling-of-endpoints = ";
settings += isEndpointShufflingDisabled() ? "true" : "false";
settings += "\n durable-client-id = ";
settings += durableClientId();
settings += "\n durable-timeout = ";
settings += to_string(durableTimeout());
// *** PLEASE ADD IN ALPHABETICAL ORDER - USER VISIBLE ***
settings += "\n enable-time-statistics = ";
settings += getEnableTimeStatistics() ? "true" : "false";
settings += "\n grid-client = ";
settings += isGridClient() ? "true" : "false";
settings += "\n heap-lru-delta = ";
settings += std::to_string(heapLRUDelta());
settings += "\n heap-lru-limit = ";
settings += std::to_string(heapLRULimit());
settings += "\n log-disk-space-limit = ";
settings += std::to_string(logDiskSpaceLimit());
settings += "\n log-file = ";
settings += logFilename();
settings += "\n log-file-size-limit = ";
settings += std::to_string(logFileSizeLimit());
settings += "\n log-level = ";
settings += Log::levelToChars(logLevel());
settings += "\n max-fe-threads = ";
settings += std::to_string(threadPoolSize());
settings += "\n max-socket-buffer-size = ";
settings += std::to_string(maxSocketBufferSize());
settings += "\n notify-ack-interval = ";
settings += to_string(notifyAckInterval());
settings += "\n notify-dupcheck-life = ";
settings += to_string(notifyDupCheckLife());
settings += "\n on-client-disconnect-clear-pdxType-Ids = ";
settings += onClientDisconnectClearPdxTypeIds() ? "true" : "false";
// *** PLEASE ADD IN ALPHABETICAL ORDER - USER VISIBLE ***
settings += "\n ping-interval = ";
settings += to_string(pingInterval());
settings += "\n redundancy-monitor-interval = ";
settings += to_string(redundancyMonitorInterval());
settings += "\n security-client-dhalgo = ";
settings += securityClientDhAlgo();
settings += "\n security-client-kspath = ";
settings += securityClientKsPath();
settings += "\n ssl-enabled = ";
settings += sslEnabled() ? "true" : "false";
settings += "\n ssl-keystore = ";
settings += sslKeyStore();
settings += "\n ssl-truststore = ";
settings += sslTrustStore();
settings += "\n statistic-archive-file = ";
settings += statisticsArchiveFile();
settings += "\n statistic-sampling-enabled = ";
settings += statisticsEnabled() ? "true" : "false";
settings += "\n statistic-sample-rate = ";
settings += to_string(statisticsSampleInterval());
settings += "\n suspended-tx-timeout = ";
settings += to_string(suspendedTxTimeout());
settings += "\n tombstone-timeout = ";
settings += to_string(tombstoneTimeout());
// *** PLEASE ADD IN ALPHABETICAL ORDER - USER VISIBLE ***
LOGCONFIG(settings);
}
} // namespace client
} // namespace geode
} // namespace apache