New listKeys() API to support glob-style key search patterns
[ric-plt/sdl.git] / include / private / redis / asyncredisstorage.hpp
1 /*
2    Copyright (c) 2018-2019 Nokia.
3
4    Licensed under the Apache License, Version 2.0 (the "License");
5    you may not use this file except in compliance with the License.
6    You may obtain a copy of the License at
7
8        http://www.apache.org/licenses/LICENSE-2.0
9
10    Unless required by applicable law or agreed to in writing, software
11    distributed under the License is distributed on an "AS IS" BASIS,
12    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    See the License for the specific language governing permissions and
14    limitations under the License.
15 */
16
17 /*
18  * This source code is part of the near-RT RIC (RAN Intelligent Controller)
19  * platform project (RICP).
20 */
21
22 #ifndef SHAREDDATALAYER_REDIS_ASYNCREDISSTORAGE_HPP_
23 #define SHAREDDATALAYER_REDIS_ASYNCREDISSTORAGE_HPP_
24
25 #include <functional>
26 #include <memory>
27 #include <queue>
28 #include <boost/optional.hpp>
29 #include <sdl/asyncstorage.hpp>
30 #include "private/logger.hpp"
31 #include "private/namespaceconfigurationsimpl.hpp"
32 #include "private/timer.hpp"
33 #include "private/redis/databaseinfo.hpp"
34 #include "private/redis/reply.hpp"
35
36 namespace shareddatalayer
37 {
38     namespace redis
39     {
40         class AsyncCommandDispatcher;
41         class AsyncDatabaseDiscovery;
42         class Reply;
43         struct Contents;
44         class ContentsBuilder;
45     }
46
47     class Engine;
48
49     class AsyncRedisStorage: public AsyncStorage
50     {
51     public:
52         enum class ErrorCode
53         {
54             SUCCESS = 0,
55             REDIS_NOT_YET_DISCOVERED,
56             INVALID_NAMESPACE,
57             //Keep this always as last item. Used in unit tests to loop all enum values.
58             END_MARKER
59         };
60
61         using AsyncCommandDispatcherCreator = std::function<std::shared_ptr<redis::AsyncCommandDispatcher>(Engine& engine,
62                                                                                                            const redis::DatabaseInfo& databaseInfo,
63                                                                                                            std::shared_ptr<redis::ContentsBuilder> contentsBuilder,
64                                                                                                            std::shared_ptr<Logger> logger)>;
65
66         static const std::error_category& errorCategory() noexcept;
67
68         AsyncRedisStorage(const AsyncRedisStorage&) = delete;
69
70         AsyncRedisStorage& operator = (const AsyncRedisStorage&) = delete;
71
72         AsyncRedisStorage(std::shared_ptr<Engine> engine,
73                           std::shared_ptr<redis::AsyncDatabaseDiscovery> discovery,
74                           const boost::optional<PublisherId>& pId,
75                           std::shared_ptr<NamespaceConfigurations> namespaceConfigurations,
76                           std::shared_ptr<Logger> logger);
77
78         AsyncRedisStorage(std::shared_ptr<Engine> engine,
79                           std::shared_ptr<redis::AsyncDatabaseDiscovery> discovery,
80                           const boost::optional<PublisherId>& pId,
81                           std::shared_ptr<NamespaceConfigurations> namespaceConfigurations,
82                           const AsyncCommandDispatcherCreator& asyncCommandDispatcherCreator,
83                           std::shared_ptr<redis::ContentsBuilder> contentsBuilder,
84                           std::shared_ptr<Logger> logger);
85
86         ~AsyncRedisStorage() override;
87
88         int fd() const override;
89
90         void handleEvents() override;
91
92         void waitReadyAsync(const Namespace& ns, const ReadyAck& readyAck) override;
93
94         void setAsync(const Namespace& ns, const DataMap& dataMap, const ModifyAck& modifyAck) override;
95
96         void setIfAsync(const Namespace& ns, const Key& key, const Data& oldData, const Data& newData, const ModifyIfAck& modifyIfAck) override;
97
98         void setIfNotExistsAsync(const Namespace& ns, const Key& key, const Data& data, const ModifyIfAck& modifyIfAck) override;
99
100         void getAsync(const Namespace& ns, const Keys& keys, const GetAck& getAck) override;
101
102         void removeAsync(const Namespace& ns, const Keys& keys, const ModifyAck& modifyAck) override;
103
104         void removeIfAsync(const Namespace& ns, const Key& key, const Data& data, const ModifyIfAck& modifyIfAck) override;
105
106         void findKeysAsync(const Namespace& ns, const std::string& keyPrefix, const FindKeysAck& findKeysAck) override;
107
108         void listKeys(const Namespace& ns, const std::string& pattern, const FindKeysAck& findKeysAck) override;
109
110         void removeAllAsync(const Namespace& ns, const ModifyAck& modifyAck) override;
111
112         redis::DatabaseInfo& getDatabaseInfo();
113
114         std::string buildKeyPrefixSearchPattern(const Namespace& ns, const std::string& keyPrefix) const;
115
116         std::string buildNamespaceKeySearchPattern(const Namespace& ns, const std::string& pattern) const;
117
118     private:
119         std::shared_ptr<Engine> engine;
120         std::shared_ptr<redis::AsyncCommandDispatcher> dispatcher;
121         std::shared_ptr<redis::AsyncDatabaseDiscovery> discovery;
122         const boost::optional<PublisherId> publisherId;
123         ReadyAck readyAck;
124         AsyncCommandDispatcherCreator asyncCommandDispatcherCreator;
125         std::shared_ptr<redis::ContentsBuilder> contentsBuilder;
126         redis::DatabaseInfo dbInfo;
127         std::shared_ptr<NamespaceConfigurations> namespaceConfigurations;
128         std::shared_ptr<Logger> logger;
129
130         bool canOperationBePerformed(const Namespace& ns, boost::optional<bool> inputDataIsEmpty, std::error_code& ecToReturn);
131
132         void serviceStateChanged(const redis::DatabaseInfo& databaseInfo);
133
134         std::string getPublishMessage() const;
135
136         void modificationCommandCallback(const std::error_code& error, const redis::Reply&, const ModifyAck&);
137
138         void conditionalCommandCallback(const std::error_code& error, const redis::Reply&, const ModifyIfAck&);
139
140         void findKeys(const std::string& ns, const std::string& keyPattern, const FindKeysAck& findKeysAck);
141     };
142
143     AsyncRedisStorage::ErrorCode& operator++ (AsyncRedisStorage::ErrorCode& ecEnum);
144     std::error_code make_error_code(AsyncRedisStorage::ErrorCode errorCode);
145 }
146
147 namespace std
148 {
149     template <>
150     struct is_error_code_enum<shareddatalayer::AsyncRedisStorage::ErrorCode>: public true_type { };
151 }
152
153 #endif