Skip to content

Commit a966c3d

Browse files
author
Senthil Nathan
committed
TLS for Redis
1 parent 3548100 commit a966c3d

File tree

49 files changed

+7212
-560
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+7212
-560
lines changed

com.ibm.streamsx.dps/impl/Makefile

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ AERO_OBJ =
2222
AERO_LIB =
2323
COUCH_OBJ = CouchbaseDBLayer.o
2424
REDIS_CLUSTER_OBJ = RedisClusterDBLayer.o
25-
26-
25+
REDIS_CLUSTER_PLUS_PLUS_OBJ = RedisClusterPlusPlusDBLayer.o
26+
2727
REDIS_LIB = $(LIB)/libDPSRedis.so
2828
REDIS_CLUSTER_LIB = $(LIB)/libDPSRedisCluster.so
29+
REDIS_CLUSTER_PLUS_PLUS_LIB = $(LIB)/libDPSRedisClusterPlusPlus.so
2930
COUCH_LIB = $(LIB)/libDPSCouchbase.so
3031
HBASE_LIB = $(LIB)/libDPSHBase.so
3132
CASSANDRA_LIB = $(LIB)/libDPSCassandra.so
@@ -34,6 +35,7 @@ MONGO_LIB = $(LIB)/libDPSMongo.so
3435
MEMCACHED_LIB = $(LIB)/libDPSMemcached.so
3536

3637
HELPER_LIBS = $(REDIS_CLUSTER_LIB)
38+
HELPER_LIBS += $(REDIS_CLUSTER_PLUS_PLUS_LIB)
3739
HELPER_LIBS += $(COUCH_LIB)
3840
HELPER_LIBS += $(REDIS_LIB)
3941
HELPER_LIBS += $(HBASE_LIB)
@@ -58,7 +60,7 @@ SPL_COMPILE_OPTIONS = $(shell $(SPL_PKGCFG) --cflags $(SPL_PKG))
5860
SPL_LINK_OPTIONS = $(shell $(SPL_PKGCFG) --libs $(SPL_PKG))
5961

6062
CPPFLAGS =
61-
CPPFLAGS += -O3 -Wall -c -fmessage-length=0 -fPIC -D_REENTRANT
63+
CPPFLAGS += -O3 -Wall -c -fmessage-length=0 -fPIC -D_REENTRANT
6264
CPPFLAGS += -I include
6365
CPPFLAGS += -I nl/include
6466
CPPFLAGS += -isystem ext/include
@@ -91,7 +93,7 @@ all: check-streams $(DISTRIBUTED_PROCESS_STORE_LIB_STATIC) $(DISTRIBUTED_PROCESS
9193
check-streams:
9294
@echo "Checking to see if STREAMS_INSTALL is set..."
9395
test -d $(STREAMS_INSTALL) || false
94-
96+
9597
$(DISTRIBUTED_PROCESS_STORE_LIB): $(DISTRIBUTED_PROCESS_STORE_OBJS)
9698
mkdir -p $(LIB)
9799
$(CXX) $(LDFLAGS) -o $@ $^
@@ -108,40 +110,46 @@ $(DISTRIBUTED_PROCESS_STORE_LIB_STATIC): $(DISTRIBUTED_PROCESS_STORE_OBJS)
108110
$(COUCH_LIB): $(COUCH_OBJ)
109111
mkdir -p $(LIB)
110112
$(CXX) $(LDFLAGS) -o $@ $^
111-
113+
112114
$(REDIS_LIB): $(REDIS_OBJ)
113115
mkdir -p $(LIB)
114116
$(CXX) $(LDFLAGS) -o $@ $^
115-
117+
116118
$(REDIS_CLUSTER_LIB): $(REDIS_CLUSTER_OBJ)
117119
mkdir -p $(LIB)
118120
$(CXX) $(LDFLAGS) -o $@ $^
119-
121+
122+
$(REDIS_CLUSTER_PLUS_PLUS_LIB): CPPFLAGS+=-std=c++11
123+
$(REDIS_CLUSTER_PLUS_PLUS_LIB): $(REDIS_CLUSTER_PLUS_PLUS_OBJ)
124+
mkdir -p $(LIB)
125+
$(CXX) $(LDFLAGS) -o $@ $^
126+
120127
$(HBASE_LIB): $(HBASE_OBJ)
121128
mkdir -p $(LIB)
122129
$(CXX) $(LDFLAGS) -o $@ $^
123130

124131
$(CASSANDRA_LIB): $(CASSANDRA_OBJ)
125132
mkdir -p $(LIB)
126133
$(CXX) $(LDFLAGS) -o $@ $^
127-
134+
128135
$(CLOUDANT_LIB): $(CLOUDANT_OBJ)
129136
mkdir -p $(LIB)
130137
$(CXX) $(LDFLAGS) -o $@ $^
131-
138+
132139
$(MONGO_LIB): $(MONGO_OBJ)
133140
mkdir -p $(LIB)
134141
$(CXX) $(LDFLAGS) -o $@ $^
135142

136143
$(MEMCACHED_LIB): $(MEMCACHED_OBJ)
137144
mkdir -p $(LIB)
138145
$(CXX) $(LDFLAGS) -o $@ $^
139-
146+
140147
clean:
141148
rm -f $(DISTRIBUTED_PROCESS_STORE_OBJS)
142149
rm -f $(DISTRIBUTED_PROCESS_STORE_LIB)
143150
rm -f $(REDIS_LIB) $(REDIS_OBJ)
144151
rm -f $(REDIS_CLUSTER_LIB) $(REDIS_CLUSTER_OBJ)
152+
rm -f $(REDIS_CLUSTER_PLUS_PLUS_LIB) $(REDIS_CLUSTER_PLUS_PLUS_OBJ)
145153
rm -f $(MEMCACHED_LIB) $(MEMCACHED_OBJ)
146154
rm -f $(CLOUDANT_LIB) $(CLOUDANT_OBJ)
147155
rm -f $(CASSANDRA_LIB) $(CASSANDRA_OBJ)

com.ibm.streamsx.dps/impl/include/DpsConstants.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
# Licensed Materials - Property of IBM
3-
# Copyright IBM Corp. 2011, 2016
3+
# Copyright IBM Corp. 2011, 2020
44
# US Government Users Restricted Rights - Use, duplication or
55
# disclosure restricted by GSA ADP Schedule Contract with
66
# IBM Corp.
@@ -93,6 +93,7 @@ interface with many different back-end in-memory stores.
9393
#define COUCHBASE_NO_SQL_DB_NAME "couchbase"
9494
#define AEROSPIKE_NO_SQL_DB_NAME "aerospike"
9595
#define REDIS_CLUSTER_NO_SQL_DB_NAME "redis-cluster"
96+
#define REDIS_CLUSTER_PLUS_PLUS_NO_SQL_DB_NAME "redis-cluster-plus-plus"
9697
#define HTTP_GET "GET"
9798
#define HTTP_PUT "PUT"
9899
#define HTTP_POST "POST"
@@ -228,5 +229,9 @@ interface with many different back-end in-memory stores.
228229
#define DL_LOCK_NOT_FOUND_ERROR 514
229230
#define DL_LOCK_REMOVAL_ERROR 515
230231
#define AEROSPIKE_GET_STORE_ID_ERROR 516
232+
#define REDIS_PLUS_PLUS_NO_ERROR 0
233+
#define REDIS_PLUS_PLUS_CONNECTION_ERROR 1
234+
#define REDIS_PLUS_PLUS_REPLY_ERROR 2
235+
#define REDIS_PLUS_PLUS_OTHER_ERROR 3
231236

232237
#endif /* DPS_CONSTANTS_H_ */
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/*
2+
# Licensed Materials - Property of IBM
3+
# Copyright IBM Corp. 2011, 2020
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_PLUS_PLUS_DB_LAYER_H_
9+
#define REDIS_CLUSTER_PLUS_PLUS_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-plus-plus 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 6 and higher) to provide HA facility for automatic
24+
fail-over when a Redis instance or the entire machine crashes.
25+
In addition, it provides the TLS/SSL support for the redis-cluster.
26+
Please note that this hiredis-cluster-plus-plus wrapper supercedes the older
27+
hiredis-cluster wrapper that we have in the DPS toolkit. If the Redis server
28+
version is v5 and lower, one may continue to use the older hiredis-cluster in DPS.
29+
If the Redis server version is v6 and higher, it is recommented to use the
30+
hiredis-cluster-plus-plus in order to work with both non-TLS and TLS.
31+
32+
The redis-plus-plus wrapper carries the Apache 2.0 copyright as shown in the following line.
33+
34+
A permissive license whose main conditions require preservation of copyright and license notices.
35+
Contributors provide an express grant of patent rights. Licensed works, modifications, and larger
36+
works may be distributed under different terms and without source code.
37+
=====================================================================
38+
*/
39+
#include "DBLayer.h"
40+
41+
#include <tr1/memory>
42+
#include <set>
43+
#include <vector>
44+
#include <sw/redis++/redis_cluster.h>
45+
46+
using namespace sw::redis;
47+
48+
namespace com {
49+
namespace ibm {
50+
namespace streamsx {
51+
namespace store {
52+
namespace distributed
53+
{
54+
class RedisClusterPlusPlusDBLayer;
55+
56+
/// Class that implements the Iterator for Redis cluster
57+
class RedisClusterPlusPlusDBLayerIterator : public DBLayer::Iterator
58+
{
59+
public:
60+
uint64_t store;
61+
std::string storeName;
62+
std::vector<std::string> dataItemKeys;
63+
uint32_t sizeOfDataItemKeysVector;
64+
uint32_t currentIndex;
65+
bool hasData;
66+
RedisClusterPlusPlusDBLayer *redisClusterPlusPlusDBLayerPtr;
67+
68+
RedisClusterPlusPlusDBLayerIterator();
69+
~RedisClusterPlusPlusDBLayerIterator();
70+
bool getNext(uint64_t store, unsigned char * & keyData, uint32_t & keySize,
71+
unsigned char * & valueData, uint32_t & valueSize, PersistenceError & dbError);
72+
};
73+
74+
/// Class that implements the DBLayer for Redis Cluster Plus Plus
75+
class RedisClusterPlusPlusDBLayer : public DBLayer
76+
{
77+
private:
78+
bool readStoreInformation(std::string const & storeIdString, PersistenceError & dbError,
79+
uint32_t & dataItemCnt, std::string & storeName,
80+
std::string & keySplTypeName, std::string & valueSplTypeName);
81+
bool acquireStoreLock(std::string const & storeIdString);
82+
void releaseStoreLock(std::string const & storeIdString);
83+
bool readLockInformation(std::string const & storeIdString, PersistenceError & dbError, uint32_t & lockUsageCnt,
84+
int32_t & lockExpirationTime, pid_t & lockOwningPid, std::string & lockName);
85+
bool updateLockInformation(std::string const & lockIdString, PersistenceError & lkError,
86+
uint32_t const & lockUsageCnt, int32_t const & lockExpirationTime, pid_t const & lockOwningPid);
87+
bool lockIdExistsOrNot(std::string lockIdString, PersistenceError & lkError);
88+
bool acquireGeneralPurposeLock(std::string const & entityName);
89+
void releaseGeneralPurposeLock(std::string const & entityName);
90+
int32_t getRedisServerPartitionIndex(std::string const & key);
91+
92+
public:
93+
RedisCluster *redis_cluster = NULL;
94+
95+
/// Constructor
96+
RedisClusterPlusPlusDBLayer();
97+
98+
/// Destructor
99+
~RedisClusterPlusPlusDBLayer();
100+
101+
// These are inherited from DBLayer, see DBLayer for descriptions
102+
void connectToDatabase(std::set<std::string> const & dbServers, PersistenceError & dbError);
103+
104+
uint64_t createStore(std::string const & name,
105+
std::string const & keySplTypeName,
106+
std::string const & valueSplTypeName,
107+
PersistenceError & dbError);
108+
uint64_t createOrGetStore(std::string const & name,
109+
std::string const & keySplTypeName,
110+
std::string const & valueSplTypeName,
111+
PersistenceError & dbError);
112+
uint64_t findStore(std::string const & name,
113+
PersistenceError & dbError);
114+
bool removeStore(uint64_t store, PersistenceError & dbError);
115+
116+
bool put(uint64_t store, char const * keyData, uint32_t keySize,
117+
unsigned char const * valueData, uint32_t valueSize, PersistenceError & dbError);
118+
bool putSafe(uint64_t store, char const * keyData, uint32_t keySize,
119+
unsigned char const * valueData, uint32_t valueSize, PersistenceError & dbError);
120+
bool putTTL(char const * keyData, uint32_t keySize,
121+
unsigned char const * valueData, uint32_t valueSize, uint32_t ttl, PersistenceError & dbError, bool encodeKey=true, bool encodeValue=true);
122+
bool get(uint64_t store, char const * keyData, uint32_t keySize,
123+
unsigned char * & valueData, uint32_t & valueSize,
124+
PersistenceError & dbError);
125+
bool getSafe(uint64_t store, char const * keyData, uint32_t keySize,
126+
unsigned char * & valueData, uint32_t & valueSize,
127+
PersistenceError & dbError);
128+
bool getTTL(char const * keyData, uint32_t keySize,
129+
unsigned char * & valueData, uint32_t & valueSize,
130+
PersistenceError & dbError, bool encodeKey=true);
131+
bool remove(uint64_t store, char const * keyData, uint32_t keySize, PersistenceError & dbError);
132+
bool removeTTL(char const * keyData, uint32_t keySize, PersistenceError & dbError, bool encodeKey=true);
133+
bool has(uint64_t store, char const * keyData, uint32_t keySize, PersistenceError & dbError);
134+
bool hasTTL(char const * keyData, uint32_t keySize, PersistenceError & dbError, bool encodeKey=true);
135+
void clear(uint64_t store, PersistenceError & dbError);
136+
uint64_t size(uint64_t store, PersistenceError & dbError);
137+
void base64_encode(std::string const & str, std::string & base64);
138+
void base64_decode(std::string & base64, std::string & result);
139+
bool isConnected();
140+
bool reconnect(std::set<std::string> & dbServers, PersistenceError & dbError);
141+
142+
RedisClusterPlusPlusDBLayerIterator * newIterator(uint64_t store, PersistenceError & dbError);
143+
void deleteIterator(uint64_t store, Iterator * iter, PersistenceError & dbError);
144+
bool storeIdExistsOrNot(std::string storeIdString, PersistenceError & dbError);
145+
bool getDataItemFromStore(std::string const & storeIdString,
146+
std::string const & keyDataString, bool const & checkOnlyForDataItemExistence,
147+
bool const & skipDataItemExistenceCheck, unsigned char * & valueData,
148+
uint32_t & valueSize, PersistenceError & dbError);
149+
std::string getStoreName(uint64_t store, PersistenceError & dbError);
150+
std::string getSplTypeNameForKey(uint64_t store, PersistenceError & dbError);
151+
std::string getSplTypeNameForValue(uint64_t store, PersistenceError & dbError);
152+
std::string getNoSqlDbProductName(void);
153+
void getDetailsAboutThisMachine(std::string & machineName, std::string & osVersion, std::string & cpuArchitecture);
154+
bool runDataStoreCommand(std::string const & cmd, PersistenceError & dbError);
155+
bool runDataStoreCommand(uint32_t const & cmdType, std::string const & httpVerb,
156+
std::string const & baseUrl, std::string const & apiEndpoint, std::string const & queryParams,
157+
std::string const & jsonRequest, std::string & jsonResponse, PersistenceError & dbError);
158+
bool runDataStoreCommand(std::vector<std::string> const & cmdList, std::string & resultValue, PersistenceError & dbError);
159+
160+
// Lock related methods.
161+
uint64_t createOrGetLock(std::string const & name, PersistenceError & lkError);
162+
void releaseLock(uint64_t lock, PersistenceError & lkError);
163+
bool acquireLock(uint64_t lock, double leaseTime, double maxWaitTimeToAcquireLock, PersistenceError & lkError);
164+
bool removeLock(uint64_t lock, PersistenceError & lkError);
165+
uint32_t getPidForLock(std::string const & name, PersistenceError & lkError);
166+
void persist(PersistenceError & dbError);
167+
168+
};
169+
} } } } }
170+
#endif /* REDIS_CLUSTER_PLUS_PLUS_DB_LAYER_H_ */

com.ibm.streamsx.dps/impl/include/RedisDBLayer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
# Licensed Materials - Property of IBM
3-
# Copyright IBM Corp. 2011, 2014
3+
# Copyright IBM Corp. 2011, 2020
44
# US Government Users Restricted Rights - Use, duplication or
55
# disclosure restricted by GSA ADP Schedule Contract with
66
# IBM Corp.
@@ -49,6 +49,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4949
#include "DBLayer.h"
5050

5151
#include "hiredis/hiredis.h"
52+
#include "hiredis/hiredis_ssl.h"
5253
#include <tr1/memory>
5354
#include <set>
5455
#include <vector>

com.ibm.streamsx.dps/impl/src/DistributedProcessStore.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
# Licensed Materials - Property of IBM
3-
# Copyright IBM Corp. 2011, 2014
3+
# Copyright IBM Corp. 2011, 2020
44
# US Government Users Restricted Rights - Use, duplication or
55
# disclosure restricted by GSA ADP Schedule Contract with
66
# IBM Corp.
@@ -267,6 +267,7 @@ namespace distributed
267267
void* handle1 = NULL;
268268
void* handle2 = NULL;
269269
void* handle3 = NULL;
270+
void* handle4 = NULL;
270271
bool libraryLoadingError = false;
271272
std::string kvLibName = "";
272273
std::string toolkitDir = ProcessingElement::pe().getToolkitDirectory("com.ibm.streamsx.dps") + "/impl/ext/lib" ;
@@ -278,9 +279,15 @@ namespace distributed
278279
} else if (noSqlKvStoreProductName.compare("redis") == 0) {
279280
handle1 = load_dependent_lib(toolkitDir, "libuv.so");
280281
handle2 = load_dependent_lib(toolkitDir, "libhiredis.so");
282+
// Oct/12/2020 to support "TLS for redis". If the user configures the DPS toolkit to
283+
// use "TLS for redis", then this additional .so file will take care of that need.
284+
// On the IBM Streams application Linux machines, it is a must to install opensssl and
285+
// and openssl-devel RPM packages. The following libhiredis_ssl.so file has a dependency on the
286+
// /lib64/libssl.so and /lib64/libcrypto.so libraries that are part of openssl.
287+
handle3 = load_dependent_lib(toolkitDir, "libhiredis_ssl.so");
281288
kvLibName= "libDPSRedis.so";
282289

283-
if (handle1 == NULL || handle2 == NULL) {
290+
if (handle1 == NULL || handle2 == NULL || handle3 == NULL) {
284291
libraryLoadingError = true;
285292
}
286293
} else if (noSqlKvStoreProductName.compare("cassandra") == 0) {
@@ -344,6 +351,21 @@ namespace distributed
344351
if (handle1 == NULL || handle2 == NULL) {
345352
libraryLoadingError = true;
346353
}
354+
} else if (noSqlKvStoreProductName.compare("redis-cluster-plus-plus") == 0) {
355+
handle1 = load_dependent_lib(toolkitDir, "libuv.so");
356+
handle2 = load_dependent_lib(toolkitDir,"libhiredis.so");
357+
// Oct/12/2020 to support "TLS for redis". If the user configures the DPS toolkit to
358+
// use "TLS for redis", then this additional .so file will take care of that need.
359+
// On the IBM Streams application Linux machines, it is a must to install opensssl and
360+
// and openssl-devel RPM packages. The following libhiredis_ssl.so file has a dependency on the
361+
// /lib64/libssl.so and /lib64/libcrypto.so libraries that are part of openssl.
362+
handle3 = load_dependent_lib(toolkitDir, "libhiredis_ssl.so");
363+
handle4 = load_dependent_lib(toolkitDir, "libredis++.so");
364+
kvLibName= "libDPSRedisClusterPlusPlus.so";
365+
366+
if (handle1 == NULL || handle2 == NULL || handle3 == NULL || handle4 == NULL) {
367+
libraryLoadingError = true;
368+
}
347369
} else {
348370
// Invalid no-sql store product name configured. Abort now.
349371
// SPLAPPLOG is causing it to get stuck in RHEL6/CentOS6 (RHEL7/CentOS7 is fine) when the @catch annotation is used in the calling SPL code.
@@ -381,6 +403,11 @@ namespace distributed
381403
handle3 = NULL;
382404
}
383405

406+
if (handle4 != NULL) {
407+
dlclose(handle4);
408+
handle4 = NULL;
409+
}
410+
384411
if (handle != NULL) {
385412
dlclose(handle);
386413
handle = NULL;
@@ -416,6 +443,11 @@ namespace distributed
416443
handle3 = NULL;
417444
}
418445

446+
if (handle4 != NULL) {
447+
dlclose(handle4);
448+
handle4 = NULL;
449+
}
450+
419451
if (handle != NULL) {
420452
dlclose(handle);
421453
handle = NULL;
@@ -449,6 +481,11 @@ namespace distributed
449481
handle3 = NULL;
450482
}
451483

484+
if (handle4 != NULL) {
485+
dlclose(handle4);
486+
handle4 = NULL;
487+
}
488+
452489
if (handle != NULL) {
453490
dlclose(handle);
454491
handle = NULL;

0 commit comments

Comments
 (0)