blob: f696f1222d4d0a5346abe6b41da9d6ddd56ed623 [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/Cache.hpp>
#include <geode/DataInput.hpp>
#include <geode/DataOutput.hpp>
#include <geode/PersistenceManager.hpp>
#include <geode/Properties.hpp>
#include "CacheXmlParser.hpp"
#include "Utils.hpp"
namespace apache {
namespace geode {
namespace client {
RegionAttributes::RegionAttributes()
: Serializable(),
m_regionTimeToLiveExpirationAction(ExpirationAction::INVALIDATE),
m_regionIdleTimeoutExpirationAction(ExpirationAction::INVALIDATE),
m_entryTimeToLiveExpirationAction(ExpirationAction::INVALIDATE),
m_entryIdleTimeoutExpirationAction(ExpirationAction::INVALIDATE),
m_lruEvictionAction(ExpirationAction::LOCAL_DESTROY),
m_lruEntriesLimit(0),
m_caching(true),
m_maxValueDistLimit(100 * 1024),
m_entryIdleTimeout(0),
m_entryTimeToLive(0),
m_regionIdleTimeout(0),
m_regionTimeToLive(0),
m_initialCapacity(10000),
m_loadFactor(0.75),
m_concurrencyLevel(16),
m_diskPolicy(DiskPolicyType::NONE),
m_clientNotificationEnabled(false),
m_persistenceProperties(nullptr),
m_persistenceManager(nullptr),
m_isClonable(false),
m_isConcurrencyChecksEnabled(true) {}
RegionAttributes::~RegionAttributes() noexcept = default;
namespace impl {
/**
* lib should be in the form required by ACE_DLL, typically just like specifying
* a
* lib in java System.loadLibrary( "x" ); Where x is a component of the name
* lib<x>.so on unix, or <x>.dll on windows.
*/
void* getFactoryFunc(const std::string& lib, const std::string& funcName) {
ACE_DLL dll;
if (dll.open(lib.c_str(), ACE_DEFAULT_SHLIB_MODE, 0) == -1) {
throw IllegalArgumentException("cannot open library: " + lib);
}
void* func = dll.symbol(funcName.c_str());
if (func == nullptr) {
throw IllegalArgumentException("cannot find factory function " + funcName +
" in library " + lib);
}
return func;
}
} // namespace impl
std::shared_ptr<CacheLoader> RegionAttributes::getCacheLoader() const {
if (!m_cacheLoader && !m_cacheLoaderLibrary.empty()) {
if (CacheXmlParser::managedCacheLoaderFn &&
m_cacheLoaderFactory.find('.') != std::string::npos) {
// this is a managed library
m_cacheLoader.reset((*CacheXmlParser::managedCacheLoaderFn)(
m_cacheLoaderLibrary.c_str(), m_cacheLoaderFactory.c_str()));
} else {
CacheLoader* (*funcptr)();
funcptr = reinterpret_cast<CacheLoader* (*)()>(
apache::geode::client::impl::getFactoryFunc(m_cacheLoaderLibrary,
m_cacheLoaderFactory));
m_cacheLoader.reset(funcptr());
}
}
return m_cacheLoader;
}
std::shared_ptr<CacheWriter> RegionAttributes::getCacheWriter() const {
if (!m_cacheWriter && !m_cacheWriterLibrary.empty()) {
if (CacheXmlParser::managedCacheWriterFn &&
m_cacheWriterFactory.find('.') != std::string::npos) {
// this is a managed library
m_cacheWriter.reset((*CacheXmlParser::managedCacheWriterFn)(
m_cacheWriterLibrary.c_str(), m_cacheWriterFactory.c_str()));
} else {
CacheWriter* (*funcptr)();
funcptr = reinterpret_cast<CacheWriter* (*)()>(
apache::geode::client::impl::getFactoryFunc(m_cacheWriterLibrary,
m_cacheWriterFactory));
m_cacheWriter.reset(funcptr());
}
}
return m_cacheWriter;
}
std::shared_ptr<CacheListener> RegionAttributes::getCacheListener() const {
if (!m_cacheListener && !m_cacheListenerLibrary.empty()) {
if (CacheXmlParser::managedCacheListenerFn &&
m_cacheListenerFactory.find('.') != std::string::npos) {
// this is a managed library
m_cacheListener.reset((*CacheXmlParser::managedCacheListenerFn)(
m_cacheListenerLibrary.c_str(), m_cacheListenerFactory.c_str()));
} else {
CacheListener* (*funcptr)();
funcptr = reinterpret_cast<CacheListener* (*)()>(
apache::geode::client::impl::getFactoryFunc(m_cacheListenerLibrary,
m_cacheListenerFactory));
m_cacheListener.reset(funcptr());
}
}
return m_cacheListener;
}
std::shared_ptr<PartitionResolver> RegionAttributes::getPartitionResolver()
const {
if (!m_partitionResolver && !m_partitionResolverLibrary.empty()) {
if (CacheXmlParser::managedPartitionResolverFn &&
m_partitionResolverFactory.find('.') != std::string::npos) {
// this is a managed library
m_partitionResolver.reset((*CacheXmlParser::managedPartitionResolverFn)(
m_partitionResolverLibrary.c_str(),
m_partitionResolverFactory.c_str()));
} else {
PartitionResolver* (*funcptr)();
funcptr = reinterpret_cast<PartitionResolver* (*)()>(
apache::geode::client::impl::getFactoryFunc(
m_partitionResolverLibrary, m_partitionResolverFactory));
m_partitionResolver.reset(funcptr());
}
}
return m_partitionResolver;
}
std::shared_ptr<PersistenceManager> RegionAttributes::getPersistenceManager()
const {
if (!m_persistenceManager && !m_persistenceLibrary.empty()) {
if (CacheXmlParser::managedPartitionResolverFn &&
m_persistenceFactory.find('.') != std::string::npos) {
// this is a managed library
m_persistenceManager.reset((*CacheXmlParser::managedPersistenceManagerFn)(
m_persistenceLibrary.c_str(), m_persistenceFactory.c_str()));
} else {
PersistenceManager* (*funcptr)();
funcptr = reinterpret_cast<PersistenceManager* (*)()>(
apache::geode::client::impl::getFactoryFunc(m_persistenceLibrary,
m_persistenceFactory));
m_persistenceManager.reset(funcptr());
}
}
return m_persistenceManager;
}
const std::string& RegionAttributes::getCacheLoaderFactory() const {
return m_cacheLoaderFactory;
}
const std::string& RegionAttributes::getCacheWriterFactory() const {
return m_cacheWriterFactory;
}
const std::string& RegionAttributes::getCacheListenerFactory() const {
return m_cacheListenerFactory;
}
const std::string& RegionAttributes::getPartitionResolverFactory() const {
return m_partitionResolverFactory;
}
const std::string& RegionAttributes::getPersistenceFactory() const {
return m_persistenceFactory;
}
const std::string& RegionAttributes::getCacheLoaderLibrary() const {
return m_cacheLoaderLibrary;
}
const std::string& RegionAttributes::getCacheWriterLibrary() const {
return m_cacheWriterLibrary;
}
const std::string& RegionAttributes::getCacheListenerLibrary() const {
return m_cacheListenerLibrary;
}
const std::string& RegionAttributes::getPartitionResolverLibrary() const {
return m_partitionResolverLibrary;
}
const std::string& RegionAttributes::getEndpoints() const {
return m_endpoints;
}
bool RegionAttributes::getClientNotificationEnabled() const {
return m_clientNotificationEnabled;
}
const std::string& RegionAttributes::getPersistenceLibrary() const {
return m_persistenceLibrary;
}
std::shared_ptr<Properties> RegionAttributes::getPersistenceProperties() const {
return m_persistenceProperties;
}
std::chrono::seconds RegionAttributes::getRegionTimeToLive() const {
return m_regionTimeToLive;
}
ExpirationAction RegionAttributes::getRegionTimeToLiveAction() const {
return m_regionTimeToLiveExpirationAction;
}
std::chrono::seconds RegionAttributes::getRegionIdleTimeout() const {
return m_regionIdleTimeout;
}
ExpirationAction RegionAttributes::getRegionIdleTimeoutAction() const {
return m_regionIdleTimeoutExpirationAction;
}
std::chrono::seconds RegionAttributes::getEntryTimeToLive() const {
return m_entryTimeToLive;
}
ExpirationAction RegionAttributes::getEntryTimeToLiveAction() const {
return m_entryTimeToLiveExpirationAction;
}
std::chrono::seconds RegionAttributes::getEntryIdleTimeout() const {
return m_entryIdleTimeout;
}
ExpirationAction RegionAttributes::getEntryIdleTimeoutAction() const {
return m_entryIdleTimeoutExpirationAction;
}
int RegionAttributes::getInitialCapacity() const { return m_initialCapacity; }
float RegionAttributes::getLoadFactor() const { return m_loadFactor; }
uint8_t RegionAttributes::getConcurrencyLevel() const {
return m_concurrencyLevel;
}
ExpirationAction RegionAttributes::getLruEvictionAction() const {
return m_lruEvictionAction;
}
uint32_t RegionAttributes::getLruEntriesLimit() const {
return m_lruEntriesLimit;
}
DiskPolicyType RegionAttributes::getDiskPolicy() const { return m_diskPolicy; }
std::shared_ptr<Serializable> RegionAttributes::createDeserializable() {
return std::make_shared<RegionAttributes>();
}
namespace impl {
void writeBool(DataOutput& out, bool field) {
out.write(static_cast<int8_t>(field ? 1 : 0));
}
void readBool(DataInput& in, bool* field) { *field = in.read() ? true : false; }
void writeString(DataOutput& out, const std::string& field) {
out.writeBytes(reinterpret_cast<int8_t*>(const_cast<char*>(field.c_str())),
static_cast<uint32_t>(field.length()) + 1);
}
void readString(DataInput& in, std::string& field) {
// length including null terminator
auto len = in.readArrayLength();
// currentBufferPosition is read-only and we are only reading, cast away const
field = std::string(const_cast<char*>(reinterpret_cast<const char*>(
in.currentBufferPosition())),
len - 1);
in.advanceCursor(len);
}
} // namespace impl
void RegionAttributes::toData(DataOutput& out) const {
out.writeInt(static_cast<int32_t>(m_regionTimeToLive.count()));
out.writeInt(static_cast<int32_t>(m_regionTimeToLiveExpirationAction));
out.writeInt(static_cast<int32_t>(m_regionIdleTimeout.count()));
out.writeInt(static_cast<int32_t>(m_regionIdleTimeoutExpirationAction));
out.writeInt(static_cast<int32_t>(m_entryTimeToLive.count()));
out.writeInt(static_cast<int32_t>(m_entryTimeToLiveExpirationAction));
out.writeInt(static_cast<int32_t>(m_entryIdleTimeout.count()));
out.writeInt(static_cast<int32_t>(m_entryIdleTimeoutExpirationAction));
out.writeInt(static_cast<int32_t>(m_initialCapacity));
out.writeFloat(m_loadFactor);
out.writeInt(static_cast<int32_t>(m_maxValueDistLimit));
out.writeInt(static_cast<int32_t>(m_concurrencyLevel));
out.writeInt(static_cast<int32_t>(m_lruEntriesLimit));
out.writeInt(static_cast<int32_t>(m_lruEvictionAction));
apache::geode::client::impl::writeBool(out, m_caching);
apache::geode::client::impl::writeBool(out, m_clientNotificationEnabled);
apache::geode::client::impl::writeString(out, m_cacheLoaderLibrary);
apache::geode::client::impl::writeString(out, m_cacheLoaderFactory);
apache::geode::client::impl::writeString(out, m_cacheWriterLibrary);
apache::geode::client::impl::writeString(out, m_cacheWriterFactory);
apache::geode::client::impl::writeString(out, m_cacheListenerLibrary);
apache::geode::client::impl::writeString(out, m_cacheListenerFactory);
apache::geode::client::impl::writeString(out, m_partitionResolverLibrary);
apache::geode::client::impl::writeString(out, m_partitionResolverFactory);
out.writeInt(static_cast<int32_t>(m_diskPolicy));
apache::geode::client::impl::writeString(out, m_endpoints);
apache::geode::client::impl::writeString(out, m_persistenceLibrary);
apache::geode::client::impl::writeString(out, m_persistenceFactory);
out.writeObject(m_persistenceProperties);
apache::geode::client::impl::writeString(out, m_poolName);
apache::geode::client::impl::writeBool(out, m_isConcurrencyChecksEnabled);
}
void RegionAttributes::fromData(DataInput& in) {
m_regionTimeToLive = std::chrono::seconds(in.readInt32());
m_regionTimeToLiveExpirationAction =
static_cast<ExpirationAction>(in.readInt32());
m_regionIdleTimeout = std::chrono::seconds(in.readInt32());
m_regionIdleTimeoutExpirationAction =
static_cast<ExpirationAction>(in.readInt32());
m_entryTimeToLive = std::chrono::seconds(in.readInt32());
m_entryTimeToLiveExpirationAction =
static_cast<ExpirationAction>(in.readInt32());
m_entryIdleTimeout = std::chrono::seconds(in.readInt32());
m_entryIdleTimeoutExpirationAction =
static_cast<ExpirationAction>(in.readInt32());
m_initialCapacity = in.readInt32();
m_loadFactor = in.readFloat();
m_maxValueDistLimit = in.readInt32();
m_concurrencyLevel = in.readInt32();
m_lruEntriesLimit = in.readInt32();
m_lruEvictionAction = static_cast<ExpirationAction>(in.readInt32());
apache::geode::client::impl::readBool(in, &m_caching);
apache::geode::client::impl::readBool(in, &m_clientNotificationEnabled);
apache::geode::client::impl::readString(in, m_cacheLoaderLibrary);
apache::geode::client::impl::readString(in, m_cacheLoaderFactory);
apache::geode::client::impl::readString(in, m_cacheWriterLibrary);
apache::geode::client::impl::readString(in, m_cacheWriterFactory);
apache::geode::client::impl::readString(in, m_cacheListenerLibrary);
apache::geode::client::impl::readString(in, m_cacheListenerFactory);
apache::geode::client::impl::readString(in, m_partitionResolverLibrary);
apache::geode::client::impl::readString(in, m_partitionResolverFactory);
m_diskPolicy = static_cast<DiskPolicyType>(in.readInt32());
apache::geode::client::impl::readString(in, m_endpoints);
apache::geode::client::impl::readString(in, m_persistenceLibrary);
apache::geode::client::impl::readString(in, m_persistenceFactory);
m_persistenceProperties =
std::dynamic_pointer_cast<Properties>(in.readObject());
apache::geode::client::impl::readString(in, m_poolName);
apache::geode::client::impl::readBool(in, &m_isConcurrencyChecksEnabled);
}
/** Return true if all the attributes are equal to those of other. */
bool RegionAttributes::operator==(const RegionAttributes& other) const {
if (m_regionTimeToLive != other.m_regionTimeToLive) return false;
if (m_regionTimeToLiveExpirationAction !=
other.m_regionTimeToLiveExpirationAction) {
return false;
}
if (m_regionIdleTimeout != other.m_regionIdleTimeout) return false;
if (m_regionIdleTimeoutExpirationAction !=
other.m_regionIdleTimeoutExpirationAction) {
return false;
}
if (m_entryTimeToLive != other.m_entryTimeToLive) return false;
if (m_entryTimeToLiveExpirationAction !=
other.m_entryTimeToLiveExpirationAction) {
return false;
}
if (m_entryIdleTimeout != other.m_entryIdleTimeout) return false;
if (m_entryIdleTimeoutExpirationAction !=
other.m_entryIdleTimeoutExpirationAction) {
return false;
}
if (m_initialCapacity != other.m_initialCapacity) return false;
if (m_loadFactor != other.m_loadFactor) return false;
if (m_maxValueDistLimit != other.m_maxValueDistLimit) return false;
if (m_concurrencyLevel != other.m_concurrencyLevel) return false;
if (m_lruEntriesLimit != other.m_lruEntriesLimit) return false;
if (m_lruEvictionAction != other.m_lruEvictionAction) return false;
if (m_caching != other.m_caching) return false;
if (m_clientNotificationEnabled != other.m_clientNotificationEnabled) {
return false;
}
if (m_cacheLoaderLibrary != other.m_cacheLoaderLibrary) {
return false;
}
if (m_cacheLoaderFactory != other.m_cacheLoaderFactory) {
return false;
}
if (m_cacheWriterLibrary != other.m_cacheWriterLibrary) {
return false;
}
if (m_cacheWriterFactory != other.m_cacheWriterFactory) {
return false;
}
if (m_cacheListenerLibrary != other.m_cacheListenerLibrary) {
return false;
}
if (m_cacheListenerFactory != other.m_cacheListenerFactory) {
return false;
}
if (m_partitionResolverLibrary != other.m_partitionResolverLibrary) {
return false;
}
if (m_partitionResolverFactory != other.m_partitionResolverFactory) {
return false;
}
if (m_diskPolicy != other.m_diskPolicy) {
return false;
}
if (m_endpoints != other.m_endpoints) {
return false;
}
if (m_persistenceLibrary != other.m_persistenceLibrary) {
return false;
}
if (m_persistenceFactory != other.m_persistenceFactory) {
return false;
}
if (m_isConcurrencyChecksEnabled != other.m_isConcurrencyChecksEnabled) {
return false;
}
return true;
}
/** Return true if any of the attributes are not equal to those of other. */
bool RegionAttributes::operator!=(const RegionAttributes& other) const {
return !(*this == other);
}
/* Throws IllegalStateException when attributes targetted for use on a server do
* not meet requirements. */
void RegionAttributes::validateSerializableAttributes() {
if (m_cacheLoader != nullptr) {
throw IllegalStateException(
"CacheLoader must be set with setCacheLoader(library, factory) in "
"members of type SERVER");
}
if (m_cacheWriter != nullptr) {
throw IllegalStateException(
"CacheWriter must be set with setCacheWriter(library, factory) in "
"members of type SERVER");
}
if (m_cacheListener != nullptr) {
throw IllegalStateException(
"CacheListener must be set with setCacheListener(library, factory) in "
"members of type SERVER");
}
if (m_partitionResolver != nullptr) {
throw IllegalStateException(
"PartitionResolver must be set with setPartitionResolver(library, "
"factory) in members of type SERVER");
}
if (m_persistenceManager != nullptr) {
throw IllegalStateException(
"persistenceManager must be set with setPersistenceManager(library, "
"factory,config) in members of type SERVER");
}
}
void RegionAttributes::setCacheListener(const std::string& lib,
const std::string& func) {
m_cacheListenerLibrary = lib;
m_cacheListenerFactory = func;
}
void RegionAttributes::setPartitionResolver(const std::string& lib,
const std::string& func) {
m_partitionResolverLibrary = lib;
m_partitionResolverFactory = func;
}
void RegionAttributes::setCacheLoader(const std::string& lib,
const std::string& func) {
m_cacheLoaderLibrary = lib;
m_cacheLoaderFactory = func;
}
void RegionAttributes::setCacheWriter(const std::string& lib,
const std::string& func) {
m_cacheWriterLibrary = lib;
m_cacheWriterFactory = func;
}
void RegionAttributes::setPersistenceManager(
const std::string& lib, const std::string& func,
const std::shared_ptr<Properties>& config) {
m_persistenceLibrary = lib;
m_persistenceFactory = func;
m_persistenceProperties = config;
}
void RegionAttributes::setEndpoints(const std::string& endpoints) {
m_endpoints = endpoints;
}
void RegionAttributes::setPoolName(const std::string& poolName) {
m_poolName = poolName;
}
void RegionAttributes::setCachingEnabled(bool enable) { m_caching = enable; }
void RegionAttributes::setLruEntriesLimit(int limit) {
m_lruEntriesLimit = limit;
}
void RegionAttributes::setDiskPolicy(DiskPolicyType diskPolicy) {
m_diskPolicy = diskPolicy;
}
void RegionAttributes::setCloningEnabled(bool isClonable) {
m_isClonable = isClonable;
}
void RegionAttributes::setConcurrencyChecksEnabled(bool enable) {
m_isConcurrencyChecksEnabled = enable;
}
} // namespace client
} // namespace geode
} // namespace apache