| /* |
| * 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 "CacheXmlParser.hpp" |
| |
| #include <chrono> |
| #include <cinttypes> |
| |
| #include <geode/PoolFactory.hpp> |
| #include <geode/PoolManager.hpp> |
| #include <geode/internal/chrono/duration.hpp> |
| |
| #include "AutoDelete.hpp" |
| #include "CacheImpl.hpp" |
| #include "CacheRegionHelper.hpp" |
| #include "util/string.hpp" |
| |
| #if defined(_WIN32) |
| #include <windows.h> |
| #else |
| #include <dlfcn.h> |
| #endif |
| |
| namespace apache { |
| namespace geode { |
| namespace client { |
| |
| namespace { |
| /** The name of the <code>cache</code> element */ |
| auto CACHE = "cache"; |
| auto CLIENT_CACHE = "client-cache"; |
| auto PDX = "pdx"; |
| |
| /** The name of the <code>redundancy-level</code> element */ |
| auto REDUNDANCY_LEVEL = "redundancy-level"; |
| |
| /** The name of the <code>region</code> element */ |
| auto REGION = "region"; |
| |
| /** The name of the <code>root-region</code> element */ |
| auto ROOT_REGION = "root-region"; |
| |
| /** The name of the <code>region-attributes</code> element */ |
| auto REGION_ATTRIBUTES = "region-attributes"; |
| |
| auto LRU_ENTRIES_LIMIT = "lru-entries-limit"; |
| |
| auto DISK_POLICY = "disk-policy"; |
| |
| auto ENDPOINTS = "endpoints"; |
| |
| /** The name of the <code>region-time-to-live</code> element */ |
| auto REGION_TIME_TO_LIVE = "region-time-to-live"; |
| |
| /** The name of the <code>region-idle-time</code> element */ |
| auto REGION_IDLE_TIME = "region-idle-time"; |
| |
| /** The name of the <code>entry-time-to-live</code> element */ |
| auto ENTRY_TIME_TO_LIVE = "entry-time-to-live"; |
| |
| /** The name of the <code>entry-idle-time</code> element */ |
| auto ENTRY_IDLE_TIME = "entry-idle-time"; |
| |
| /** The name of the <code>expiration-attributes</code> element */ |
| auto EXPIRATION_ATTRIBUTES = "expiration-attributes"; |
| |
| /** The name of the <code>cache-loader</code> element */ |
| auto CACHE_LOADER = "cache-loader"; |
| |
| /** The name of the <code>cache-writer</code> element */ |
| auto CACHE_WRITER = "cache-writer"; |
| |
| /** The name of the <code>cache-listener</code> element */ |
| auto CACHE_LISTENER = "cache-listener"; |
| |
| /** The name of the <code>partition-resolver</code> element */ |
| auto PARTITION_RESOLVER = "partition-resolver"; |
| |
| auto LIBRARY_NAME = "library-name"; |
| |
| auto LIBRARY_FUNCTION_NAME = "library-function-name"; |
| |
| auto CACHING_ENABLED = "caching-enabled"; |
| |
| auto INTEREST_LIST_ENABLED = "interest-list-enabled"; |
| |
| auto MAX_DISTRIBUTE_VALUE_LENGTH_WHEN_CREATE = |
| "max-distribute-value-length-when-create"; |
| /** The name of the <code>scope</code> attribute */ |
| auto SCOPE = "scope"; |
| |
| /** The name of the <code>client-notification</code> attribute */ |
| auto CLIENT_NOTIFICATION_ENABLED = "client-notification"; |
| |
| /** The name of the <code>initial-capacity</code> attribute */ |
| auto INITIAL_CAPACITY = "initial-capacity"; |
| |
| /** The name of the <code>initial-capacity</code> attribute */ |
| auto CONCURRENCY_LEVEL = "concurrency-level"; |
| |
| /** The name of the <code>load-factor</code> attribute */ |
| auto LOAD_FACTOR = "load-factor"; |
| |
| /** The name of the <code>statistics-enabled</code> attribute */ |
| auto STATISTICS_ENABLED = "statistics-enabled"; |
| |
| /** The name of the <code>timeout</code> attribute */ |
| auto TIMEOUT = "timeout"; |
| |
| /** The name of the <code>action</code> attribute */ |
| auto ACTION = "action"; |
| |
| /** The name of the <code>local</code> value */ |
| auto LOCAL = "local"; |
| |
| /** The name of the <code>distributed-no-ack</code> value */ |
| auto DISTRIBUTED_NO_ACK = "distributed-no-ack"; |
| |
| /** The name of the <code>distributed-ack</code> value */ |
| auto DISTRIBUTED_ACK = "distributed-ack"; |
| |
| /** The name of the <code>global</code> value */ |
| auto GLOBAL = "global"; |
| |
| /** The name of the <code>invalidate</code> value */ |
| auto INVALIDATE = "invalidate"; |
| |
| /** The name of the <code>destroy</code> value */ |
| auto DESTROY = "destroy"; |
| |
| /** The name of the <code>overflow</code> value */ |
| auto OVERFLOWS = "overflows"; |
| |
| /** The name of the <code>overflow</code> value */ |
| auto PERSIST = "persist"; |
| |
| /** The name of the <code>none</code> value */ |
| auto NONE = "none"; |
| |
| /** The name of the <code>local-invalidate</code> value */ |
| auto LOCAL_INVALIDATE = "local-invalidate"; |
| |
| /** The name of the <code>local-destroy</code> value */ |
| auto LOCAL_DESTROY = "local-destroy"; |
| |
| /** The name of the <code>persistence-manager</code> value */ |
| auto PERSISTENCE_MANAGER = "persistence-manager"; |
| |
| /** The name of the <code>property</code> value */ |
| auto PROPERTY = "property"; |
| |
| auto CONCURRENCY_CHECKS_ENABLED = "concurrency-checks-enabled"; |
| |
| auto TOMBSTONE_TIMEOUT = "tombstone-timeout"; |
| |
| /** Pool elements and attributes */ |
| |
| auto POOL_NAME = "pool-name"; |
| auto POOL = "pool"; |
| auto NAME = "name"; |
| auto VALUE = "value"; |
| auto LOCATOR = "locator"; |
| auto SERVER = "server"; |
| auto HOST = "host"; |
| auto PORT = "port"; |
| auto IGNORE_UNREAD_FIELDS = "ignore-unread-fields"; |
| auto READ_SERIALIZED = "read-serialized"; |
| auto FREE_CONNECTION_TIMEOUT = "free-connection-timeout"; |
| auto MULTIUSER_SECURE_MODE = "multiuser-authentication"; |
| auto IDLE_TIMEOUT = "idle-timeout"; |
| auto LOAD_CONDITIONING_INTERVAL = "load-conditioning-interval"; |
| auto MAX_CONNECTIONS = "max-connections"; |
| auto MIN_CONNECTIONS = "min-connections"; |
| auto PING_INTERVAL = "ping-interval"; |
| auto UPDATE_LOCATOR_LIST_INTERVAL = "update-locator-list-interval"; |
| auto READ_TIMEOUT = "read-timeout"; |
| auto RETRY_ATTEMPTS = "retry-attempts"; |
| auto SERVER_GROUP = "server-group"; |
| auto SOCKET_BUFFER_SIZE = "socket-buffer-size"; |
| auto STATISTIC_INTERVAL = "statistic-interval"; |
| auto SUBSCRIPTION_ACK_INTERVAL = "subscription-ack-interval"; |
| auto SUBSCRIPTION_ENABLED = "subscription-enabled"; |
| auto SUBSCRIPTION_MTT = "subscription-message-tracking-timeout"; |
| auto SUBSCRIPTION_REDUNDANCY = "subscription-redundancy"; |
| auto THREAD_LOCAL_CONNECTIONS = "thread-local-connections"; |
| auto CLONING_ENABLED = "cloning-enabled"; |
| auto ID = "id"; |
| auto REFID = "refid"; |
| auto PR_SINGLE_HOP_ENABLED = "pr-single-hop-enabled"; |
| |
| std::vector<std::pair<std::string, int>> parseEndPoints( |
| const std::string &str) { |
| std::vector<std::pair<std::string, int>> endPoints; |
| std::string::size_type start = 0; |
| std::string::size_type pos = str.find_first_of(','); |
| while (std::string::npos != pos) { |
| const std::string endPoint(str.substr(start, pos - start)); |
| const std::string::size_type split = endPoint.find_last_of(':'); |
| if (std::string::npos == split) { |
| endPoints.push_back(std::pair<std::string, int>(endPoint, 0)); |
| } else { |
| int port = 0; |
| try { |
| port = std::stoi(endPoint.substr(split + 1)); |
| } catch (...) { |
| // NOP |
| } |
| endPoints.push_back( |
| std::pair<std::string, int>(endPoint.substr(0, split), port)); |
| } |
| start = pos + 1; |
| pos = str.find_first_of(',', start); |
| } |
| return endPoints; |
| } |
| } // namespace |
| |
| /** |
| * warningDebug: |
| * @ctxt: An XML parser context |
| * @msg: the message to display/transmit |
| * @...: extra parameters for the message display |
| * |
| * Display and format a warning messages, gives file, line, position and |
| * extra parameters. |
| */ |
| extern "C" void warningDebug(void *, const char *msg, ...) { |
| char logmsg[2048]; |
| va_list args; |
| va_start(args, msg); |
| vsprintf(logmsg, msg, args); |
| va_end(args); |
| LOGWARN("SAX.warning during XML declarative client initialization: %s", |
| logmsg); |
| } |
| |
| /////////////End of XML Parser Cackllback functions/////////////// |
| |
| ///////////////static variables of the class//////////////////////// |
| |
| FactoryLoaderFn<CacheLoader> CacheXmlParser::managedCacheLoaderFn_ = nullptr; |
| FactoryLoaderFn<CacheListener> CacheXmlParser::managedCacheListenerFn_ = |
| nullptr; |
| FactoryLoaderFn<PartitionResolver> CacheXmlParser::managedPartitionResolverFn_ = |
| nullptr; |
| FactoryLoaderFn<CacheWriter> CacheXmlParser::managedCacheWriterFn_ = nullptr; |
| FactoryLoaderFn<PersistenceManager> |
| CacheXmlParser::managedPersistenceManagerFn_ = nullptr; |
| |
| ////////////////////////////////////////////////////////////////// |
| |
| CacheXmlParser::CacheXmlParser(Cache *cache) |
| : cacheCreation_(nullptr), |
| nestedRegions_(0), |
| config_(nullptr), |
| parserMessage_(""), |
| flagCacheXmlException_(false), |
| flagIllegalStateException_(false), |
| flagAnyOtherException_(false), |
| flagExpirationAttribute_(false), |
| namedRegions_(CacheImpl::getRegionShortcut()), |
| poolFactory_(nullptr), |
| cache_(cache) { |
| start_element_map_.emplace( |
| std::make_pair(std::string(CACHE), &CacheXmlParser::startCache)); |
| start_element_map_.emplace( |
| std::make_pair(std::string(CLIENT_CACHE), &CacheXmlParser::startCache)); |
| start_element_map_.emplace( |
| std::make_pair(std::string(PDX), &CacheXmlParser::startPdx)); |
| start_element_map_.emplace( |
| std::make_pair(std::string(REGION), &CacheXmlParser::startRegion)); |
| start_element_map_.emplace( |
| std::make_pair(std::string(ROOT_REGION), &CacheXmlParser::startRegion)); |
| start_element_map_.emplace(std::make_pair( |
| std::string(REGION_ATTRIBUTES), &CacheXmlParser::startRegionAttributes)); |
| start_element_map_.emplace( |
| std::make_pair(std::string(EXPIRATION_ATTRIBUTES), |
| &CacheXmlParser::startExpirationAttributes)); |
| start_element_map_.emplace(std::make_pair(std::string(CACHE_LOADER), |
| &CacheXmlParser::startCacheLoader)); |
| start_element_map_.emplace(std::make_pair(std::string(CACHE_WRITER), |
| &CacheXmlParser::startCacheWriter)); |
| start_element_map_.emplace(std::make_pair( |
| std::string(CACHE_LISTENER), &CacheXmlParser::startCacheListener)); |
| start_element_map_.emplace( |
| std::make_pair(std::string(PARTITION_RESOLVER), |
| &CacheXmlParser::startPartitionResolver)); |
| start_element_map_.emplace( |
| std::make_pair(std::string(PERSISTENCE_MANAGER), |
| &CacheXmlParser::startPersistenceManager)); |
| start_element_map_.emplace(std::make_pair( |
| std::string(PROPERTY), &CacheXmlParser::startPersistenceProperty)); |
| start_element_map_.emplace( |
| std::make_pair(std::string(POOL), &CacheXmlParser::startPool)); |
| start_element_map_.emplace( |
| std::make_pair(std::string(LOCATOR), &CacheXmlParser::startLocator)); |
| start_element_map_.emplace( |
| std::make_pair(std::string(SERVER), &CacheXmlParser::startServer)); |
| |
| end_element_map_.emplace( |
| std::make_pair(std::string(CACHE), &CacheXmlParser::endCache)); |
| end_element_map_.emplace( |
| std::make_pair(std::string(CLIENT_CACHE), &CacheXmlParser::endCache)); |
| end_element_map_.emplace( |
| std::make_pair(std::string(REGION), &CacheXmlParser::endRegion)); |
| end_element_map_.emplace( |
| std::make_pair(std::string(ROOT_REGION), &CacheXmlParser::endRegion)); |
| end_element_map_.emplace(std::make_pair( |
| std::string(REGION_ATTRIBUTES), &CacheXmlParser::endRegionAttributes)); |
| end_element_map_.emplace(std::make_pair( |
| std::string(REGION_TIME_TO_LIVE), &CacheXmlParser::endRegionTimeToLive)); |
| end_element_map_.emplace(std::make_pair(std::string(REGION_IDLE_TIME), |
| &CacheXmlParser::endRegionIdleTime)); |
| end_element_map_.emplace(std::make_pair(std::string(ENTRY_TIME_TO_LIVE), |
| &CacheXmlParser::endEntryTimeToLive)); |
| end_element_map_.emplace(std::make_pair(std::string(ENTRY_IDLE_TIME), |
| &CacheXmlParser::endEntryIdleTime)); |
| end_element_map_.emplace( |
| std::make_pair(std::string(PERSISTENCE_MANAGER), |
| &CacheXmlParser::endPersistenceManager)); |
| end_element_map_.emplace( |
| std::make_pair(std::string(POOL), &CacheXmlParser::endPool)); |
| } |
| |
| void CacheXmlParser::startElement(const XMLCh *const, |
| const XMLCh *const localname, |
| const XMLCh *const, |
| const xercesc::Attributes &attrs) { |
| auto message = xercesc::XMLString::transcode(localname); |
| auto name = std::string(message); |
| auto iter = start_element_map_.find(name); |
| if (iter != std::end(start_element_map_)) { |
| iter->second(*this, attrs); |
| } |
| xercesc::XMLString::release(&message); |
| } |
| |
| void CacheXmlParser::endElement(const XMLCh *const, |
| const XMLCh *const localname, |
| const XMLCh *const) { |
| auto message = xercesc::XMLString::transcode(localname); |
| auto name = std::string(message); |
| auto iter = end_element_map_.find(name); |
| if (iter != std::end(end_element_map_)) { |
| iter->second(*this); |
| } |
| xercesc::XMLString::release(&message); |
| } |
| |
| void CacheXmlParser::fatalError(const xercesc::SAXParseException &exception) { |
| char *message = xercesc::XMLString::transcode(exception.getMessage()); |
| LOGDEBUG("Fatal Error: \"%s\" at line: %" PRIu64, message, |
| exception.getLineNumber()); |
| auto ex = CacheXmlException(message); |
| xercesc::XMLString::release(&message); |
| throw ex; |
| } |
| |
| void CacheXmlParser::parseFile(const char *filename) { |
| try { |
| xercesc::XMLPlatformUtils::Initialize(); |
| } catch (const xercesc::XMLException &toCatch) { |
| char *message = xercesc::XMLString::transcode(toCatch.getMessage()); |
| auto exceptionMessage = "Error parsing XML file: " + std::string(message); |
| xercesc::XMLString::release(&message); |
| throw CacheXmlException(exceptionMessage); |
| } |
| |
| auto parser = xercesc::XMLReaderFactory::createXMLReader(); |
| |
| parser->setFeature(xercesc::XMLUni::fgXercesSchema, false); |
| parser->setContentHandler(this); |
| parser->setErrorHandler(this); |
| |
| try { |
| parser->parse(filename); |
| } catch (const xercesc::XMLException &toCatch) { |
| char *message = xercesc::XMLString::transcode(toCatch.getMessage()); |
| auto exceptionMessage = "Error parsing XML file: " + std::string(message); |
| xercesc::XMLString::release(&message); |
| throw CacheXmlException(exceptionMessage); |
| } catch (const xercesc::SAXParseException &toCatch) { |
| char *message = xercesc::XMLString::transcode(toCatch.getMessage()); |
| auto exceptionMessage = "Error parsing XML file: " + std::string(message); |
| xercesc::XMLString::release(&message); |
| throw CacheXmlException(exceptionMessage); |
| } |
| |
| delete parser; |
| xercesc::XMLPlatformUtils::Terminate(); |
| } |
| |
| void CacheXmlParser::parseMemory(const char *buffer, int size) { |
| try { |
| xercesc::XMLPlatformUtils::Initialize(); |
| } catch (const xercesc::XMLException &toCatch) { |
| char *message = xercesc::XMLString::transcode(toCatch.getMessage()); |
| auto exceptionMessage = "Error parsing XML file: " + std::string(message); |
| xercesc::XMLString::release(&message); |
| throw CacheXmlException(exceptionMessage); |
| } |
| |
| auto parser = xercesc::XMLReaderFactory::createXMLReader(); |
| |
| parser->setContentHandler(this); |
| parser->setErrorHandler(this); |
| |
| try { |
| xercesc::MemBufInputSource myxml_buf( |
| reinterpret_cast<const XMLByte *>(buffer), size, |
| "CacheXmlParser memory source"); |
| parser->parse(myxml_buf); |
| } catch (const xercesc::XMLException &toCatch) { |
| char *message = xercesc::XMLString::transcode(toCatch.getMessage()); |
| auto exceptionMessage = "Error parsing XML file: " + std::string(message); |
| xercesc::XMLString::release(&message); |
| throw CacheXmlException(exceptionMessage); |
| } catch (const xercesc::SAXParseException &toCatch) { |
| char *message = xercesc::XMLString::transcode(toCatch.getMessage()); |
| auto exceptionMessage = "Error parsing XML file: " + std::string(message); |
| xercesc::XMLString::release(&message); |
| throw CacheXmlException(exceptionMessage); |
| } |
| |
| delete parser; |
| xercesc::XMLPlatformUtils::Terminate(); |
| } |
| |
| ////////////////////// Static Methods ////////////////////// |
| |
| /** |
| * Parses XML data and from it creates an instance of |
| * <code>CacheXmlParser</code> that can be used to create |
| * the {@link Cache}, etc. |
| * |
| * @param cacheXml |
| * The xml file |
| * |
| * @throws CacheXmlException |
| * Something went wrong while parsing the XML |
| * @throws OutOfMemoryException |
| * @throws CacheXmlException |
| * If xml file is not well-formed or |
| * Something went wrong while parsing the XML |
| * @throws IllegalStateException |
| * If xml file is well-flrmed but not valid |
| * @throws UnknownException otherwise |
| */ |
| CacheXmlParser *CacheXmlParser::parse(const char *cacheXml, Cache *cache) { |
| CacheXmlParser *handler; |
| _GEODE_NEW(handler, CacheXmlParser(cache)); |
| // use RAII to delete the handler object in case of exceptions |
| DeleteObject<CacheXmlParser> delHandler(handler); |
| |
| { |
| handler->parseFile(cacheXml); |
| delHandler.noDelete(); |
| return handler; |
| } |
| } |
| |
| void CacheXmlParser::setAttributes(Cache *) {} |
| |
| /** |
| * Creates cache artifacts ({@link Cache}s, etc.) based upon the XML |
| * parsed by this parser. |
| * |
| * @param cache |
| * The cachewhcih is to be populated |
| * @throws OutOfMemoryException if the memory allocation failed |
| * @throws NotConnectedException if the cache is not connected |
| * @throws InvalidArgumentException if the attributePtr is nullptr. |
| * or if RegionAttributes is null or if regionName is null, |
| * the empty string, or contains a '/' |
| * @throws RegionExistsException |
| * @throws CacheClosedException if the cache is closed |
| * at the time of region creation |
| * @throws UnknownException otherwise |
| * |
| */ |
| void CacheXmlParser::create(Cache *cache) { |
| // use DeleteObject class to delete cacheCreation_ in case of exceptions |
| DeleteObject<CacheXmlCreation> delCacheCreation(cacheCreation_); |
| |
| if (cache == nullptr) { |
| throw IllegalArgumentException( |
| "XML:No cache specified for performing configuration"); |
| } |
| if (!cacheCreation_) { |
| throw CacheXmlException("XML: Element <cache> was not provided in the xml"); |
| } |
| cacheCreation_->create(cache); |
| delCacheCreation.noDelete(); |
| Log::info("Declarative configuration of cache completed successfully"); |
| } |
| |
| std::string CacheXmlParser::getOptionalAttribute( |
| const xercesc::Attributes &attrs, const char *attributeName) { |
| using unique_xml_char = std::unique_ptr<XMLCh, std::function<void(XMLCh *)>>; |
| using unique_xerces_char = std::unique_ptr<char, std::function<void(char *)>>; |
| auto xml_deleter = [](XMLCh *ch) { xercesc::XMLString::release(&ch); }; |
| auto xerces_deleter = [](char *ch) { xercesc::XMLString::release(&ch); }; |
| |
| unique_xml_char translatedName(xercesc::XMLString::transcode(attributeName), |
| xml_deleter); |
| auto value = attrs.getValue(translatedName.get()); |
| if (!value) { |
| return ""; |
| } |
| |
| unique_xerces_char translatedValue(xercesc::XMLString::transcode(value), |
| xerces_deleter); |
| if (!strlen(translatedValue.get())) { |
| throw CacheXmlException("XML: Empty value provided for attribute: " + |
| std::string(CACHE) + " or " + CLIENT_CACHE); |
| } |
| |
| return {translatedValue.get()}; |
| } |
| |
| std::string CacheXmlParser::getRequiredAttribute( |
| const xercesc::Attributes &attrs, const char *attributeName) { |
| using unique_xml_char = std::unique_ptr<XMLCh, std::function<void(XMLCh *)>>; |
| auto xml_deleter = [](XMLCh *ch) { xercesc::XMLString::release(&ch); }; |
| |
| unique_xml_char translatedName(xercesc::XMLString::transcode(attributeName), |
| xml_deleter); |
| auto value = attrs.getValue(translatedName.get()); |
| if (!value) { |
| throw CacheXmlException("XML: No value provided for required attribute: " + |
| std::string(attributeName)); |
| } |
| |
| return getOptionalAttribute(attrs, attributeName); |
| } |
| |
| void CacheXmlParser::startCache(const xercesc::Attributes &attrs) { |
| auto value = getOptionalAttribute(attrs, ENDPOINTS); |
| if (!value.empty()) { |
| if (poolFactory_) { |
| for (auto &&endPoint : parseEndPoints(value)) { |
| poolFactory_->addServer(endPoint.first, endPoint.second); |
| } |
| } |
| } |
| |
| value = getOptionalAttribute(attrs, REDUNDANCY_LEVEL); |
| if (!value.empty()) { |
| if (poolFactory_) { |
| poolFactory_->setSubscriptionRedundancy(std::stoi(value)); |
| } |
| } |
| |
| _GEODE_NEW(cacheCreation_, CacheXmlCreation()); |
| } |
| |
| void CacheXmlParser::startPdx(const xercesc::Attributes &attrs) { |
| auto ignoreUnreadFields = getOptionalAttribute(attrs, IGNORE_UNREAD_FIELDS); |
| if (!ignoreUnreadFields.empty()) { |
| if (equal_ignore_case(ignoreUnreadFields, "true")) { |
| cacheCreation_->setPdxIgnoreUnreadField(true); |
| } else { |
| cacheCreation_->setPdxIgnoreUnreadField(false); |
| } |
| } |
| |
| auto pdxReadSerialized = getOptionalAttribute(attrs, READ_SERIALIZED); |
| if (!pdxReadSerialized.empty()) { |
| if (equal_ignore_case(pdxReadSerialized, "true")) { |
| cacheCreation_->setPdxReadSerialized(true); |
| } else { |
| cacheCreation_->setPdxReadSerialized(false); |
| } |
| } |
| } |
| |
| void CacheXmlParser::startLocator(const xercesc::Attributes &attrs) { |
| poolFactory_ = std::static_pointer_cast<PoolFactory>(_stack.top()); |
| |
| auto host = getRequiredAttribute(attrs, HOST); |
| auto port = getRequiredAttribute(attrs, PORT); |
| |
| poolFactory_->addLocator(host, std::stoi(port)); |
| } |
| |
| void CacheXmlParser::startServer(const xercesc::Attributes &attrs) { |
| auto factory = std::static_pointer_cast<PoolFactory>(_stack.top()); |
| |
| auto host = getRequiredAttribute(attrs, HOST); |
| auto port = getRequiredAttribute(attrs, PORT); |
| |
| factory->addServer(host, std::stoi(port)); |
| } |
| |
| void CacheXmlParser::startPool(const xercesc::Attributes &attrs) { |
| using apache::geode::client::equal_ignore_case; |
| using apache::geode::internal::chrono::duration::from_string; |
| |
| auto factory = |
| std::make_shared<PoolFactory>(cache_->getPoolManager().createFactory()); |
| |
| auto poolName = getRequiredAttribute(attrs, NAME); |
| |
| auto poolxml = std::make_shared<PoolXmlCreation>(poolName, factory); |
| |
| auto freeConnectionTimeout = |
| getOptionalAttribute(attrs, FREE_CONNECTION_TIMEOUT); |
| if (!freeConnectionTimeout.empty()) { |
| factory->setFreeConnectionTimeout( |
| from_string<std::chrono::milliseconds>(freeConnectionTimeout)); |
| } |
| |
| auto multiUserSecureMode = getOptionalAttribute(attrs, MULTIUSER_SECURE_MODE); |
| if (!multiUserSecureMode.empty()) { |
| if (equal_ignore_case(multiUserSecureMode, "true")) { |
| factory->setMultiuserAuthentication(true); |
| } else { |
| factory->setMultiuserAuthentication(false); |
| } |
| } |
| |
| auto idleTimeout = getOptionalAttribute(attrs, IDLE_TIMEOUT); |
| if (!idleTimeout.empty()) { |
| factory->setIdleTimeout( |
| from_string<std::chrono::milliseconds>(idleTimeout)); |
| } |
| |
| auto loadConditioningInterval = |
| getOptionalAttribute(attrs, LOAD_CONDITIONING_INTERVAL); |
| if (!loadConditioningInterval.empty()) { |
| factory->setLoadConditioningInterval( |
| from_string<std::chrono::milliseconds>(loadConditioningInterval)); |
| } |
| |
| auto maxConnections = getOptionalAttribute(attrs, MAX_CONNECTIONS); |
| if (!maxConnections.empty()) { |
| factory->setMaxConnections(atoi(maxConnections.c_str())); |
| } |
| |
| auto minConnections = getOptionalAttribute(attrs, MIN_CONNECTIONS); |
| if (!minConnections.empty()) { |
| factory->setMinConnections(atoi(minConnections.c_str())); |
| } |
| |
| auto pingInterval = getOptionalAttribute(attrs, PING_INTERVAL); |
| if (!pingInterval.empty()) { |
| factory->setPingInterval( |
| from_string<std::chrono::milliseconds>(std::string(pingInterval))); |
| } |
| |
| auto updateLocatorListInterval = |
| getOptionalAttribute(attrs, UPDATE_LOCATOR_LIST_INTERVAL); |
| if (!updateLocatorListInterval.empty()) { |
| factory->setUpdateLocatorListInterval( |
| from_string<std::chrono::milliseconds>(updateLocatorListInterval)); |
| } |
| |
| auto readTimeout = getOptionalAttribute(attrs, READ_TIMEOUT); |
| if (!readTimeout.empty()) { |
| factory->setReadTimeout( |
| from_string<std::chrono::milliseconds>(std::string(readTimeout))); |
| } |
| |
| auto retryAttempts = getOptionalAttribute(attrs, RETRY_ATTEMPTS); |
| if (!retryAttempts.empty()) { |
| factory->setRetryAttempts(atoi(retryAttempts.c_str())); |
| } |
| |
| auto serverGroup = getOptionalAttribute(attrs, SERVER_GROUP); |
| if (!serverGroup.empty()) { |
| factory->setServerGroup(serverGroup); |
| } |
| |
| auto socketBufferSize = getOptionalAttribute(attrs, SOCKET_BUFFER_SIZE); |
| if (!socketBufferSize.empty()) { |
| factory->setSocketBufferSize(atoi(socketBufferSize.c_str())); |
| } |
| |
| auto statisticInterval = getOptionalAttribute(attrs, STATISTIC_INTERVAL); |
| if (!statisticInterval.empty()) { |
| factory->setStatisticInterval( |
| from_string<std::chrono::milliseconds>(statisticInterval)); |
| } |
| |
| auto subscriptionAckInterval = |
| getOptionalAttribute(attrs, SUBSCRIPTION_ACK_INTERVAL); |
| if (!subscriptionAckInterval.empty()) { |
| factory->setSubscriptionAckInterval( |
| from_string<std::chrono::milliseconds>(subscriptionAckInterval)); |
| } |
| |
| auto subscriptionEnabled = getOptionalAttribute(attrs, SUBSCRIPTION_ENABLED); |
| if (!subscriptionEnabled.empty()) { |
| if (equal_ignore_case(subscriptionEnabled, "true")) { |
| factory->setSubscriptionEnabled(true); |
| } else { |
| factory->setSubscriptionEnabled(false); |
| } |
| } |
| |
| auto subscriptionMessageTrackingTimeout = |
| getOptionalAttribute(attrs, SUBSCRIPTION_MTT); |
| if (!subscriptionMessageTrackingTimeout.empty()) { |
| factory->setSubscriptionMessageTrackingTimeout( |
| from_string<std::chrono::milliseconds>( |
| subscriptionMessageTrackingTimeout)); |
| } |
| |
| auto subscriptionRedundancy = |
| getOptionalAttribute(attrs, SUBSCRIPTION_REDUNDANCY); |
| if (!subscriptionRedundancy.empty()) { |
| factory->setSubscriptionRedundancy(atoi(subscriptionRedundancy.c_str())); |
| } |
| |
| auto threadLocalConnections = |
| getOptionalAttribute(attrs, THREAD_LOCAL_CONNECTIONS); |
| if (!threadLocalConnections.empty()) { |
| if (equal_ignore_case(threadLocalConnections, "true")) { |
| factory->setThreadLocalConnections(true); |
| } else { |
| factory->setThreadLocalConnections(false); |
| } |
| } |
| |
| auto prSingleHopEnabled = getOptionalAttribute(attrs, PR_SINGLE_HOP_ENABLED); |
| if (!prSingleHopEnabled.empty()) { |
| if (equal_ignore_case(prSingleHopEnabled, "true")) { |
| factory->setPRSingleHopEnabled(true); |
| } else { |
| factory->setPRSingleHopEnabled(false); |
| } |
| } |
| |
| _stack.push(poolxml); |
| _stack.push(factory); |
| } |
| |
| void CacheXmlParser::endPool() { |
| _stack.pop(); // remove factory |
| auto poolxml = std::static_pointer_cast<PoolXmlCreation>(_stack.top()); |
| _stack.pop(); // remove pool |
| cacheCreation_->addPool(poolxml); |
| } |
| |
| /** |
| * When a <code>region</code> element is first encountered, we |
| * create a {@link RegionCreation} and push it on the _stack. |
| * An {@link RegionAttributesFactory }is also created and puhed on _stack. |
| */ |
| void CacheXmlParser::startRegion(const xercesc::Attributes &attrs) { |
| incNesting(); |
| auto isRoot = isRootLevel(); |
| auto regionName = getRequiredAttribute(attrs, NAME); |
| |
| auto region = std::make_shared<RegionXmlCreation>(regionName, isRoot); |
| if (!region) { |
| throw UnknownException("CacheXmlParser::startRegion:Out of memory"); |
| } |
| |
| _stack.push(region); |
| |
| auto refid = getOptionalAttribute(attrs, REFID); |
| if (!refid.empty()) { |
| if (namedRegions_.find(refid) != namedRegions_.end()) { |
| auto regionAttributesFactory = |
| RegionAttributesFactory(namedRegions_[refid]); |
| region->setAttributes(regionAttributesFactory.create()); |
| } else { |
| throw CacheXmlException("XML:referenced named attribute '" + refid + |
| "' does not exist."); |
| } |
| } |
| } |
| |
| void CacheXmlParser::startRegionAttributes(const xercesc::Attributes &attrs) { |
| bool isDistributed = false; |
| bool isTCR = false; |
| std::shared_ptr<RegionAttributesFactory> regionAttributesFactory = nullptr; |
| |
| if (attrs.getLength() > 24) { |
| throw CacheXmlException( |
| "XML:Too many attributes provided for <region-attributes>"); |
| } |
| |
| if (attrs.getLength() == 0) { |
| auto region = std::static_pointer_cast<RegionXmlCreation>(_stack.top()); |
| regionAttributesFactory = |
| std::make_shared<RegionAttributesFactory>(region->getAttributes()); |
| } else { |
| auto id = getOptionalAttribute(attrs, ID); |
| if (!id.empty()) { |
| auto region = std::static_pointer_cast<RegionXmlCreation>(_stack.top()); |
| region->setAttrId(id); |
| } |
| |
| auto refid = getOptionalAttribute(attrs, REFID); |
| if (refid.empty()) { |
| auto region = std::static_pointer_cast<RegionXmlCreation>(_stack.top()); |
| regionAttributesFactory = |
| std::make_shared<RegionAttributesFactory>(region->getAttributes()); |
| } else { |
| if (namedRegions_.find(refid) != namedRegions_.end()) { |
| regionAttributesFactory = |
| std::make_shared<RegionAttributesFactory>(namedRegions_[refid]); |
| } else { |
| throw CacheXmlException("XML:referenced named attribute '" + refid + |
| "' does not exist."); |
| } |
| } |
| |
| if (!regionAttributesFactory) { |
| throw UnknownException( |
| "CacheXmlParser::startRegionAttributes:Out of memory"); |
| } |
| |
| auto clientNotificationEnabled = |
| getOptionalAttribute(attrs, CLIENT_NOTIFICATION_ENABLED); |
| if (!clientNotificationEnabled.empty()) { |
| bool flag = false; |
| std::transform(clientNotificationEnabled.begin(), |
| clientNotificationEnabled.end(), |
| clientNotificationEnabled.begin(), ::tolower); |
| if ("false" == clientNotificationEnabled) { |
| flag = false; |
| } else if ("true" == clientNotificationEnabled) { |
| flag = true; |
| } else { |
| throw CacheXmlException( |
| "XML: " + clientNotificationEnabled + |
| " is not a valid name for the attribute <client-notification>"); |
| } |
| if (poolFactory_) { |
| poolFactory_->setSubscriptionEnabled(flag); |
| } |
| } |
| |
| auto initialCapacity = getOptionalAttribute(attrs, INITIAL_CAPACITY); |
| if (!initialCapacity.empty()) { |
| regionAttributesFactory->setInitialCapacity(std::stoi(initialCapacity)); |
| } |
| |
| auto concurrencyLevel = getOptionalAttribute(attrs, CONCURRENCY_LEVEL); |
| if (!concurrencyLevel.empty()) { |
| regionAttributesFactory->setConcurrencyLevel(std::stoi(concurrencyLevel)); |
| } |
| |
| auto loadFactor = getOptionalAttribute(attrs, LOAD_FACTOR); |
| if (!loadFactor.empty()) { |
| regionAttributesFactory->setLoadFactor(std::stof(loadFactor)); |
| } |
| |
| auto cachingEnabled = getOptionalAttribute(attrs, CACHING_ENABLED); |
| if (!cachingEnabled.empty()) { |
| bool flag = false; |
| std::transform(cachingEnabled.begin(), cachingEnabled.end(), |
| cachingEnabled.begin(), ::tolower); |
| if ("false" == cachingEnabled) { |
| flag = false; |
| } else if ("true" == cachingEnabled) { |
| flag = true; |
| } else { |
| throw CacheXmlException( |
| "XML: " + cachingEnabled + |
| " is not a valid name for the attribute <caching-enabled>"); |
| } |
| regionAttributesFactory->setCachingEnabled(flag); |
| } |
| |
| auto lruEntriesLimit = getOptionalAttribute(attrs, LRU_ENTRIES_LIMIT); |
| if (!lruEntriesLimit.empty()) { |
| regionAttributesFactory->setLruEntriesLimit(std::stoi(lruEntriesLimit)); |
| } |
| |
| auto diskPolicyString = getOptionalAttribute(attrs, DISK_POLICY); |
| if (!diskPolicyString.empty()) { |
| auto diskPolicy = apache::geode::client::DiskPolicyType::NONE; |
| if (OVERFLOWS == diskPolicyString) { |
| diskPolicy = apache::geode::client::DiskPolicyType::OVERFLOWS; |
| } else if (PERSIST == diskPolicyString) { |
| throw IllegalStateException("Persistence feature is not supported"); |
| } else if (NONE == diskPolicyString) { |
| diskPolicy = apache::geode::client::DiskPolicyType::NONE; |
| } else { |
| throw CacheXmlException( |
| "XML: " + diskPolicyString + |
| " is not a valid name for the attribute <disk-policy>"); |
| } |
| regionAttributesFactory->setDiskPolicy(diskPolicy); |
| } |
| |
| auto endpoints = getOptionalAttribute(attrs, ENDPOINTS); |
| if (!endpoints.empty()) { |
| if (poolFactory_) { |
| for (auto &&endPoint : parseEndPoints(ENDPOINTS)) { |
| poolFactory_->addServer(endPoint.first, endPoint.second); |
| } |
| } |
| isTCR = true; |
| } |
| |
| auto poolName = getOptionalAttribute(attrs, POOL_NAME); |
| if (!poolName.empty()) { |
| regionAttributesFactory->setPoolName(poolName); |
| isTCR = true; |
| } |
| |
| auto cloningEnabled = getOptionalAttribute(attrs, CLONING_ENABLED); |
| if (!cloningEnabled.empty()) { |
| bool flag = false; |
| std::transform(cloningEnabled.begin(), cloningEnabled.end(), |
| cloningEnabled.begin(), ::tolower); |
| |
| if ("false" == cloningEnabled) { |
| flag = false; |
| } else if ("true" == cloningEnabled) { |
| flag = true; |
| } else { |
| throw CacheXmlException("XML: " + cloningEnabled + |
| " is not a valid value for the attribute <" + |
| std::string(CLONING_ENABLED) + ">"); |
| } |
| regionAttributesFactory->setCloningEnabled(flag); |
| isTCR = true; |
| } |
| |
| auto concurrencyChecksEnabled = |
| getOptionalAttribute(attrs, CONCURRENCY_CHECKS_ENABLED); |
| if (!concurrencyChecksEnabled.empty()) { |
| bool flag = false; |
| std::transform(concurrencyChecksEnabled.begin(), |
| concurrencyChecksEnabled.end(), |
| concurrencyChecksEnabled.begin(), ::tolower); |
| if ("false" == concurrencyChecksEnabled) { |
| flag = false; |
| } else if ("true" == concurrencyChecksEnabled) { |
| flag = true; |
| } else { |
| throw CacheXmlException("XML: " + concurrencyChecksEnabled + |
| " is not a valid value for the attribute " |
| "<" + |
| std::string(CONCURRENCY_CHECKS_ENABLED) + ">"); |
| } |
| regionAttributesFactory->setConcurrencyChecksEnabled(flag); |
| } |
| } |
| |
| if (isDistributed && isTCR) { |
| // we don't allow DR+TCR at current stage |
| throw CacheXmlException( |
| "XML:endpoints cannot be defined for distributed region.\n"); |
| } |
| |
| _stack.push(regionAttributesFactory); |
| } |
| |
| void CacheXmlParser::endRegionAttributes() { |
| auto regionAttributesFactory = |
| std::static_pointer_cast<RegionAttributesFactory>(_stack.top()); |
| _stack.pop(); |
| if (!regionAttributesFactory) { |
| throw UnknownException( |
| "CacheXmlParser::endRegion:RegionAttributesFactory is null"); |
| } |
| |
| auto regionAttributes = regionAttributesFactory->create(); |
| |
| auto regionPtr = std::static_pointer_cast<RegionXmlCreation>(_stack.top()); |
| if (!regionPtr) { |
| throw UnknownException("CacheXmlParser::endRegion:Region is null"); |
| } |
| |
| std::string id = regionPtr->getAttrId(); |
| if (id != "") { |
| namedRegions_[id] = regionAttributes; |
| } |
| |
| regionPtr->setAttributes(regionAttributes); |
| } |
| |
| /** |
| * When a <code>expiration-attributes</code> element is first |
| * encountered, we create an {@link ExpirationAttibutes} object from |
| * the element's attributes and push it on the _stack. |
| */ |
| void CacheXmlParser::startExpirationAttributes( |
| const xercesc::Attributes &attrs) { |
| using apache::geode::internal::chrono::duration::from_string; |
| |
| flagExpirationAttribute_ = true; |
| |
| if (attrs.getLength() > 2) { |
| throw CacheXmlException( |
| "XML:Incorrect number of attributes provided for " |
| "<expiration-attributes>"); |
| } |
| |
| ExpirationAction expire = ExpirationAction::INVALID_ACTION; |
| auto action = getOptionalAttribute(attrs, ACTION); |
| if (action.empty()) { |
| throw CacheXmlException( |
| "XML:The attribute <action> of <expiration-attributes> cannot be" |
| "set to empty string. It should either have a action or the " |
| "attribute should be removed. In the latter case the default action " |
| "will be set"); |
| } else if (action == INVALIDATE) { |
| expire = ExpirationAction::INVALIDATE; |
| } else if (action == DESTROY) { |
| expire = ExpirationAction::DESTROY; |
| } else if (action == LOCAL_INVALIDATE) { |
| expire = ExpirationAction::LOCAL_INVALIDATE; |
| } else if (action == LOCAL_DESTROY) { |
| expire = ExpirationAction::LOCAL_DESTROY; |
| } else { |
| throw CacheXmlException("XML: " + action + |
| " is not a valid value for the attribute <action>"); |
| } |
| |
| auto timeOut = getOptionalAttribute(attrs, TIMEOUT); |
| if (timeOut.empty()) { |
| throw CacheXmlException( |
| "XML:Value for attribute <timeout> needs to be specified"); |
| } |
| |
| auto timeOutSeconds = from_string<std::chrono::seconds>(timeOut); |
| |
| auto expireAttr = |
| std::make_shared<ExpirationAttributes>(timeOutSeconds, expire); |
| if (!expireAttr) { |
| throw UnknownException( |
| "CacheXmlParser::startExpirationAttributes:Out of memory"); |
| } |
| expireAttr->setAction(expire); |
| |
| _stack.push(expireAttr); |
| } |
| |
| std::string CacheXmlParser::getLibraryName(const xercesc::Attributes &attrs) { |
| return getRequiredAttribute(attrs, LIBRARY_NAME); |
| } |
| |
| std::string CacheXmlParser::getLibraryFunctionName( |
| const xercesc::Attributes &attrs) { |
| return getRequiredAttribute(attrs, LIBRARY_FUNCTION_NAME); |
| } |
| |
| void CacheXmlParser::startPersistenceManager(const xercesc::Attributes &attrs) { |
| auto libraryName = getLibraryName(attrs); |
| auto libraryFunctionName = getLibraryFunctionName(attrs); |
| |
| verifyFactoryFunction(managedPersistenceManagerFn_, libraryName, |
| libraryFunctionName); |
| |
| _stack.emplace(std::make_shared<std::string>(std::move(libraryName))); |
| _stack.emplace(std::make_shared<std::string>(std::move(libraryFunctionName))); |
| } |
| |
| void CacheXmlParser::startPersistenceProperty( |
| const xercesc::Attributes &attrs) { |
| auto propertyName = getRequiredAttribute(attrs, NAME); |
| auto propertyValue = getRequiredAttribute(attrs, VALUE); |
| |
| if (config_ == nullptr) { |
| config_ = Properties::create(); |
| } |
| |
| config_->insert(propertyName, propertyValue); |
| } |
| |
| void CacheXmlParser::startCacheLoader(const xercesc::Attributes &attrs) { |
| auto libraryName = getLibraryName(attrs); |
| auto libraryFunctionName = getLibraryFunctionName(attrs); |
| |
| verifyFactoryFunction(managedCacheLoaderFn_, libraryName, |
| libraryFunctionName); |
| |
| auto regionAttributesFactory = |
| std::static_pointer_cast<RegionAttributesFactory>(_stack.top()); |
| regionAttributesFactory->setCacheLoader(libraryName, libraryFunctionName); |
| } |
| |
| void CacheXmlParser::startCacheListener(const xercesc::Attributes &attrs) { |
| auto libraryName = getLibraryName(attrs); |
| auto libraryFunctionName = getLibraryFunctionName(attrs); |
| |
| verifyFactoryFunction(managedCacheListenerFn_, libraryName, |
| libraryFunctionName); |
| |
| auto regionAttributesFactory = |
| std::static_pointer_cast<RegionAttributesFactory>(_stack.top()); |
| regionAttributesFactory->setCacheListener(libraryName, libraryFunctionName); |
| } |
| |
| void CacheXmlParser::startPartitionResolver(const xercesc::Attributes &attrs) { |
| auto libraryName = getLibraryName(attrs); |
| auto libraryFunctionName = getLibraryFunctionName(attrs); |
| |
| verifyFactoryFunction(managedPartitionResolverFn_, libraryName, |
| libraryFunctionName); |
| |
| auto regionAttributesFactory = |
| std::static_pointer_cast<RegionAttributesFactory>(_stack.top()); |
| regionAttributesFactory->setPartitionResolver(libraryName, |
| libraryFunctionName); |
| } |
| |
| void CacheXmlParser::startCacheWriter(const xercesc::Attributes &attrs) { |
| auto libraryName = getLibraryName(attrs); |
| auto libraryFunctionName = getLibraryFunctionName(attrs); |
| |
| verifyFactoryFunction(managedCacheWriterFn_, libraryName, |
| libraryFunctionName); |
| |
| auto regionAttributesFactory = |
| std::static_pointer_cast<RegionAttributesFactory>(_stack.top()); |
| regionAttributesFactory->setCacheWriter(libraryName, libraryFunctionName); |
| } |
| |
| /** |
| * After popping the current <code>RegionXmlCreation</code> off the |
| * _stack, if the element on top of the _stack is a |
| * <code>RegionXmlCreation</code>, then it is the parent region. |
| */ |
| void CacheXmlParser::endRegion() { |
| auto isRoot = isRootLevel(); |
| auto regionPtr = std::static_pointer_cast<RegionXmlCreation>(_stack.top()); |
| _stack.pop(); |
| if (isRoot) { |
| if (!_stack.empty()) { |
| throw CacheXmlException("Xml file has incorrectly nested region tags"); |
| } |
| if (!cacheCreation_) { |
| throw CacheXmlException( |
| "XML: Element <cache> was not provided in the xml"); |
| } |
| |
| cacheCreation_->addRootRegion(regionPtr); |
| } else { |
| if (_stack.empty()) { |
| throw CacheXmlException("Xml file has incorrectly nested region tags"); |
| } |
| auto parent = std::static_pointer_cast<RegionXmlCreation>(_stack.top()); |
| parent->addSubregion(regionPtr); |
| } |
| decNesting(); |
| } |
| |
| /** |
| * When a <code>cache</code> element is finished |
| */ |
| void CacheXmlParser::endCache() {} |
| |
| /** |
| * When a <code>region-time-to-live</code> element is finished, the |
| * {@link ExpirationAttributes} are on top of the _stack followed by |
| * the {@link RegionAttributesFactory} to which the expiration |
| * attributes are assigned. |
| */ |
| void CacheXmlParser::endRegionTimeToLive() { |
| if (!flagExpirationAttribute_) { |
| throw CacheXmlException( |
| "XML: <region-time-to-live> cannot be without a " |
| "<expiration-attributes>"); |
| } |
| |
| auto expireAttr = |
| std::static_pointer_cast<ExpirationAttributes>(_stack.top()); |
| _stack.pop(); |
| |
| auto regionAttributesFactory = |
| std::static_pointer_cast<RegionAttributesFactory>(_stack.top()); |
| regionAttributesFactory->setRegionTimeToLive(expireAttr->getAction(), |
| expireAttr->getTimeout()); |
| flagExpirationAttribute_ = false; |
| } |
| |
| /** |
| * When a <code>region-idle-time</code> element is finished, the |
| * {@link ExpirationAttributes} are on top of the _stack followed by |
| * the {@link RegionAttributesFactory} to which the expiration |
| * attributes are assigned. |
| */ |
| void CacheXmlParser::endRegionIdleTime() { |
| if (!flagExpirationAttribute_) { |
| throw CacheXmlException( |
| "XML: <region-idle-time> cannot be without <expiration-attributes>"); |
| } |
| auto expireAttr = |
| std::static_pointer_cast<ExpirationAttributes>(_stack.top()); |
| _stack.pop(); |
| auto regionAttributesFactory = |
| std::static_pointer_cast<RegionAttributesFactory>(_stack.top()); |
| |
| regionAttributesFactory->setRegionIdleTimeout(expireAttr->getAction(), |
| expireAttr->getTimeout()); |
| flagExpirationAttribute_ = false; |
| } |
| |
| /** |
| * When a <code>entry-time-to-live</code> element is finished, the |
| * {@link ExpirationAttributes} are on top of the _stack followed by |
| * the {@link RegionAttributesFactory} to which the expiration |
| * attributes are assigned. |
| */ |
| void CacheXmlParser::endEntryTimeToLive() { |
| if (!flagExpirationAttribute_) { |
| throw CacheXmlException( |
| "XML: <entry-time-to-live> cannot be without <expiration-attributes>"); |
| } |
| auto expireAttr = |
| std::static_pointer_cast<ExpirationAttributes>(_stack.top()); |
| _stack.pop(); |
| auto regionAttributesFactory = |
| std::static_pointer_cast<RegionAttributesFactory>(_stack.top()); |
| |
| regionAttributesFactory->setEntryTimeToLive(expireAttr->getAction(), |
| expireAttr->getTimeout()); |
| flagExpirationAttribute_ = false; |
| } |
| |
| /** |
| * When a <code>entry-idle-time</code> element is finished, the |
| * {@link ExpirationAttributes} are on top of the _stack followed by |
| * the {@link RegionAttributesFactory} to which the expiration |
| * attributes are assigned. |
| */ |
| void CacheXmlParser::endEntryIdleTime() { |
| if (!flagExpirationAttribute_) { |
| throw CacheXmlException( |
| "XML: <entry-idle-time> cannot be without <expiration-attributes>"); |
| } |
| auto expireAttr = |
| std::static_pointer_cast<ExpirationAttributes>(_stack.top()); |
| _stack.pop(); |
| auto regionAttributesFactory = |
| std::static_pointer_cast<RegionAttributesFactory>(_stack.top()); |
| // TODO GEODE-3136: consider string parser here. |
| regionAttributesFactory->setEntryIdleTimeout(expireAttr->getAction(), |
| expireAttr->getTimeout()); |
| flagExpirationAttribute_ = false; |
| } |
| |
| /** |
| * When persistence-manager attributes is finished, it will set the attribute |
| * factory. |
| */ |
| void CacheXmlParser::endPersistenceManager() { |
| std::shared_ptr<std::string> libraryFunctionName = |
| std::static_pointer_cast<std::string>(_stack.top()); |
| _stack.pop(); |
| std::shared_ptr<std::string> libraryName = |
| std::static_pointer_cast<std::string>(_stack.top()); |
| _stack.pop(); |
| auto regionAttributesFactory = |
| std::static_pointer_cast<RegionAttributesFactory>(_stack.top()); |
| if (config_ != nullptr) { |
| regionAttributesFactory->setPersistenceManager( |
| libraryName->c_str(), libraryFunctionName->c_str(), config_); |
| config_ = nullptr; |
| } else { |
| regionAttributesFactory->setPersistenceManager( |
| libraryName->c_str(), libraryFunctionName->c_str()); |
| } |
| } |
| |
| CacheXmlParser::~CacheXmlParser() { _GEODE_SAFE_DELETE(cacheCreation_); } |
| |
| } // namespace client |
| } // namespace geode |
| } // namespace apache |