|
| 1 | +/* |
| 2 | +# Licensed Materials - Property of IBM |
| 3 | +# Copyright IBM Corp. 2011, 2015 |
| 4 | +# US Government Users Restricted Rights - Use, duplication or |
| 5 | +# disclosure restricted by GSA ADP Schedule Contract with |
| 6 | +# IBM Corp. |
| 7 | +*/ |
| 8 | +#ifndef REDIS_CLUSTER_DB_LAYER_H_ |
| 9 | +#define REDIS_CLUSTER_DB_LAYER_H_ |
| 10 | +/* |
| 11 | +===================================================================== |
| 12 | +Here is the copyright statement for our use of the hiredis APIs: |
| 13 | +
|
| 14 | +Hiredis was written by Salvatore Sanfilippo (antirez at gmail) and |
| 15 | +Pieter Noordhuis (pcnoordhuis at gmail) and is released under the |
| 16 | +BSD license. |
| 17 | +
|
| 18 | +Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com> |
| 19 | +Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> |
| 20 | +
|
| 21 | +hiredis-cluster include files provide wrappers on top of the hiredis library. |
| 22 | +This wrapper allows us to use the familiar hiredis APIs in the context of |
| 23 | +a Redis cluster (Version 3 and higher) to provide HA facility for automatic |
| 24 | +fail-over when a Redis instance or the entire machine crashes. |
| 25 | +This wrapper carries the copyright as shown in the following line. |
| 26 | +
|
| 27 | +Copyright (c) 2015, Dmitrii Shinkevich <shinmail at gmail dot com> |
| 28 | +
|
| 29 | +All rights reserved. |
| 30 | +
|
| 31 | +Redistribution and use in source and binary forms, with or without |
| 32 | +modification, are permitted provided that the following conditions are met: |
| 33 | +
|
| 34 | +* Redistributions of source code must retain the above copyright notice, |
| 35 | + this list of conditions and the following disclaimer. |
| 36 | +
|
| 37 | +* Redistributions in binary form must reproduce the above copyright notice, |
| 38 | + this list of conditions and the following disclaimer in the documentation |
| 39 | + and/or other materials provided with the distribution. |
| 40 | +
|
| 41 | +* Neither the name of Redis nor the names of its contributors may be used |
| 42 | + to endorse or promote products derived from this software without specific |
| 43 | + prior written permission. |
| 44 | +
|
| 45 | +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| 46 | +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 47 | +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 48 | +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR |
| 49 | +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 50 | +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 51 | +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| 52 | +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 53 | +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 54 | +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 55 | +===================================================================== |
| 56 | +*/ |
| 57 | +#include "DBLayer.h" |
| 58 | + |
| 59 | +#include "hiredis.h" |
| 60 | +#include "hiredis-cluster/cluster.h" |
| 61 | +#include "hiredis-cluster/hirediscommand.h" |
| 62 | +#include <tr1/memory> |
| 63 | +#include <set> |
| 64 | +#include <vector> |
| 65 | + |
| 66 | +using namespace RedisCluster; |
| 67 | + |
| 68 | +namespace com { |
| 69 | +namespace ibm { |
| 70 | +namespace streamsx { |
| 71 | +namespace store { |
| 72 | +namespace distributed |
| 73 | +{ |
| 74 | + class RedisClusterDBLayer; |
| 75 | + |
| 76 | + /// Class that implements the Iterator for Redis cluster |
| 77 | + class RedisClusterDBLayerIterator : public DBLayer::Iterator |
| 78 | + { |
| 79 | + public: |
| 80 | + uint64_t store; |
| 81 | + std::string storeName; |
| 82 | + std::vector<std::string> dataItemKeys; |
| 83 | + uint32_t sizeOfDataItemKeysVector; |
| 84 | + uint32_t currentIndex; |
| 85 | + bool hasData; |
| 86 | + Cluster<redisContext>::ptr_t redis_cluster; |
| 87 | + redisReply *redis_cluster_reply; |
| 88 | + RedisClusterDBLayer *redisClusterDBLayerPtr; |
| 89 | + |
| 90 | + RedisClusterDBLayerIterator(); |
| 91 | + ~RedisClusterDBLayerIterator(); |
| 92 | + bool getNext(uint64_t store, unsigned char * & keyData, uint32_t & keySize, |
| 93 | + unsigned char * & valueData, uint32_t & valueSize, PersistenceError & dbError); |
| 94 | + }; |
| 95 | + |
| 96 | + /// Class that implements the DBLayer for Redis |
| 97 | + class RedisClusterDBLayer : public DBLayer |
| 98 | + { |
| 99 | + private: |
| 100 | + Cluster<redisContext>::ptr_t redis_cluster; |
| 101 | + redisReply *redis_cluster_reply; |
| 102 | + |
| 103 | + |
| 104 | + bool readStoreInformation(std::string const & storeIdString, PersistenceError & dbError, |
| 105 | + uint32_t & dataItemCnt, std::string & storeName, |
| 106 | + std::string & keySplTypeName, std::string & valueSplTypeName); |
| 107 | + bool acquireStoreLock(std::string const & storeIdString); |
| 108 | + void releaseStoreLock(std::string const & storeIdString); |
| 109 | + bool readLockInformation(std::string const & storeIdString, PersistenceError & dbError, uint32_t & lockUsageCnt, |
| 110 | + int32_t & lockExpirationTime, pid_t & lockOwningPid, std::string & lockName); |
| 111 | + bool updateLockInformation(std::string const & lockIdString, PersistenceError & lkError, |
| 112 | + uint32_t const & lockUsageCnt, int32_t const & lockExpirationTime, pid_t const & lockOwningPid); |
| 113 | + bool lockIdExistsOrNot(std::string lockIdString, PersistenceError & lkError); |
| 114 | + bool acquireGeneralPurposeLock(std::string const & entityName); |
| 115 | + void releaseGeneralPurposeLock(std::string const & entityName); |
| 116 | + int32_t getRedisServerPartitionIndex(std::string const & key); |
| 117 | + |
| 118 | + public: |
| 119 | + /// Constructor |
| 120 | + RedisClusterDBLayer(); |
| 121 | + |
| 122 | + /// Destructor |
| 123 | + ~RedisClusterDBLayer(); |
| 124 | + |
| 125 | + // These are inherited from DBLayer, see DBLayer for descriptions |
| 126 | + void connectToDatabase(std::set<std::string> const & dbServers, PersistenceError & dbError); |
| 127 | + |
| 128 | + uint64_t createStore(std::string const & name, |
| 129 | + std::string const & keySplTypeName, |
| 130 | + std::string const & valueSplTypeName, |
| 131 | + PersistenceError & dbError); |
| 132 | + uint64_t createOrGetStore(std::string const & name, |
| 133 | + std::string const & keySplTypeName, |
| 134 | + std::string const & valueSplTypeName, |
| 135 | + PersistenceError & dbError); |
| 136 | + uint64_t findStore(std::string const & name, |
| 137 | + PersistenceError & dbError); |
| 138 | + bool removeStore(uint64_t store, PersistenceError & dbError); |
| 139 | + |
| 140 | + bool put(uint64_t store, char const * keyData, uint32_t keySize, |
| 141 | + unsigned char const * valueData, uint32_t valueSize, PersistenceError & dbError); |
| 142 | + bool putSafe(uint64_t store, char const * keyData, uint32_t keySize, |
| 143 | + unsigned char const * valueData, uint32_t valueSize, PersistenceError & dbError); |
| 144 | + bool putTTL(char const * keyData, uint32_t keySize, |
| 145 | + unsigned char const * valueData, uint32_t valueSize, uint32_t ttl, PersistenceError & dbError); |
| 146 | + bool get(uint64_t store, char const * keyData, uint32_t keySize, |
| 147 | + unsigned char * & valueData, uint32_t & valueSize, |
| 148 | + PersistenceError & dbError); |
| 149 | + bool getSafe(uint64_t store, char const * keyData, uint32_t keySize, |
| 150 | + unsigned char * & valueData, uint32_t & valueSize, |
| 151 | + PersistenceError & dbError); |
| 152 | + bool getTTL(char const * keyData, uint32_t keySize, |
| 153 | + unsigned char * & valueData, uint32_t & valueSize, |
| 154 | + PersistenceError & dbError); |
| 155 | + bool remove(uint64_t store, char const * keyData, uint32_t keySize, PersistenceError & dbError); |
| 156 | + bool removeTTL(char const * keyData, uint32_t keySize, PersistenceError & dbError); |
| 157 | + bool has(uint64_t store, char const * keyData, uint32_t keySize, PersistenceError & dbError); |
| 158 | + bool hasTTL(char const * keyData, uint32_t keySize, PersistenceError & dbError); |
| 159 | + void clear(uint64_t store, PersistenceError & dbError); |
| 160 | + uint64_t size(uint64_t store, PersistenceError & dbError); |
| 161 | + void base64_encode(std::string const & str, std::string & base64); |
| 162 | + void base64_decode(std::string & base64, std::string & result); |
| 163 | + RedisClusterDBLayerIterator * newIterator(uint64_t store, PersistenceError & dbError); |
| 164 | + void deleteIterator(uint64_t store, Iterator * iter, PersistenceError & dbError); |
| 165 | + bool storeIdExistsOrNot(std::string storeIdString, PersistenceError & dbError); |
| 166 | + bool getDataItemFromStore(std::string const & storeIdString, |
| 167 | + std::string const & keyDataString, bool const & checkOnlyForDataItemExistence, |
| 168 | + bool const & skipDataItemExistenceCheck, unsigned char * & valueData, |
| 169 | + uint32_t & valueSize, PersistenceError & dbError); |
| 170 | + std::string getStoreName(uint64_t store, PersistenceError & dbError); |
| 171 | + std::string getSplTypeNameForKey(uint64_t store, PersistenceError & dbError); |
| 172 | + std::string getSplTypeNameForValue(uint64_t store, PersistenceError & dbError); |
| 173 | + std::string getNoSqlDbProductName(void); |
| 174 | + void getDetailsAboutThisMachine(std::string & machineName, std::string & osVersion, std::string & cpuArchitecture); |
| 175 | + bool runDataStoreCommand(std::string const & cmd, PersistenceError & dbError); |
| 176 | + bool runDataStoreCommand(uint32_t const & cmdType, std::string const & httpVerb, |
| 177 | + std::string const & baseUrl, std::string const & apiEndpoint, std::string const & queryParams, |
| 178 | + std::string const & jsonRequest, std::string & jsonResponse, PersistenceError & dbError); |
| 179 | + |
| 180 | + // Lock related methods. |
| 181 | + uint64_t createOrGetLock(std::string const & name, PersistenceError & lkError); |
| 182 | + void releaseLock(uint64_t lock, PersistenceError & lkError); |
| 183 | + bool acquireLock(uint64_t lock, double leaseTime, double maxWaitTimeToAcquireLock, PersistenceError & lkError); |
| 184 | + bool removeLock(uint64_t lock, PersistenceError & lkError); |
| 185 | + uint32_t getPidForLock(std::string const & name, PersistenceError & lkError); |
| 186 | + |
| 187 | + }; |
| 188 | +} } } } } |
| 189 | +#endif /* REDIS_CLUSTER_DB_LAYER_H_ */ |
0 commit comments