From e59722548702a2f6bbac3ae87cc3f4f0282d707d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 2 Jan 2025 19:21:09 +0000 Subject: [PATCH] fix: error toast message while configuring trigger while creating a monitor (#1178) * fix: error toast message while configuring trigger while creating a monitor Signed-off-by: vikhy-aws <191836418+vikhy-aws@users.noreply.github.com> * fix: gracefully handle exceptions related to config index not created Signed-off-by: vikhy-aws <191836418+vikhy-aws@users.noreply.github.com> * fix: gracefully handle exceptions related to config index not created Signed-off-by: vikhy-aws <191836418+vikhy-aws@users.noreply.github.com> * fix: fix unit test to conform to code changes Signed-off-by: vikhy-aws <191836418+vikhy-aws@users.noreply.github.com> --------- Signed-off-by: vikhy-aws <191836418+vikhy-aws@users.noreply.github.com> (cherry picked from commit ad86031f4800a8db1057bc4a3abdd27f52c03448) Signed-off-by: github-actions[bot] --- .../ConfigureActions/ConfigureActions.js | 5 +- server/services/DestinationsService.js | 21 +- server/services/DestinationsService.test.js | 188 ++++++++++++++++++ server/services/MonitorService.js | 55 +++-- 4 files changed, 245 insertions(+), 24 deletions(-) create mode 100644 server/services/DestinationsService.test.js diff --git a/public/pages/CreateTrigger/containers/ConfigureActions/ConfigureActions.js b/public/pages/CreateTrigger/containers/ConfigureActions/ConfigureActions.js index 1cf059a76..7c676ba28 100644 --- a/public/pages/CreateTrigger/containers/ConfigureActions/ConfigureActions.js +++ b/public/pages/CreateTrigger/containers/ConfigureActions/ConfigureActions.js @@ -182,8 +182,9 @@ class ConfigureActions extends React.Component { type: toChannelType(destination.type), description: '', })); - } else { - backendErrorNotification(notifications, 'load', 'destinations', response.err); + } else if (response.totalMonitors !== 0) { + // If the config index is not created, don't show the notification + backendErrorNotification(notifications, 'load', 'destinations', response.err); } let channels = await this.getChannels(); diff --git a/server/services/DestinationsService.js b/server/services/DestinationsService.js index fe549ca5d..412f3e2f3 100644 --- a/server/services/DestinationsService.js +++ b/server/services/DestinationsService.js @@ -175,17 +175,24 @@ export default class DestinationsService extends MDSEnabledClientService { }, }); } catch (err) { + // Indices will be created when the monitor is created. if (isIndexNotFoundError(err)) { return res.ok({ - body: { ok: false, resp: {} }, + body: { + ok: false, + totalMonitors: 0, + monitors: [], + message: "Config index will be created automatically when the monitor is created" + }, + }); + } else { + return res.ok({ + body: { + ok: false, + err: err.message, + }, }); } - return res.ok({ - body: { - ok: false, - err: err.message, - }, - }); } }; diff --git a/server/services/DestinationsService.test.js b/server/services/DestinationsService.test.js new file mode 100644 index 000000000..7b57e5307 --- /dev/null +++ b/server/services/DestinationsService.test.js @@ -0,0 +1,188 @@ +import DestinationsService from "./DestinationsService"; + +describe("Test DestinationsService -- getDestinations", () => { + let destinationsService; + let mockContext; + let mockReq; + let mockRes; + let mockClient; + + beforeEach(() => { + mockClient = jest.fn(); + + mockContext = {}; + + mockRes = { + ok: jest.fn().mockReturnValue({ body: {} }), + }; + + destinationsService = new DestinationsService(); + destinationsService.getClientBasedOnDataSource = jest.fn().mockReturnValue(mockClient); + + }); + + describe("Test getDestinations", () => { + + test("should successfully get destinations list -- name as sort string", async () => { + const mockReq = { + query: { + from: 0, + size: 20, + search: "", + sortDirection: "desc", + sortField: "name", + type: "ALL", + }, + }; + + const mockResponse = { + destinations: [{ + id: "1", + name: "Sample Destination", + schema_version: 1, + seq_no: 1, + primary_term: 1, + }], + totalDestinations: 1, + }; + mockClient.mockResolvedValueOnce(mockResponse); + + await destinationsService.getDestinations(mockContext, mockReq, mockRes); + + expect(mockClient).toHaveBeenCalledWith("alerting.searchDestinations", { + sortString: "destination.name.keyword", + sortOrder: "desc", + startIndex: 0, + size: 20, + searchString: "", + destinationType: "ALL", + }); + expect(mockRes.ok).toHaveBeenCalledWith({ + body: { + ok: true, + destinations: [{ + id: "1", + name: "Sample Destination", + schema_version: 1, + seq_no: 1, + primary_term: 1, + version: 1, + ifSeqNo: 1, + ifPrimaryTerm: 1, + }], + totalDestinations: 1, + }, + }); + }); + + test("should successfully get destinations list -- type as sort string", async () => { + const mockReq = { + query: { + from: 0, + size: 20, + search: "", + sortDirection: "desc", + sortField: "type", + type: "ALL", + }, + }; + + const mockResponse = { + destinations: [{ + id: "1", + name: "Sample Destination", + schema_version: 1, + seq_no: 1, + primary_term: 1, + }], + totalDestinations: 1, + }; + mockClient.mockResolvedValueOnce(mockResponse); + + await destinationsService.getDestinations(mockContext, mockReq, mockRes); + + expect(mockClient).toHaveBeenCalledWith("alerting.searchDestinations", { + sortString: "destination.type", + sortOrder: "desc", + startIndex: 0, + size: 20, + searchString: "", + destinationType: "ALL", + }); + expect(mockRes.ok).toHaveBeenCalledWith({ + body: { + ok: true, + destinations: [{ + id: "1", + name: "Sample Destination", + schema_version: 1, + seq_no: 1, + primary_term: 1, + version: 1, + ifSeqNo: 1, + ifPrimaryTerm: 1, + }], + totalDestinations: 1, + }, + }); + }); + + test("should handle index not found error", async () => { + const mockReq = { + query: { + from: 0, + size: 20, + search: "", + sortDirection: "desc", + sortField: "name", + type: "ALL", + }, + }; + const error = new Error(); + error.statusCode = 404; + error.body = { + error: { + reason: 'Configured indices are not found: [.opendistro-alerting-config]' + } + }; + mockClient.mockRejectedValueOnce(error); + + await destinationsService.getDestinations(mockContext, mockReq, mockRes); + + expect(mockRes.ok).toHaveBeenCalledWith({ + body: { + ok: false, + totalMonitors: 0, + monitors: [], + message: "Config index will be created automatically when the monitor is created" + }, + }); + }); + + test("should handle other errors", async () => { + const mockReq = { + query: { + from: 0, + size: 20, + search: "", + sortDirection: "desc", + sortField: "name", + type: "ALL", + }, + }; + + const error = new Error("Some error"); + mockClient.mockRejectedValueOnce(error); + + await destinationsService.getDestinations(mockContext, mockReq, mockRes); + + expect(mockRes.ok).toHaveBeenCalledWith({ + body: { + ok: false, + err: "Some error" + }, + }); + }); + + }); +}); diff --git a/server/services/MonitorService.js b/server/services/MonitorService.js index 592bf300a..097c3e4f5 100644 --- a/server/services/MonitorService.js +++ b/server/services/MonitorService.js @@ -481,18 +481,28 @@ export default class MonitorService extends MDSEnabledClientService { }, }); } catch (err) { - console.error('Alerting - MonitorService - getMonitors', err); if (isIndexNotFoundError(err)) { + // Config index is not created unitl a monitor is created. return res.ok({ - body: { ok: false, resp: { totalMonitors: 0, monitors: [] } }, + body: { + ok: false, + resp: { + totalMonitors: 0, + monitors: [], + message: "No monitors created" + } + }, + }); + } else { + // If the index is created, some error in retrieving the monitors. + console.error('Alerting - MonitorService - getMonitors', err); + return res.ok({ + body: { + ok: false, + resp: err.message, + }, }); } - return res.ok({ - body: { - ok: false, - resp: err.message, - }, - }); } }; @@ -594,13 +604,28 @@ export default class MonitorService extends MDSEnabledClientService { }, }); } catch (err) { - console.error('Alerting - MonitorService - searchMonitor:', err); - return res.ok({ - body: { - ok: false, - resp: err.message, - }, - }); + if (isIndexNotFoundError(err)) { + // Config index is not created unitl a monitor is created. + return res.ok({ + body: { + ok: false, + resp: { + totalMonitors: 0, + monitors: [], + message: "No monitors created" + } + }, + }); + } else { + // If the index is created, some error in retrieving the monitors. + console.error('Alerting - MonitorService - searchMonitor:', err); + return res.ok({ + body: { + ok: false, + resp: err.message, + }, + }); + } } }; }