blob: b756473aaea3b9983feef470f85dd5c047a465b7 [file] [log] [blame]
Rolf Badorekef2bf512019-08-20 11:17:15 +03001/*
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#ifndef SHAREDDATALAYER_REDIS_ASYNCREDISSTORAGE_HPP_
18#define SHAREDDATALAYER_REDIS_ASYNCREDISSTORAGE_HPP_
19
20#include <functional>
21#include <memory>
22#include <queue>
23#include <boost/optional.hpp>
24#include <sdl/asyncstorage.hpp>
25#include "private/logger.hpp"
26#include "private/namespaceconfigurationsimpl.hpp"
27#include "private/timer.hpp"
28#include "private/redis/databaseinfo.hpp"
29#include "private/redis/reply.hpp"
30
31namespace shareddatalayer
32{
33 namespace redis
34 {
35 class AsyncCommandDispatcher;
36 class AsyncDatabaseDiscovery;
37 class Reply;
38 struct Contents;
39 class ContentsBuilder;
40 }
41
42 class Engine;
43
44 class AsyncRedisStorage: public AsyncStorage
45 {
46 public:
47 enum class ErrorCode
48 {
49 SUCCESS = 0,
50 REDIS_NOT_YET_DISCOVERED,
51 INVALID_NAMESPACE,
52 //Keep this always as last item. Used in unit tests to loop all enum values.
53 END_MARKER
54 };
55
56 using AsyncCommandDispatcherCreator = std::function<std::shared_ptr<redis::AsyncCommandDispatcher>(Engine& engine,
57 const redis::DatabaseInfo& databaseInfo,
58 std::shared_ptr<redis::ContentsBuilder> contentsBuilder,
59 std::shared_ptr<Logger> logger)>;
60
61 static const std::error_category& errorCategory() noexcept;
62
63 AsyncRedisStorage(const AsyncRedisStorage&) = delete;
64
65 AsyncRedisStorage& operator = (const AsyncRedisStorage&) = delete;
66
67 AsyncRedisStorage(std::shared_ptr<Engine> engine,
68 std::shared_ptr<redis::AsyncDatabaseDiscovery> discovery,
69 const boost::optional<PublisherId>& pId,
70 std::shared_ptr<NamespaceConfigurations> namespaceConfigurations,
71 std::shared_ptr<Logger> logger);
72
73 AsyncRedisStorage(std::shared_ptr<Engine> engine,
74 std::shared_ptr<redis::AsyncDatabaseDiscovery> discovery,
75 const boost::optional<PublisherId>& pId,
76 std::shared_ptr<NamespaceConfigurations> namespaceConfigurations,
77 const AsyncCommandDispatcherCreator& asyncCommandDispatcherCreator,
78 std::shared_ptr<redis::ContentsBuilder> contentsBuilder,
79 std::shared_ptr<Logger> logger);
80
81 ~AsyncRedisStorage() override;
82
83 int fd() const override;
84
85 void handleEvents() override;
86
87 void waitReadyAsync(const Namespace& ns, const ReadyAck& readyAck) override;
88
89 void setAsync(const Namespace& ns, const DataMap& dataMap, const ModifyAck& modifyAck) override;
90
91 void setIfAsync(const Namespace& ns, const Key& key, const Data& oldData, const Data& newData, const ModifyIfAck& modifyIfAck) override;
92
93 void setIfNotExistsAsync(const Namespace& ns, const Key& key, const Data& data, const ModifyIfAck& modifyIfAck) override;
94
95 void getAsync(const Namespace& ns, const Keys& keys, const GetAck& getAck) override;
96
97 void removeAsync(const Namespace& ns, const Keys& keys, const ModifyAck& modifyAck) override;
98
99 void removeIfAsync(const Namespace& ns, const Key& key, const Data& data, const ModifyIfAck& modifyIfAck) override;
100
101 void findKeysAsync(const Namespace& ns, const std::string& keyPrefix, const FindKeysAck& findKeysAck) override;
102
103 void removeAllAsync(const Namespace& ns, const ModifyAck& modifyAck) override;
104
105 redis::DatabaseInfo& getDatabaseInfo();
106
107 std::string buildKeyPrefixSearchPattern(const Namespace& ns, const std::string& keyPrefix) const;
108
109 private:
110 std::shared_ptr<Engine> engine;
111 std::shared_ptr<redis::AsyncCommandDispatcher> dispatcher;
112 std::shared_ptr<redis::AsyncDatabaseDiscovery> discovery;
113 const boost::optional<PublisherId> publisherId;
114 ReadyAck readyAck;
115 AsyncCommandDispatcherCreator asyncCommandDispatcherCreator;
116 std::shared_ptr<redis::ContentsBuilder> contentsBuilder;
117 redis::DatabaseInfo dbInfo;
118 std::shared_ptr<NamespaceConfigurations> namespaceConfigurations;
119 std::shared_ptr<Logger> logger;
120
121 bool canOperationBePerformed(const Namespace& ns, boost::optional<bool> inputDataIsEmpty, std::error_code& ecToReturn);
122
123 void serviceStateChanged(const redis::DatabaseInfo& databaseInfo);
124
125 std::string getPublishMessage() const;
126
127 void modificationCommandCallback(const std::error_code& error, const redis::Reply&, const ModifyAck&);
128
129 void conditionalCommandCallback(const std::error_code& error, const redis::Reply&, const ModifyIfAck&);
130 };
131
132 AsyncRedisStorage::ErrorCode& operator++ (AsyncRedisStorage::ErrorCode& ecEnum);
133 std::error_code make_error_code(AsyncRedisStorage::ErrorCode errorCode);
134}
135
136namespace std
137{
138 template <>
139 struct is_error_code_enum<shareddatalayer::AsyncRedisStorage::ErrorCode>: public true_type { };
140}
141
142#endif