summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0010-Remove-Terminated-Event-Subscriptions.patch
blob: 9af5a066be0fa976c1a11226f28fc239fe483315 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
From f665ba085bb2310f008b7534f827fb401ad973c2 Mon Sep 17 00:00:00 2001
From: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
Date: Tue, 12 Oct 2021 08:19:51 +0000
Subject: [PATCH] Delete/Remove Terminated Event Subscription(s)

Added functionality to delete/remove event subscription(s) which are
configured to Terminate after retries.

Currently, when an Event is subscribed with Retry Policy as
"TerminateAfterRetries", the state of the connection is set to
"Terminated" after retrying, but the Subscription is not removed.
This commit adds the functionality to detect terminated connection and
remove the respective subscription.

Tested:
 - Created a Subscription with
   DeliveryRetryPolicy: "TerminateAfterRetries"
 - Received Events successfully on Event listener
 - Once the Event listener was stopped, the Subscription was
   removed/deleted after retries.

Change-Id: If447acb2db74fb29a5d1cfe6194b77cda82bc8a1
Signed-off-by: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com>
---
 http/http_client.hpp                          | 43 +++++++++++++++----
 .../include/event_service_manager.hpp         | 36 ++++++++++++++++
 2 files changed, 70 insertions(+), 9 deletions(-)

diff --git a/http/http_client.hpp b/http/http_client.hpp
index 5e7ff47..54ae2c3 100644
--- a/http/http_client.hpp
+++ b/http/http_client.hpp
@@ -55,6 +55,8 @@ enum class ConnState
     closeInProgress,
     closed,
     suspended,
+    terminate,
+    terminateInProgress,
     terminated,
     abortConnection,
     retry
@@ -288,7 +290,14 @@ class HttpClient : public std::enable_shared_from_this<HttpClient>
     }
     void doClose()
     {
-        state = ConnState::closeInProgress;
+        if (state == ConnState::terminate)
+        {
+            state = ConnState::terminateInProgress;
+        }
+        else if (state != ConnState::suspended)
+        {
+            state = ConnState::closeInProgress;
+        }
 
         // Set the timeout on the tcp stream socket for the async operation
         conn.expires_after(std::chrono::seconds(30));
@@ -318,8 +327,11 @@ class HttpClient : public std::enable_shared_from_this<HttpClient>
                 }
                 self->conn.close();
 
-                if ((self->state != ConnState::suspended) &&
-                    (self->state != ConnState::terminated))
+                if (self->state == ConnState::terminateInProgress)
+                {
+                    self->state = ConnState::terminated;
+                }
+                else if (self->state == ConnState::closeInProgress)
                 {
                     self->state = ConnState::closed;
                     self->handleConnState();
@@ -341,8 +353,11 @@ class HttpClient : public std::enable_shared_from_this<HttpClient>
             }
             conn.close();
 
-            if ((state != ConnState::suspended) &&
-                (state != ConnState::terminated))
+            if (state == ConnState::terminateInProgress)
+            {
+                state = ConnState::terminated;
+            }
+            else if (state == ConnState::closeInProgress)
             {
                 state = ConnState::closed;
                 handleConnState();
@@ -365,8 +380,7 @@ class HttpClient : public std::enable_shared_from_this<HttpClient>
             BMCWEB_LOG_DEBUG << "Retry policy: " << retryPolicyAction;
             if (retryPolicyAction == "TerminateAfterRetries")
             {
-                // TODO: delete subscription
-                state = ConnState::terminated;
+                state = ConnState::terminate;
             }
             if (retryPolicyAction == "SuspendRetries")
             {
@@ -423,6 +437,7 @@ class HttpClient : public std::enable_shared_from_this<HttpClient>
             case ConnState::sendInProgress:
             case ConnState::recvInProgress:
             case ConnState::closeInProgress:
+            case ConnState::terminateInProgress:
             {
                 BMCWEB_LOG_DEBUG << "Async operation is already in progress";
                 break;
@@ -439,7 +454,7 @@ class HttpClient : public std::enable_shared_from_this<HttpClient>
                 break;
             }
             case ConnState::suspended:
-            case ConnState::terminated:
+            case ConnState::terminate:
             {
                 doClose();
                 break;
@@ -506,7 +521,8 @@ class HttpClient : public std::enable_shared_from_this<HttpClient>
     }
     void sendData(const std::string& data)
     {
-        if ((state == ConnState::suspended) || (state == ConnState::terminated))
+        if ((state == ConnState::terminate) ||
+            (state == ConnState::terminated) || (state == ConnState::suspended))
         {
             return;
         }
@@ -524,6 +540,15 @@ class HttpClient : public std::enable_shared_from_this<HttpClient>
         return;
     }
 
+    bool isTerminated()
+    {
+        if (state == ConnState::terminated)
+        {
+            return true;
+        }
+        return false;
+    }
+
     void addHeaders(
         const std::vector<std::pair<std::string, std::string>>& httpHeaders)
     {
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index 6f60a31..363adb0 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -591,6 +591,14 @@ class Subscription : public persistent_data::UserSubscription
         return std::nullopt;
     }
 
+    bool isTerminated()
+    {
+        if (conn != nullptr)
+            return conn->isTerminated();
+
+        return false;
+    }
+
   private:
     std::shared_ptr<crow::SseConnection> sseConn = nullptr;
     uint64_t eventSeqNum;
@@ -847,6 +855,22 @@ class EventServiceManager
         }
     }
 
+    void deleteTerminatedSubcriptions()
+    {
+        boost::container::flat_map<std::string,
+                                   std::shared_ptr<Subscription>>::iterator it =
+            subscriptionsMap.begin();
+        while (it != subscriptionsMap.end())
+        {
+            std::shared_ptr<Subscription> entry = it->second;
+            if (entry->isTerminated())
+            {
+                subscriptionsMap.erase(it);
+            }
+            it++;
+        }
+    }
+
     void updateNoOfSubscribersCount()
     {
         size_t eventLogSubCount = 0;
@@ -881,6 +905,7 @@ class EventServiceManager
 
     std::shared_ptr<Subscription> getSubscription(const std::string& id)
     {
+        deleteTerminatedSubcriptions();
         auto obj = subscriptionsMap.find(id);
         if (obj == subscriptionsMap.end())
         {
@@ -971,6 +996,7 @@ class EventServiceManager
 
     bool isSubscriptionExist(const std::string& id)
     {
+        deleteTerminatedSubcriptions();
         auto obj = subscriptionsMap.find(id);
         if (obj == subscriptionsMap.end())
         {
@@ -1033,6 +1059,7 @@ class EventServiceManager
 
     size_t getNumberOfSubscriptions()
     {
+        deleteTerminatedSubcriptions();
         return subscriptionsMap.size();
     }
 
@@ -1049,6 +1076,7 @@ class EventServiceManager
 
     std::vector<std::string> getAllIDs()
     {
+        deleteTerminatedSubcriptions();
         std::vector<std::string> idList;
         for (const auto& it : subscriptionsMap)
         {
@@ -1059,6 +1087,7 @@ class EventServiceManager
 
     bool isDestinationExist(const std::string& destUrl)
     {
+        deleteTerminatedSubcriptions();
         for (const auto& it : subscriptionsMap)
         {
             std::shared_ptr<Subscription> entry = it.second;
@@ -1073,6 +1102,7 @@ class EventServiceManager
 
     void sendTestEventLog()
     {
+        deleteTerminatedSubcriptions();
         for (const auto& it : this->subscriptionsMap)
         {
             std::shared_ptr<Subscription> entry = it.second;
@@ -1100,6 +1130,8 @@ class EventServiceManager
         }
         eventRecord.push_back(eventMessage);
 
+        deleteTerminatedSubcriptions();
+
         for (const auto& it : this->subscriptionsMap)
         {
             std::shared_ptr<Subscription> entry = it.second;
@@ -1143,6 +1175,8 @@ class EventServiceManager
     }
     void sendBroadcastMsg(const std::string& broadcastMsg)
     {
+        deleteTerminatedSubcriptions();
+
         for (const auto& it : this->subscriptionsMap)
         {
             std::shared_ptr<Subscription> entry = it.second;
@@ -1291,6 +1325,8 @@ class EventServiceManager
             return;
         }
 
+        deleteTerminatedSubcriptions();
+
         for (const auto& it : this->subscriptionsMap)
         {
             std::shared_ptr<Subscription> entry = it.second;
-- 
2.25.1