"Fossies" - the Fresh Open Source Software Archive 
Member "netxms-3.8.166/src/server/core/ua_notification_item.cpp" (23 Feb 2021, 9882 Bytes) of package /linux/misc/netxms-3.8.166.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "ua_notification_item.cpp" see the
Fossies "Dox" file reference documentation.
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2019-2020 Raden Solutions
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: ua_notification_item.cpp
20 **
21 **/
22
23 #include "nxcore.h"
24
25 Mutex g_userAgentNotificationListMutex;
26 ObjectArray<UserAgentNotificationItem> g_userAgentNotificationList(0, 16, Ownership::True);
27
28 /**
29 * Init user agent messages
30 */
31 void InitUserAgentNotifications()
32 {
33 DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
34
35 DB_RESULT hResult = DBSelect(hdb, _T("SELECT id,message,objects,start_time,end_time,recall,on_startup,creation_time,created_by FROM user_agent_notifications"));
36 if (hResult != nullptr)
37 {
38 int count = DBGetNumRows(hResult);
39 for(int i = 0; i < count; i++)
40 {
41 g_userAgentNotificationList.add(new UserAgentNotificationItem(hResult, i));
42 }
43 DBFreeResult(hResult);
44 }
45 DBConnectionPoolReleaseConnection(hdb);
46 DbgPrintf(2, _T("%d user agent messages loaded"), g_userAgentNotificationList.size());
47 }
48
49 /**
50 * Delete expired user agent notifications
51 */
52 void DeleteExpiredUserAgentNotifications(DB_HANDLE hdb, UINT32 retentionTime)
53 {
54 g_userAgentNotificationListMutex.lock();
55 time_t now = time(nullptr);
56 Iterator<UserAgentNotificationItem> *it = g_userAgentNotificationList.iterator();
57 while (it->hasNext())
58 {
59 UserAgentNotificationItem *uan = it->next();
60 if((now - uan->getEndTime()) >= retentionTime && uan->hasNoRef())
61 {
62 it->remove();
63 break;
64 }
65 }
66 delete it;
67 g_userAgentNotificationListMutex.unlock();
68
69 TCHAR query[256];
70 _sntprintf(query, sizeof(query) / sizeof(TCHAR), _T("DELETE FROM user_agent_notifications WHERE end_time>=") INT64_FMT,
71 static_cast<INT64>(now - retentionTime));
72 DBQuery(hdb, query);
73
74 _sntprintf(query, sizeof(query) / sizeof(TCHAR), _T("DELETE FROM user_agent_notifications WHERE creation_time>=") INT64_FMT _T(" AND end_time=0"),
75 static_cast<INT64>(now - retentionTime));
76 DBQuery(hdb, query);
77 }
78
79 void FillUserAgentNotificationsAll(NXCPMessage *msg, Node *node)
80 {
81 g_userAgentNotificationListMutex.lock();
82 int base = VID_UA_NOTIFICATION_BASE;
83 time_t now = time(nullptr);
84 int count = 0;
85 for (int i = 0; i < g_userAgentNotificationList.size(); i++)
86 {
87 UserAgentNotificationItem *uan = g_userAgentNotificationList.get(i);
88 if ((uan->getEndTime() >= now) && !uan->isRecalled() && uan->isApplicable(node->getId()))
89 {
90 uan->fillMessage(base, msg, false);
91 base += 10;
92 count++;
93 }
94 }
95 msg->setField(VID_UA_NOTIFICATION_COUNT, count);
96 g_userAgentNotificationListMutex.unlock();
97 }
98
99 /**
100 * Create new user agent notification
101 */
102 UserAgentNotificationItem *CreateNewUserAgentNotification(const TCHAR *message, const IntegerArray<uint32_t>& objects, time_t startTime, time_t endTime, bool onStartup, uint32_t userId)
103 {
104 g_userAgentNotificationListMutex.lock();
105 UserAgentNotificationItem *uan = new UserAgentNotificationItem(message, objects, startTime, endTime, onStartup, userId);
106 g_userAgentNotificationList.add(uan);
107 uan->incRefCount();
108 uan->incRefCount();
109 g_userAgentNotificationListMutex.unlock();
110
111 ThreadPoolExecute(g_clientThreadPool, uan, &UserAgentNotificationItem::processUpdate);
112 NotifyClientSessions(NX_NOTIFY_USER_AGENT_MESSAGE_CHANGED, uan->getId());
113 return uan;
114 }
115
116 /**
117 * Create user agent message form database
118 */
119 UserAgentNotificationItem::UserAgentNotificationItem(DB_RESULT result, int row) : m_objects(64, 64)
120 {
121 m_id = DBGetFieldULong(result, row, 0);
122 DBGetField(result, row, 1, m_message, MAX_USER_AGENT_MESSAGE_SIZE);
123
124 TCHAR objectList[MAX_DB_STRING];
125 DBGetField(result, row, 2, objectList, MAX_DB_STRING);
126 int count;
127 TCHAR **ids = SplitString(objectList, _T(','), &count);
128 for(int i = 0; i < count; i++)
129 {
130 m_objects.add(_tcstoul(ids[i], nullptr, 10));
131 MemFree(ids[i]);
132 }
133 MemFree(ids);
134
135 m_startTime = DBGetFieldLong(result, row, 3);
136 m_endTime = DBGetFieldLong(result, row, 4);
137 m_recall = DBGetFieldLong(result, row, 5) ? true : false;
138 m_onStartup = DBGetFieldLong(result, row, 6) ? true : false;
139 m_creationTime = DBGetFieldLong(result, row, 7);
140 m_creatorId = DBGetFieldLong(result, row, 8);
141 m_refCount = 0;
142 }
143
144 /**
145 * Create new user agent message
146 */
147 UserAgentNotificationItem::UserAgentNotificationItem(const TCHAR *message, const IntegerArray<uint32_t>& objects, time_t startTime, time_t endTime, bool startup, uint32_t userId) : m_objects(objects)
148 {
149 m_id = CreateUniqueId(IDG_UA_MESSAGE);
150 _tcslcpy(m_message, message, MAX_USER_AGENT_MESSAGE_SIZE);
151 m_startTime = startTime;
152 m_endTime = endTime;
153 m_recall = false;
154 m_onStartup = startup;
155 m_refCount = 0;
156 m_creationTime = time(nullptr);
157 m_creatorId = userId;
158 }
159
160 /**
161 * Check if user agent message is applicable on the node
162 */
163 bool UserAgentNotificationItem::isApplicable(uint32_t nodeId) const
164 {
165 for (int i = 0; i < m_objects.size(); i++)
166 {
167 uint32_t id = m_objects.get(i);
168 if ((id == nodeId) || IsParentObject(id, nodeId))
169 return true;
170 }
171 return false;
172 }
173
174 /**
175 * Check if object is node - then send update, if container - iterate over children
176 */
177 static void SendUpdate(NXCPMessage *msg, NetObj *object)
178 {
179 if (object->getObjectClass() == OBJECT_NODE)
180 {
181 if ((static_cast<Node*>(object)->getCapabilities() & NC_HAS_USER_AGENT) == 0)
182 return;
183
184 shared_ptr<AgentConnectionEx> conn = static_cast<Node *>(object)->getAgentConnection(false);
185 if (conn != nullptr)
186 {
187 msg->setId(conn->generateRequestId());
188 conn->sendMessage(msg);
189 }
190 }
191 else
192 {
193 SharedObjectArray<NetObj> *children = object->getChildren();
194 for(int i = 0; i < children->size(); i++)
195 {
196 SendUpdate(msg, children->get(i));
197 }
198 delete children;
199 }
200 }
201
202 /**
203 * Method called on user agent message creation or update(recall)
204 */
205 void UserAgentNotificationItem::processUpdate()
206 {
207 NXCPMessage msg;
208 msg.setCode(m_recall ? CMD_RECALL_UA_NOTIFICATION : CMD_ADD_UA_NOTIFICATION);
209 fillMessage(VID_UA_NOTIFICATION_BASE, &msg, false);
210
211 //create and fill message
212 for (int i = 0; i < m_objects.size(); i++)
213 {
214 shared_ptr<NetObj> object = FindObjectById(m_objects.get(i));
215 if (object != nullptr)
216 SendUpdate(&msg, object.get());
217 }
218
219 saveToDatabase();
220 decRefCount();
221 }
222
223 /**
224 * Fill message with user agent message data
225 */
226 void UserAgentNotificationItem::fillMessage(UINT32 base, NXCPMessage *msg, bool fullInfo) const
227 {
228 msg->setField(base, m_id);
229 msg->setField(base + 1, m_message);
230 msg->setFieldFromTime(base + 2, m_startTime);
231 msg->setFieldFromTime(base + 3, m_endTime);
232 msg->setField(base + 4, m_onStartup);
233 if (fullInfo) // do not send info to agent
234 {
235 msg->setFieldFromInt32Array(base + 5, &m_objects);
236 msg->setField(base + 6, m_recall);
237 msg->setFieldFromTime(base + 7, m_creationTime);
238 msg->setField(base + 8, m_creatorId);
239 }
240 }
241
242 /**
243 * Save object to database
244 */
245 void UserAgentNotificationItem::saveToDatabase()
246 {
247 DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
248
249 static const TCHAR *columns[] = {
250 _T("message"), _T("objects"), _T("start_time"), _T("end_time"), _T("recall"), _T("on_startup"),
251 _T("creation_time"), _T("created_by"), nullptr
252 };
253
254 DB_STATEMENT hStmt = DBPrepareMerge(hdb, _T("user_agent_notifications"), _T("id"), m_id, columns);
255 if (hStmt != nullptr)
256 {
257 DBBind(hStmt, 1, DB_SQLTYPE_VARCHAR, m_message, MAX_USER_AGENT_MESSAGE_SIZE);
258
259 StringBuffer buffer;
260 for(int i = 0; i < m_objects.size(); i++)
261 {
262 if (buffer.length() > 0)
263 buffer.append(_T(','));
264 buffer.append(m_objects.get(i));
265 }
266 DBBind(hStmt, 2, DB_SQLTYPE_VARCHAR, buffer, MAX_USER_AGENT_MESSAGE_SIZE);
267 DBBind(hStmt, 3, DB_SQLTYPE_INTEGER, static_cast<uint32_t>(m_startTime));
268 DBBind(hStmt, 4, DB_SQLTYPE_INTEGER, static_cast<uint32_t>(m_endTime));
269 DBBind(hStmt, 5, DB_SQLTYPE_VARCHAR, (m_recall ? _T("1") : _T("0")), DB_BIND_STATIC);
270 DBBind(hStmt, 6, DB_SQLTYPE_VARCHAR, (m_onStartup ? _T("1") : _T("0")), DB_BIND_STATIC);
271 DBBind(hStmt, 7, DB_SQLTYPE_INTEGER, static_cast<uint32_t>(m_creationTime));
272 DBBind(hStmt, 8, DB_SQLTYPE_INTEGER, m_creatorId);
273 DBBind(hStmt, 9, DB_SQLTYPE_INTEGER, m_id);
274
275 DBExecute(hStmt);
276 DBFreeStatement(hStmt);
277 }
278
279 DBConnectionPoolReleaseConnection(hdb);
280 }
281
282 /**
283 * Serealize object to json
284 */
285 json_t *UserAgentNotificationItem::toJson() const
286 {
287 json_t *root = json_object();
288 json_object_set_new(root, "id", json_integer(m_id));
289 json_object_set_new(root, "message", json_string_t(m_message));
290 json_object_set_new(root, "objectList", m_objects.toJson());
291 json_object_set_new(root, "startTime", json_integer(m_startTime));
292 json_object_set_new(root, "endTime", json_integer(m_endTime));
293 json_object_set_new(root, "recalled", json_boolean(m_recall));
294 json_object_set_new(root, "creationTime", json_boolean(m_creationTime));
295 json_object_set_new(root, "createdBy", json_boolean(m_creatorId));
296 return root;
297 }