From eb77bfdaf42bdf0e1efe59fafe1ddc65603d33e1 Mon Sep 17 00:00:00 2001 From: ashish-egov Date: Tue, 30 Jul 2024 10:14:39 +0530 Subject: [PATCH 1/8] Revert "Ashish egov patch 2 (#1178)" This reverts commit e86a4dcb10dda9210ce4be75977502af7df366f6. --- .../src/server/kafka/Producer.ts | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/utilities/project-factory/src/server/kafka/Producer.ts b/utilities/project-factory/src/server/kafka/Producer.ts index bba3e19ae8b..10938d880fd 100644 --- a/utilities/project-factory/src/server/kafka/Producer.ts +++ b/utilities/project-factory/src/server/kafka/Producer.ts @@ -12,39 +12,33 @@ const kafkaClient = new KafkaClient({ // Creating a new Kafka producer instance using the Kafka client const producer = new Producer(kafkaClient, { partitionerType: 2 }); // Using partitioner type 2 -// Function to check broker availability +// Function to send a test message to check broker availability const checkBrokerAvailability = () => { - kafkaClient.loadMetadataForTopics([], (err, data) => { + const payloads = [ + { + topic: config.kafka.KAFKA_TEST_TOPIC, + messages: JSON.stringify({ message: 'Test message to check broker availability' }), + }, + ]; + + producer.send(payloads, (err, data) => { if (err) { if (err.message && err.message.toLowerCase().includes('broker not available')) { logger.error('Broker not available. Shutting down the service.'); shutdownGracefully(); } else { - logger.error('Error checking broker availability:', err); + logger.error('Error sending test message:', err); } } else { - logger.info('Broker is available:', data); + logger.info('Test message sent successfully:', data); } }); }; -// Event listener for 'ready' event, indicating that the client is ready to check broker availability -kafkaClient.on('ready', () => { - logger.info('Kafka client is ready'); // Log message indicating client is ready - checkBrokerAvailability(); // Check broker availability -}); - // Event listener for 'ready' event, indicating that the producer is ready to send messages producer.on('ready', () => { logger.info('Producer is ready'); // Log message indicating producer is ready - checkBrokerAvailability(); -}); - -// Event listener for 'error' event, indicating that the client encountered an error -kafkaClient.on('error', (err) => { - logger.error('Kafka client is in error state'); // Log message indicating client is in error state - console.error(err.stack || err); // Log the error stack or message - shutdownGracefully(); + checkBrokerAvailability(); // Check broker availability by sending a test message }); // Event listener for 'error' event, indicating that the producer encountered an error @@ -54,4 +48,4 @@ producer.on('error', (err) => { shutdownGracefully(); }); -export { producer }; // Exporting the producer instance for external use \ No newline at end of file +export { producer }; // Exporting the producer instance for external use From 83ef33d405ea591e12e4217910c7fcc766789ead Mon Sep 17 00:00:00 2001 From: ashish-egov <137176738+ashish-egov@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:40:59 +0530 Subject: [PATCH 2/8] All changes (#1201) * Update Listener.ts * added new branch * Update Listener.ts * fixed mapping kafka error * mapping kafka fixed * fix kafka * fix kafka * Removing foreign key constraint * Producer update * Update Producer.ts * Update Producer.ts * Feat : updated producemodified message * Feat : removed waiting * adding constraint * Update V20240731162600__add_uniqiue_constraint_process_track.sql * Update constants.ts * Update publishProjectFactory.yml --- ...__add_uniqiue_constraint_process_track.sql | 10 +++++++ .../src/server/config/constants.ts | 1 - .../src/server/kafka/Producer.ts | 29 +++++++++++-------- .../src/server/utils/campaignUtils.ts | 2 -- 4 files changed, 27 insertions(+), 15 deletions(-) create mode 100644 utilities/project-factory/migration/main/V20240731162600__add_uniqiue_constraint_process_track.sql diff --git a/utilities/project-factory/migration/main/V20240731162600__add_uniqiue_constraint_process_track.sql b/utilities/project-factory/migration/main/V20240731162600__add_uniqiue_constraint_process_track.sql new file mode 100644 index 00000000000..d9bfbd0af53 --- /dev/null +++ b/utilities/project-factory/migration/main/V20240731162600__add_uniqiue_constraint_process_track.sql @@ -0,0 +1,10 @@ +-- Step 1: Remove duplicate rows +DELETE FROM eg_cm_campaign_process a +USING health.eg_cm_campaign_process b +WHERE a.id < b.id +AND a.campaignId = b.campaignId +AND a.type = b.type; + +-- Step 2: Add the unique constraint +ALTER TABLE eg_cm_campaign_process +ADD CONSTRAINT uq_campaignId_type UNIQUE (campaignId, type); diff --git a/utilities/project-factory/src/server/config/constants.ts b/utilities/project-factory/src/server/config/constants.ts index 5236b19af5e..5023c9de00b 100644 --- a/utilities/project-factory/src/server/config/constants.ts +++ b/utilities/project-factory/src/server/config/constants.ts @@ -130,7 +130,6 @@ export const processTrackForUi = [ processTrackTypes.facilityCreation, processTrackTypes.staffCreation, processTrackTypes.targetAndDeliveryRulesCreation, - processTrackTypes.confirmingResourceCreation, processTrackTypes.staffMapping, processTrackTypes.resourceMapping, processTrackTypes.facilityMapping, diff --git a/utilities/project-factory/src/server/kafka/Producer.ts b/utilities/project-factory/src/server/kafka/Producer.ts index bba3e19ae8b..541b4dd45c7 100644 --- a/utilities/project-factory/src/server/kafka/Producer.ts +++ b/utilities/project-factory/src/server/kafka/Producer.ts @@ -12,18 +12,23 @@ const kafkaClient = new KafkaClient({ // Creating a new Kafka producer instance using the Kafka client const producer = new Producer(kafkaClient, { partitionerType: 2 }); // Using partitioner type 2 -// Function to check broker availability +// Function to check broker availability by listing all brokers const checkBrokerAvailability = () => { - kafkaClient.loadMetadataForTopics([], (err, data) => { + kafkaClient.loadMetadataForTopics([], (err: any, data: any) => { if (err) { - if (err.message && err.message.toLowerCase().includes('broker not available')) { - logger.error('Broker not available. Shutting down the service.'); + logger.error('Error checking broker availability:', err); + shutdownGracefully(); + } else { + const brokers = data[1]?.metadata || {}; + const brokerCount = Object.keys(brokers).length; + logger.info('Broker count:' + String(brokerCount)); + + if (brokerCount <= 0) { + logger.error('No brokers found. Shutting down the service.'); shutdownGracefully(); } else { - logger.error('Error checking broker availability:', err); + logger.info('Brokers are available:', brokers); } - } else { - logger.info('Broker is available:', data); } }); }; @@ -37,21 +42,21 @@ kafkaClient.on('ready', () => { // Event listener for 'ready' event, indicating that the producer is ready to send messages producer.on('ready', () => { logger.info('Producer is ready'); // Log message indicating producer is ready - checkBrokerAvailability(); + checkBrokerAvailability(); // Check broker availability }); // Event listener for 'error' event, indicating that the client encountered an error -kafkaClient.on('error', (err) => { +kafkaClient.on('error', (err: any) => { logger.error('Kafka client is in error state'); // Log message indicating client is in error state console.error(err.stack || err); // Log the error stack or message shutdownGracefully(); }); // Event listener for 'error' event, indicating that the producer encountered an error -producer.on('error', (err) => { +producer.on('error', (err: any) => { logger.error('Producer is in error state'); // Log message indicating producer is in error state - console.error(err.stack || err); // Log the error stack or message + console.error(err); // Log the error stack or message shutdownGracefully(); }); -export { producer }; // Exporting the producer instance for external use \ No newline at end of file +export { producer }; // Exporting the producer instance for external use diff --git a/utilities/project-factory/src/server/utils/campaignUtils.ts b/utilities/project-factory/src/server/utils/campaignUtils.ts index fbf3d20d9e5..7c81f7fc501 100644 --- a/utilities/project-factory/src/server/utils/campaignUtils.ts +++ b/utilities/project-factory/src/server/utils/campaignUtils.ts @@ -1349,8 +1349,6 @@ async function createProject(request: any, actionUrl: any, localizationMap?: any async function processAfterPersist(request: any, actionInUrl: any) { try { - logger.info("Waiting for 2 second to persist process tracks...") - await new Promise((resolve) => setTimeout(resolve, 2000)); const localizationMap = await getLocalizedMessagesHandler(request, request?.body?.CampaignDetails?.tenantId); if (request?.body?.CampaignDetails?.action == "create") { await persistTrack(request.body.CampaignDetails.id, processTrackTypes.validation, processTrackStatuses.completed); From 1235fa6abb9921d1f54dd79c4e5648000203b140 Mon Sep 17 00:00:00 2001 From: nabeelmd-eGov <94039229+nabeelmd-eGov@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:58:41 +0530 Subject: [PATCH 3/8] HCMPRE 154 (#1202) * date validation fix * Update date logic * FIX * css add * non editable fix * date start from tomorrow * css fix for language screen * disable today date * date and cycle fix --------- Co-authored-by: nabeelmd-eGov --- .../src/pages/employee/DateAndCycleUpdate.js | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/DateAndCycleUpdate.js b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/DateAndCycleUpdate.js index 093e201d774..02d53ba56a2 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/DateAndCycleUpdate.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/DateAndCycleUpdate.js @@ -77,6 +77,7 @@ const DateAndCycleUpdate = ({ onSelect, formData, ...props }) => { const { t } = useTranslation(); const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000; const today = Digit.Utils.date.getDate(Date.now()); + const tomorrow = Digit.Utils.date.getDate(new Date(today).getTime() + ONE_DAY_IN_MS); const tenantId = Digit.ULBService.getCurrentTenantId(); const { state } = useLocation(); const historyState = window.history.state; @@ -260,7 +261,7 @@ const DateAndCycleUpdate = ({ onSelect, formData, ...props }) => { ?.toISOString() ?.split("T")?.[0] : today >= startDate - ? today + ? tomorrow : startDate, max: endDate, }, @@ -278,17 +279,27 @@ const DateAndCycleUpdate = ({ onSelect, formData, ...props }) => { withoutLabel={true} type="date" value={item?.endDate} - nonEditable={item?.endDate && item?.endDate?.length > 0 && today >= item?.endDate ? true : false} + nonEditable={ + item?.endDate && + item?.endDate?.length > 0 && + today >= item?.endDate && + (cycleDates?.[index + 1] ? today >= cycleDates?.[index + 1]?.startDate : true) + ? true + : false + } placeholder={t("HCM_END_DATE")} populators={{ validation: { - min: !isNaN(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime()) - ? new Date(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime() + ONE_DAY_IN_MS) - ?.toISOString() - ?.split("T")?.[0] - : today >= startDate - ? today - : startDate, + min: + !isNaN(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime()) && + Digit.Utils.date.getDate(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime() + ONE_DAY_IN_MS) > + today + ? new Date(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime() + ONE_DAY_IN_MS) + ?.toISOString() + ?.split("T")?.[0] + : today >= startDate + ? tomorrow + : startDate, max: endDate, }, }} From dd16bcb2da24e21ff2615e4b7ff352d1080318a8 Mon Sep 17 00:00:00 2001 From: nabeelmd-eGov <94039229+nabeelmd-eGov@users.noreply.github.com> Date: Wed, 31 Jul 2024 18:40:46 +0530 Subject: [PATCH 4/8] Revert "HCMPRE 154 (#1191)" (#1203) This reverts commit 59ec9531ebfc7535bacf324723edae975166867c. Co-authored-by: nabeelmd-eGov --- .../src/components/BoundaryWithDate.js | 28 ++++++------------ .../src/pages/employee/DateAndCycleUpdate.js | 29 ++++++------------- 2 files changed, 18 insertions(+), 39 deletions(-) diff --git a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/BoundaryWithDate.js b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/BoundaryWithDate.js index 2df60822efa..83a84c4a3ef 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/BoundaryWithDate.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/BoundaryWithDate.js @@ -10,7 +10,6 @@ const BoundaryWithDate = ({ project, props, onSelect, dateReducerDispatch, canDe // const { t } = useTranslation(); const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000; const today = Digit.Utils.date.getDate(Date.now()); - const tomorrow = Digit.Utils.date.getDate(new Date(today).getTime() + ONE_DAY_IN_MS); const [startDate, setStartDate] = useState(project?.startDate ? Digit.Utils.date.getDate(project?.startDate) : ""); // Set default start date to today const [endDate, setEndDate] = useState(project?.endDate ? Digit.Utils.date.getDate(project?.endDate) : ""); // Default end date const [cycleDates, setCycleDates] = useState(null); @@ -153,7 +152,7 @@ const BoundaryWithDate = ({ project, props, onSelect, dateReducerDispatch, canDe ?.toISOString() ?.split("T")?.[0] : today >= startDate - ? tomorrow + ? today : startDate, max: endDate, }, @@ -170,26 +169,17 @@ const BoundaryWithDate = ({ project, props, onSelect, dateReducerDispatch, canDe withoutLabel={true} type="date" value={item?.endDate} - nonEditable={ - item?.endDate?.length > 0 && - today >= item?.endDate && - (cycleDates?.[index + 1] ? today >= cycleDates?.[index + 1]?.startDate : true) - ? true - : false - } + nonEditable={item?.endDate?.length > 0 && today >= item?.endDate && today >= cycleDates?.[index + 1]?.startDate ? true : false} placeholder={t("HCM_END_DATE")} populators={{ validation: { - min: - !isNaN(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime()) && - Digit.Utils.date.getDate(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime() + ONE_DAY_IN_MS) > - today - ? new Date(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime() + ONE_DAY_IN_MS) - ?.toISOString() - ?.split("T")?.[0] - : today >= startDate - ? tomorrow - : startDate, + min: !isNaN(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime()) + ? new Date(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime() + ONE_DAY_IN_MS) + ?.toISOString() + ?.split("T")?.[0] + : today >= startDate + ? today + : startDate, max: endDate, }, }} diff --git a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/DateAndCycleUpdate.js b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/DateAndCycleUpdate.js index 02d53ba56a2..093e201d774 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/DateAndCycleUpdate.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/DateAndCycleUpdate.js @@ -77,7 +77,6 @@ const DateAndCycleUpdate = ({ onSelect, formData, ...props }) => { const { t } = useTranslation(); const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000; const today = Digit.Utils.date.getDate(Date.now()); - const tomorrow = Digit.Utils.date.getDate(new Date(today).getTime() + ONE_DAY_IN_MS); const tenantId = Digit.ULBService.getCurrentTenantId(); const { state } = useLocation(); const historyState = window.history.state; @@ -261,7 +260,7 @@ const DateAndCycleUpdate = ({ onSelect, formData, ...props }) => { ?.toISOString() ?.split("T")?.[0] : today >= startDate - ? tomorrow + ? today : startDate, max: endDate, }, @@ -279,27 +278,17 @@ const DateAndCycleUpdate = ({ onSelect, formData, ...props }) => { withoutLabel={true} type="date" value={item?.endDate} - nonEditable={ - item?.endDate && - item?.endDate?.length > 0 && - today >= item?.endDate && - (cycleDates?.[index + 1] ? today >= cycleDates?.[index + 1]?.startDate : true) - ? true - : false - } + nonEditable={item?.endDate && item?.endDate?.length > 0 && today >= item?.endDate ? true : false} placeholder={t("HCM_END_DATE")} populators={{ validation: { - min: - !isNaN(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime()) && - Digit.Utils.date.getDate(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime() + ONE_DAY_IN_MS) > - today - ? new Date(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime() + ONE_DAY_IN_MS) - ?.toISOString() - ?.split("T")?.[0] - : today >= startDate - ? tomorrow - : startDate, + min: !isNaN(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime()) + ? new Date(new Date(cycleDates?.find((j) => j.cycleIndex == index + 1)?.startDate)?.getTime() + ONE_DAY_IN_MS) + ?.toISOString() + ?.split("T")?.[0] + : today >= startDate + ? today + : startDate, max: endDate, }, }} From 821232c21b4f3242ba59ece45f2f6058a3d205a5 Mon Sep 17 00:00:00 2001 From: Bhavya-egov <137176879+Bhavya-egov@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:18:37 +0530 Subject: [PATCH 5/8] updated versions (#1205) --- micro-ui/web/micro-ui-internals/example/package.json | 4 ++-- micro-ui/web/micro-ui-internals/example/public/index.html | 2 +- micro-ui/web/package.json | 4 ++-- micro-ui/web/public/index.html | 2 +- micro-ui/web/workbench/package.json | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/micro-ui/web/micro-ui-internals/example/package.json b/micro-ui/web/micro-ui-internals/example/package.json index e706f047a47..9054c035595 100644 --- a/micro-ui/web/micro-ui-internals/example/package.json +++ b/micro-ui/web/micro-ui-internals/example/package.json @@ -9,10 +9,10 @@ "start": "react-scripts start" }, "devDependencies": { - "@egovernments/digit-ui-libraries": "1.8.2-beta.5", + "@egovernments/digit-ui-libraries": "1.8.2-beta.6", "@egovernments/digit-ui-module-workbench": "1.0.2-beta.3", "@egovernments/digit-ui-components": "0.0.2-beta.19", - "@egovernments/digit-ui-module-core": "1.8.2-beta.9", + "@egovernments/digit-ui-module-core": "1.8.2-beta.10", "@egovernments/digit-ui-module-utilities": "1.0.1-beta.30", "@egovernments/digit-ui-react-components": "1.8.2-beta.11", "@egovernments/digit-ui-module-hcmworkbench":"0.0.38", diff --git a/micro-ui/web/micro-ui-internals/example/public/index.html b/micro-ui/web/micro-ui-internals/example/public/index.html index 684f5350549..bb26448b487 100644 --- a/micro-ui/web/micro-ui-internals/example/public/index.html +++ b/micro-ui/web/micro-ui-internals/example/public/index.html @@ -14,7 +14,7 @@ rel="stylesheet" href="https://unpkg.com/@egovernments/digit-ui-css@1.8.0-alpha.6/dist/index.css" /> --> - + diff --git a/micro-ui/web/package.json b/micro-ui/web/package.json index 8e13578379b..35c1a3faa09 100644 --- a/micro-ui/web/package.json +++ b/micro-ui/web/package.json @@ -14,9 +14,9 @@ ], "homepage": "/digit-ui", "dependencies": { - "@egovernments/digit-ui-libraries": "1.8.2-beta.5", + "@egovernments/digit-ui-libraries": "1.8.2-beta.6", "@egovernments/digit-ui-module-workbench": "1.0.1-beta.16", - "@egovernments/digit-ui-module-core": "1.8.2-beta.9", + "@egovernments/digit-ui-module-core": "1.8.2-beta.10", "@egovernments/digit-ui-module-hrms": "1.8.0-beta.2", "@egovernments/digit-ui-react-components": "1.8.2-beta.11", "@egovernments/digit-ui-components": "0.0.2-beta.19", diff --git a/micro-ui/web/public/index.html b/micro-ui/web/public/index.html index a99ea661706..9a2442d74d1 100644 --- a/micro-ui/web/public/index.html +++ b/micro-ui/web/public/index.html @@ -8,7 +8,7 @@ href="https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@400;500;700&family=Roboto:wght@400;500;700&display=swap" rel="stylesheet" type="text/css" /> - + diff --git a/micro-ui/web/workbench/package.json b/micro-ui/web/workbench/package.json index dde9d61650c..2c664164a74 100644 --- a/micro-ui/web/workbench/package.json +++ b/micro-ui/web/workbench/package.json @@ -12,10 +12,10 @@ ], "homepage": "/workbench-ui", "dependencies": { - "@egovernments/digit-ui-libraries": "1.8.2-beta.5", + "@egovernments/digit-ui-libraries": "1.8.2-beta.6", "@egovernments/digit-ui-module-workbench": "1.0.2-beta.3", "@egovernments/digit-ui-components": "0.0.2-beta.19", - "@egovernments/digit-ui-module-core": "1.8.2-beta.9", + "@egovernments/digit-ui-module-core": "1.8.2-beta.10", "@egovernments/digit-ui-module-utilities": "1.0.1-beta.30", "@egovernments/digit-ui-react-components": "1.8.2-beta.11", "@egovernments/digit-ui-module-hcmworkbench":"0.0.38", From 39b03e6ede76dc56df709033060c73471fbbba0f Mon Sep 17 00:00:00 2001 From: nabeelmd-eGov <94039229+nabeelmd-eGov@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:36:56 +0530 Subject: [PATCH 6/8] Update date change screen date logic fix, info added, hard reload issue fix (#1206) Co-authored-by: nabeelmd-eGov --- .../src/components/BoundaryWithDate.js | 12 +++++++++--- .../src/configs/UICustomizations.js | 10 +++++----- .../src/pages/employee/DateAndCycleUpdate.js | 11 +++++++++-- .../src/pages/employee/UpdateDatesWithBoundaries.js | 13 ++++++++++++- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/BoundaryWithDate.js b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/BoundaryWithDate.js index 83a84c4a3ef..8e26b99452d 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/BoundaryWithDate.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/components/BoundaryWithDate.js @@ -28,7 +28,7 @@ const BoundaryWithDate = ({ project, props, onSelect, dateReducerDispatch, canDe }, [project]); const handleDateChange = ({ date, endDate = false, cycleDate = false, cycleIndex }) => { - if (typeof date === "undefined") { + if (typeof date === "undefined" || date <= today) { return null; } if (!endDate) { @@ -47,7 +47,7 @@ const BoundaryWithDate = ({ project, props, onSelect, dateReducerDispatch, canDe }; const handleCycleDateChange = ({ date, endDate = false, cycleIndex }) => { - if (typeof date === "undefined") { + if (typeof date === "undefined" || date <= today) { return null; } if (!endDate) { @@ -169,7 +169,13 @@ const BoundaryWithDate = ({ project, props, onSelect, dateReducerDispatch, canDe withoutLabel={true} type="date" value={item?.endDate} - nonEditable={item?.endDate?.length > 0 && today >= item?.endDate && today >= cycleDates?.[index + 1]?.startDate ? true : false} + nonEditable={ + item?.endDate?.length > 0 && + today >= item?.endDate && + (cycleDates?.[index + 1] ? today >= cycleDates?.[index + 1]?.startDate : true) + ? true + : false + } placeholder={t("HCM_END_DATE")} populators={{ validation: { diff --git a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/configs/UICustomizations.js b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/configs/UICustomizations.js index 881d767a315..3cbc7824f75 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/configs/UICustomizations.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/configs/UICustomizations.js @@ -1,4 +1,4 @@ -import { Link, useHistory } from "react-router-dom"; +import { Link } from "react-router-dom"; import _ from "lodash"; import React from "react"; import { Fragment } from "react"; @@ -118,8 +118,8 @@ export const UICustomizations = { "", `/${window.contextPath}/employee/campaign/update-dates-boundary?id=${row?.id}` ); - window.location.href = `/${window.contextPath}/employee/campaign/update-dates-boundary?id=${row?.id}`; - + const navEvent = new PopStateEvent("popstate"); + window.dispatchEvent(navEvent); break; case "ACTION_LABEL_VIEW_TIMELINE": setTimeline(true); @@ -393,8 +393,8 @@ export const UICustomizations = { "", `/${window.contextPath}/employee/campaign/update-dates-boundary?id=${row?.id}` ); - window.location.href = `/${window.contextPath}/employee/campaign/update-dates-boundary?id=${row?.id}`; - + const navEvent = new PopStateEvent("popstate"); + window.dispatchEvent(navEvent); break; case "ACTION_LABEL_VIEW_TIMELINE": setTimeline(true); diff --git a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/DateAndCycleUpdate.js b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/DateAndCycleUpdate.js index 093e201d774..cdca043f048 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/DateAndCycleUpdate.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/DateAndCycleUpdate.js @@ -160,7 +160,7 @@ const DateAndCycleUpdate = ({ onSelect, formData, ...props }) => { }; const handleCycleDateChange = ({ date, endDate = false, cycleIndex }) => { - if (typeof date === "undefined") { + if (typeof date === "undefined" || date <= today) { return null; } if (!endDate) { @@ -278,7 +278,14 @@ const DateAndCycleUpdate = ({ onSelect, formData, ...props }) => { withoutLabel={true} type="date" value={item?.endDate} - nonEditable={item?.endDate && item?.endDate?.length > 0 && today >= item?.endDate ? true : false} + nonEditable={ + item?.endDate && + item?.endDate?.length > 0 && + today >= item?.endDate && + (cycleDates?.[index + 1] ? today >= cycleDates?.[index + 1]?.startDate : true) + ? true + : false + } placeholder={t("HCM_END_DATE")} populators={{ validation: { diff --git a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/UpdateDatesWithBoundaries.js b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/UpdateDatesWithBoundaries.js index 07a67e84f4d..11a685e698c 100644 --- a/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/UpdateDatesWithBoundaries.js +++ b/micro-ui/web/micro-ui-internals/packages/modules/campaign-manager/src/pages/employee/UpdateDatesWithBoundaries.js @@ -3,7 +3,7 @@ import React, { useState, useEffect } from "react"; import { useTranslation } from "react-i18next"; import { useHistory, useLocation } from "react-router-dom"; import { dateChangeBoundaryConfig, dateChangeConfig } from "../../configs/dateChangeBoundaryConfig"; -import { Button, PopUp, Toast } from "@egovernments/digit-ui-components"; +import { Button, InfoCard, PopUp, Toast } from "@egovernments/digit-ui-components"; function UpdateDatesWithBoundaries() { const { t } = useTranslation(); @@ -152,6 +152,17 @@ function UpdateDatesWithBoundaries() { actionClassName={"dateUpdateAction"} noCardStyle={true} /> + {t(`UPDATE_DATE_CHANGE_INFO_TEXT`)}]} + label={"Info"} + headerClassName={"headerClassName"} + /> {showPopUp && ( Date: Thu, 1 Aug 2024 16:01:06 +0530 Subject: [PATCH 7/8] Config update for project-factory (#1207) * updated readmeconfig for sheet * added cache for generating target template when only delivery conditions change * added logic for having only 18 target columns if exceed i will create one column with header OTHER_TARGETS * updated config to fetch from devops accordingly * updated config for project -factory --- utilities/project-factory/src/server/config/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utilities/project-factory/src/server/config/index.ts b/utilities/project-factory/src/server/config/index.ts index 598ea165e4b..87cf8d4c4fd 100644 --- a/utilities/project-factory/src/server/config/index.ts +++ b/utilities/project-factory/src/server/config/index.ts @@ -18,10 +18,10 @@ const getDBSchemaName = (dbSchema = "") => { const config = { cacheTime : 300, enableDynamicTemplateFor: process.env.ENABLE_DYNAMIC_TEMPLATE_FOR || "MR-DN", - isCallGenerateWhenDeliveryConditionsDiffer: process.env.IS_CALL_GENERATE_WHEN_DELIVERY_CONDITIONS_DIFFER || false, + isCallGenerateWhenDeliveryConditionsDiffer: (process.env.IS_CALL_GENERATE_WHEN_DELIVERY_CONDITIONS_DIFFER === "true") || false, prefixForMicroplanCampaigns: "MP", - excludeHierarchyTypeFromBoundaryCodes: process.env.EXCLUDE_HIERARCHY_TYPE_FROM_BOUNDARY_CODES || false, - excludeBoundaryNameAtLastFromBoundaryCodes: process.env.EXCLUDE_BOUNDARY_NAME_AT_LAST_FROM_BOUNDARY_CODES || false, + excludeHierarchyTypeFromBoundaryCodes: (process.env.EXCLUDE_HIERARCHY_TYPE_FROM_BOUNDARY_CODES === "true") || false, + excludeBoundaryNameAtLastFromBoundaryCodes: (process.env.EXCLUDE_BOUNDARY_NAME_AT_LAST_FROM_BOUNDARY_CODES === "true") || false, masterNameForSchemaOfColumnHeaders: "adminSchema", masterNameForSplitBoundariesOn: "hierarchyConfig", boundary: { From 45884805123cb4534fe6a26bcb3113678ad402cb Mon Sep 17 00:00:00 2001 From: ashish-egov Date: Thu, 1 Aug 2024 16:19:31 +0530 Subject: [PATCH 8/8] Feat : improved kafka --- .../src/server/api/campaignApis.ts | 6 +- .../src/server/kafka/Listener.ts | 41 +----- .../src/server/kafka/Producer.ts | 120 +++++++++++++----- .../src/server/utils/campaignMappingUtils.ts | 2 +- .../src/server/utils/campaignUtils.ts | 2 +- .../src/server/utils/genericUtils.ts | 4 +- .../src/server/utils/processTrackUtils.ts | 2 +- 7 files changed, 95 insertions(+), 82 deletions(-) diff --git a/utilities/project-factory/src/server/api/campaignApis.ts b/utilities/project-factory/src/server/api/campaignApis.ts index 0edd9b151ce..b817575319d 100644 --- a/utilities/project-factory/src/server/api/campaignApis.ts +++ b/utilities/project-factory/src/server/api/campaignApis.ts @@ -8,7 +8,7 @@ import { immediateValidationForTargetSheet, validateSheetData, validateTargetShe import { callMdmsTypeSchema, getCampaignNumber } from "./genericApis"; import { boundaryBulkUpload, convertToTypeData, generateHierarchy, generateProcessedFileAndPersist, getBoundaryOnWhichWeSplit, getLocalizedName, reorderBoundariesOfDataAndValidate, checkIfSourceIsMicroplan } from "../utils/campaignUtils"; const _ = require('lodash'); -import { produceModifiedMessages } from "../kafka/Listener"; +import { produceModifiedMessages } from "../kafka/Producer"; import { createDataService } from "../service/dataManageService"; import { searchProjectTypeCampaignService } from "../service/campaignManageService"; import { getExcelWorkbookFromFileURL } from "../utils/excelUtils"; @@ -535,7 +535,7 @@ async function processValidate(request: any, localizationMap?: { [key: string]: logger.info("target sheet format validation started"); await immediateValidationForTargetSheet(request, dataFromSheet, differentTabsBasedOnLevel, localizationMap); logger.info("target sheet format validation completed and starts with data validation"); - validateTargetSheetData(dataFromSheet, request, createAndSearchConfig?.boundaryValidation, differentTabsBasedOnLevel,localizationMap); + validateTargetSheetData(dataFromSheet, request, createAndSearchConfig?.boundaryValidation, differentTabsBasedOnLevel, localizationMap); } else { @@ -870,7 +870,7 @@ async function processCreate(request: any, localizationMap?: any) { const mdmsResponse = await callMdmsTypeSchema(request, tenantId, type); schema = mdmsResponse } - else if(type == "facilityMicroplan") { + else if (type == "facilityMicroplan") { const mdmsResponse = await callMdmsTypeSchema(request, tenantId, "facility", "microplan"); schema = mdmsResponse logger.info("Appending project type to capacity for microplan " + campaignType); diff --git a/utilities/project-factory/src/server/kafka/Listener.ts b/utilities/project-factory/src/server/kafka/Listener.ts index 12a16269288..128f99c08cb 100644 --- a/utilities/project-factory/src/server/kafka/Listener.ts +++ b/utilities/project-factory/src/server/kafka/Listener.ts @@ -1,9 +1,8 @@ import { ConsumerGroup, ConsumerGroupOptions, Message } from 'kafka-node'; import config from '../config'; import { getFormattedStringForDebug, logger } from '../utils/logger'; -import { shutdownGracefully, throwError } from '../utils/genericUtils'; +import { shutdownGracefully } from '../utils/genericUtils'; import { handleCampaignMapping } from '../utils/campaignMappingUtils'; -import { producer } from './Producer'; // Kafka Configuration const kafkaConfig: ConsumerGroupOptions = { @@ -54,41 +53,3 @@ export function listener() { logger.error(`Offset out of range error: ${err}`); }); } - - -/** - * Produces modified messages to a specified Kafka topic. - * @param modifiedMessages An array of modified messages to be produced. - * @param topic The Kafka topic to which the messages will be produced. - * @returns A promise that resolves when the messages are successfully produced. - */ -async function produceModifiedMessages(modifiedMessages: any[], topic: any) { - try { - logger.info(`KAFKA :: PRODUCER :: a message sent to topic ${topic}`); - logger.debug(`KAFKA :: PRODUCER :: message ${getFormattedStringForDebug(modifiedMessages)}`); - const payloads = [ - { - topic: topic, - messages: JSON.stringify(modifiedMessages), // Convert modified messages to JSON string - }, - ]; - - // Send payloads to the Kafka producer - producer.send(payloads, (err: any) => { - if (err) { - console.error(err); - console.log('Error coming for message : ', modifiedMessages); - logger.info('KAFKA :: PRODUCER :: Some Error Occurred '); - logger.error(`KAFKA :: PRODUCER :: Error : ${JSON.stringify(err)}`); - } else { - logger.info('KAFKA :: PRODUCER :: message sent successfully '); - } - }); - } catch (error) { - console.error(error); - logger.error(`KAFKA :: PRODUCER :: Exception caught: ${JSON.stringify(error)}`); - throwError("COMMON", 400, "KAKFA_ERROR", "Some error occured in kafka"); // Re-throw the error after logging it - } -} - -export { produceModifiedMessages } // Export the produceModifiedMessages function for external use diff --git a/utilities/project-factory/src/server/kafka/Producer.ts b/utilities/project-factory/src/server/kafka/Producer.ts index 10938d880fd..01faf56c3ff 100644 --- a/utilities/project-factory/src/server/kafka/Producer.ts +++ b/utilities/project-factory/src/server/kafka/Producer.ts @@ -1,51 +1,103 @@ -import config from '../config'; // Importing configuration settings -import { Producer, KafkaClient } from 'kafka-node'; // Importing Producer and KafkaClient from 'kafka-node' library +import { Producer, KafkaClient } from 'kafka-node'; import { logger } from "../utils/logger"; -import { shutdownGracefully } from '../utils/genericUtils'; +import { shutdownGracefully, throwError } from '../utils/genericUtils'; +import config from '../config'; + +// Global producer instance +let producer: Producer; -// Creating a new Kafka client instance using the configured Kafka broker host const kafkaClient = new KafkaClient({ - kafkaHost: config?.host?.KAFKA_BROKER_HOST, // Configuring Kafka broker host - connectRetryOptions: { retries: 1 }, // Configuring connection retry options + kafkaHost: config?.host?.KAFKA_BROKER_HOST, + connectRetryOptions: { retries: 1 }, }); -// Creating a new Kafka producer instance using the Kafka client -const producer = new Producer(kafkaClient, { partitionerType: 2 }); // Using partitioner type 2 +const createProducer = () => { + producer = new Producer(kafkaClient, { partitionerType: 2 }); + + producer.on('ready', () => { + logger.info('Producer is ready'); + checkBrokerAvailability(); + }); -// Function to send a test message to check broker availability + producer.on('error', (err: any) => { + logger.error('Producer is in error state'); + console.error(err); + shutdownGracefully(); + }); +}; + +// Function to check broker availability by listing all brokers const checkBrokerAvailability = () => { - const payloads = [ - { - topic: config.kafka.KAFKA_TEST_TOPIC, - messages: JSON.stringify({ message: 'Test message to check broker availability' }), - }, - ]; - - producer.send(payloads, (err, data) => { + kafkaClient.loadMetadataForTopics([], (err: any, data: any) => { if (err) { - if (err.message && err.message.toLowerCase().includes('broker not available')) { - logger.error('Broker not available. Shutting down the service.'); + logger.error('Error checking broker availability:', err); + shutdownGracefully(); + } else { + const brokers = data[1]?.metadata || {}; + const brokerCount = Object.keys(brokers).length; + logger.info('Broker count:' + String(brokerCount)); + + if (brokerCount <= 0) { + logger.error('No brokers found. Shutting down the service.'); shutdownGracefully(); } else { - logger.error('Error sending test message:', err); + logger.info('Brokers are available:', brokers); } - } else { - logger.info('Test message sent successfully:', data); } }); }; -// Event listener for 'ready' event, indicating that the producer is ready to send messages -producer.on('ready', () => { - logger.info('Producer is ready'); // Log message indicating producer is ready - checkBrokerAvailability(); // Check broker availability by sending a test message -}); -// Event listener for 'error' event, indicating that the producer encountered an error -producer.on('error', (err) => { - logger.error('Producer is in error state'); // Log message indicating producer is in error state - console.error(err.stack || err); // Log the error stack or message - shutdownGracefully(); -}); +createProducer(); + +const sendWithRetries = (payloads: any[], retries = 3, shutdown: boolean = false): Promise => { + return new Promise((resolve, reject) => { + producer.send(payloads, async (err: any) => { + if (err) { + logger.error('Error sending message:', err); + if (retries > 0) { + logger.info(`Retrying to send message. Retries left: ${retries}`); + await new Promise(resolve => setTimeout(resolve, 2000)); // wait before retrying + resolve(sendWithRetries(payloads, retries - 1)); + } else { + // Attempt to reconnect and retry + logger.error('Failed to send message after retries. Reconnecting producer...'); + if (shutdown) { + shutdownGracefully(); + } + else { + producer.close(() => { + createProducer(); // Recreate the producer + setTimeout(() => { + sendWithRetries(payloads, 1, true).catch(reject); + }, 2000); // wait before retrying after reconnect + }); + } + } + } else { + logger.info('Message sent successfully'); + resolve(); + } + }); + }); +}; + +async function produceModifiedMessages(modifiedMessages: any[], topic: any) { + try { + logger.info(`KAFKA :: PRODUCER :: A message sent to topic ${topic}`); + logger.debug(`KAFKA :: PRODUCER :: Message ${JSON.stringify(modifiedMessages)}`); + const payloads = [ + { + topic: topic, + messages: JSON.stringify(modifiedMessages), + }, + ]; + + await sendWithRetries(payloads, 3); + } catch (error) { + logger.error(`KAFKA :: PRODUCER :: Exception caught: ${JSON.stringify(error)}`); + throwError("COMMON", 400, "KAFKA_ERROR", "Some error occurred in Kafka"); // Re-throw the error after logging it + } +} -export { producer }; // Exporting the producer instance for external use +export { produceModifiedMessages }; diff --git a/utilities/project-factory/src/server/utils/campaignMappingUtils.ts b/utilities/project-factory/src/server/utils/campaignMappingUtils.ts index 5219ad4fcb2..b394af10ed2 100644 --- a/utilities/project-factory/src/server/utils/campaignMappingUtils.ts +++ b/utilities/project-factory/src/server/utils/campaignMappingUtils.ts @@ -3,7 +3,7 @@ import config from "../config"; import { getDataFromSheet, throwError } from "./genericUtils"; import { getFormattedStringForDebug, logger } from "./logger"; import { defaultheader, httpRequest } from "./request"; -import { produceModifiedMessages } from "../kafka/Listener"; +import { produceModifiedMessages } from "../kafka/Producer"; import { enrichAndPersistCampaignWithError, getLocalizedName } from "./campaignUtils"; import { campaignStatuses, resourceDataStatuses } from "../config/constants"; import { createCampaignService } from "../service/campaignManageService"; diff --git a/utilities/project-factory/src/server/utils/campaignUtils.ts b/utilities/project-factory/src/server/utils/campaignUtils.ts index 2a329538a0e..f0bc96b29dd 100644 --- a/utilities/project-factory/src/server/utils/campaignUtils.ts +++ b/utilities/project-factory/src/server/utils/campaignUtils.ts @@ -2,7 +2,7 @@ import { defaultheader, httpRequest } from "./request"; import config from "../config/index"; import { v4 as uuidv4 } from 'uuid'; -import { produceModifiedMessages } from '../kafka/Listener' +import { produceModifiedMessages } from "../kafka/Producer"; import { confirmProjectParentCreation, createProjectCampaignResourcData, getCampaignSearchResponse, getHierarchy, handleResouceDetailsError, projectCreate } from "../api/campaignApis"; import { getCampaignNumber, createAndUploadFile, getSheetData, createExcelSheet, getAutoGeneratedBoundaryCodesHandler, createBoundaryEntities, createBoundaryRelationship, getMDMSV1Data, getTargetSheetDataAfterCode, callMdmsTypeSchema, getSheetDataFromWorksheet } from "../api/genericApis"; import { getFormattedStringForDebug, logger } from "./logger"; diff --git a/utilities/project-factory/src/server/utils/genericUtils.ts b/utilities/project-factory/src/server/utils/genericUtils.ts index ce3709a0774..5d90690bbef 100644 --- a/utilities/project-factory/src/server/utils/genericUtils.ts +++ b/utilities/project-factory/src/server/utils/genericUtils.ts @@ -2,7 +2,7 @@ import { NextFunction, Request, Response } from "express"; import { httpRequest, defaultheader } from "./request"; import config, { getErrorCodes } from "../config/index"; import { v4 as uuidv4 } from 'uuid'; -import { produceModifiedMessages } from "../kafka/Listener"; +import { produceModifiedMessages } from "../kafka/Producer"; import { generateHierarchyList, getAllFacilities, getCampaignSearchResponse, getHierarchy } from "../api/campaignApis"; import { getBoundarySheetData, getSheetData, createAndUploadFile, createExcelSheet, getTargetSheetData, callMdmsData, callMdmsTypeSchema } from "../api/genericApis"; import { logger } from "./logger"; @@ -374,7 +374,7 @@ async function fullProcessFlowForNewEntry(newEntryResponse: any, generatedResour if (type === 'boundary') { // get boundary data from boundary relationship search api logger.info("Generating Boundary Data") - const boundaryDataSheetGeneratedBeforeDifferentTabSeparation = await getBoundaryDataService(request,enableCaching); + const boundaryDataSheetGeneratedBeforeDifferentTabSeparation = await getBoundaryDataService(request, enableCaching); logger.info(`Boundary data generated successfully: ${JSON.stringify(boundaryDataSheetGeneratedBeforeDifferentTabSeparation)}`); // get boundary sheet data after being generated logger.info("generating different tabs logic ") diff --git a/utilities/project-factory/src/server/utils/processTrackUtils.ts b/utilities/project-factory/src/server/utils/processTrackUtils.ts index 3451e632fb9..aadd67d8a0f 100644 --- a/utilities/project-factory/src/server/utils/processTrackUtils.ts +++ b/utilities/project-factory/src/server/utils/processTrackUtils.ts @@ -1,5 +1,5 @@ import config from './../config'; -import { produceModifiedMessages } from '../kafka/Listener'; +import { produceModifiedMessages } from "../kafka/Producer";; import { v4 as uuidv4 } from 'uuid'; import { executeQuery } from './db'; import { processTrackForUi, processTrackStatuses, processTrackTypes } from '../config/constants';