Skip to content

Commit

Permalink
Schema validation2 (#721)
Browse files Browse the repository at this point in the history
* Feat : removed campaignId validation for boundary upload

* Feat : added schema validation

* Fixed mdms host

* Feat : added boundary validation

* Feat : optimized product search
  • Loading branch information
ashish-egov authored May 29, 2024
1 parent 613906d commit 08a9cbe
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 63 deletions.
31 changes: 30 additions & 1 deletion utilities/project-factory/src/server/api/campaignApis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,34 @@ async function createProjectCampaignResourcData(request: any) {
}
}

async function confirmProjectParentCreation(request: any, projectId: any) {
const searchBody = {
RequestInfo: request.body.RequestInfo,
Projects: [
{
id: projectId,
tenantId: request.body.CampaignDetails.tenantId
}
]
}
var projectFound = false;
var retry = 6;
while (!projectFound && retry >= 0) {
const response = await httpRequest(config.host.projectHost + config.paths.projectSearch, searchBody);
if (response?.Project?.[0]) {
projectFound = true;
}
else {
logger.info("Project not found. Waiting for 1 seconds");
retry = retry - 1
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
if (!projectFound) {
throwError("PROJECT", 500, "PROJECT_CONFIRMATION_FAILED", "Project confirmation failed, for the project with id " + projectId);
}
}

async function projectCreate(projectCreateBody: any, request: any) {
logger.info("Project creation url " + config.host.projectHost + config.paths.projectCreate)
logger.debug("Project creation body " + getFormattedStringForDebug(projectCreateBody))
Expand Down Expand Up @@ -753,5 +781,6 @@ export {
getHierarchy,
getHeadersOfBoundarySheet,
handleResouceDetailsError,
getFiltersFromCampaignSearchResponse
getFiltersFromCampaignSearchResponse,
confirmProjectParentCreation
};
1 change: 1 addition & 0 deletions utilities/project-factory/src/server/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const CONSTANTS: any = {
PROJECT_SEARCH_ERROR: "Error occured during project search , check projectId",
PROJECT_UPDATE_ERROR: "Error occured during project update , check projectId",
PROJECT_CREATION_ERROR: "Some error occured during project creation",
PROJECT_CONFIRMATION_FAILED: "Error occured in project creation and peristence",
},
MDMS: {
INVALID_README_CONFIG: "Invalid readme config"
Expand Down
120 changes: 58 additions & 62 deletions utilities/project-factory/src/server/utils/campaignUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { httpRequest } from "./request";
import config from "../config/index";
import { v4 as uuidv4 } from 'uuid';
import { produceModifiedMessages } from '../kafka/Listener'
import { createProjectCampaignResourcData, getHierarchy, handleResouceDetailsError, projectCreate } from "../api/campaignApis";
import { confirmProjectParentCreation, createProjectCampaignResourcData, getHierarchy, handleResouceDetailsError, projectCreate } from "../api/campaignApis";
import { getCampaignNumber, createAndUploadFile, getSheetData, createExcelSheet, getAutoGeneratedBoundaryCodesHandler, getTargetSheetData, createBoundaryEntities, createBoundaryRelationship, getMDMSV1Data } from "../api/genericApis";
import { getFormattedStringForDebug, logger } from "./logger";
import createAndSearch from "../config/createAndSearch";
Expand Down Expand Up @@ -531,12 +531,19 @@ async function persistForCampaignProjectMapping(request: any, createResourceDeta
}
}

function removeBoundariesFromRequest(request: any) {
if (request?.body?.CampaignDetails?.boundaries && Array.isArray(request?.body?.CampaignDetails?.boundaries) && request?.body?.CampaignDetails?.boundaries?.length > 0) {
request.body.CampaignDetails.boundaries = request?.body?.CampaignDetails?.boundaries?.filter((boundary: any) => !boundary?.insertedAfter)
}
}


async function enrichAndPersistProjectCampaignRequest(request: any, actionInUrl: any, firstPersist: boolean = false, localizationMap?: any) {
var createResourceDetailsIds: any[] = []
if (request?.body?.CampaignDetails?.resources && Array.isArray(request?.body?.CampaignDetails?.resources) && request?.body?.CampaignDetails?.resources?.length > 0 && request?.body?.CampaignDetails?.action == "create") {
createResourceDetailsIds = getCreateResourceIds(request?.body?.CampaignDetails?.resources);
}
removeBoundariesFromRequest(request);
if (actionInUrl == "create") {
await enrichAndPersistCampaignForCreate(request, firstPersist)
}
Expand Down Expand Up @@ -908,75 +915,54 @@ function mapTargets(boundaryResponses: any, codesTargetMapping: any) {
}
}

async function processBoundaryForData(boundary: any, boundaryCodes: any, boundaries: any[], request: any, includeAllChildren: any = false, parent?: any) {
if (!boundaryCodes.has(boundary.code)) {
boundaries.push({ code: boundary?.code, type: boundary?.boundaryType });
boundaryCodes.add(boundary?.code);
}
if (boundary?.includeAllChildren || includeAllChildren) {
const params = {
tenantId: request?.body?.ResourceDetails?.tenantId,
codes: boundary?.code,
hierarchyType: request?.body?.ResourceDetails?.hierarchyType,
includeChildren: true
}
const boundaryResponse = await httpRequest(config.host.boundaryHost + config.paths.boundaryRelationship, request.body, params);
if (boundaryResponse?.TenantBoundary?.[0]) {
// TODO @nitish add more info in the logger about validation
logger.info(`boundary found for the code ${boundary?.code}`)
logger.debug("Boundary found " +getFormattedStringForDebug(boundaryResponse?.TenantBoundary?.[0]?.boundary));
if (boundaryResponse?.TenantBoundary?.[0]?.boundary?.[0]?.children) {
for (const childBoundary of boundaryResponse.TenantBoundary[0]?.boundary?.[0].children) {
await processBoundaryForData(childBoundary, boundaryCodes, boundaries, request, true, boundary?.code);
}
}
}
}
}


async function processBoundary(boundary: any, boundaryCodes: any, boundaries: any[], request: any, includeAllChildren: any = false, parent?: any) {
if (!boundaryCodes.has(boundary.code)) {
boundaries.push({ code: boundary?.code, type: boundary?.boundaryType });
boundaryCodes.add(boundary?.code);
async function processBoundary(boundaryResponse: any, boundaries: any, includeAllChildren: any, boundaryCodes: any) {
if (!boundaryResponse) return;
if (!boundaryCodes.has(boundaryResponse.code)) {
boundaries.push({ code: boundaryResponse?.code, type: boundaryResponse?.boundaryType, insertedAfter: true });
boundaryCodes.add(boundaryResponse?.code);
}
if (boundary?.includeAllChildren || includeAllChildren) {
const params = {
tenantId: request?.body?.CampaignDetails?.tenantId,
codes: boundary?.code,
hierarchyType: request?.body?.CampaignDetails?.hierarchyType,
includeChildren: true
}
const boundaryResponse = await httpRequest(config.host.boundaryHost + config.paths.boundaryRelationship, request.body, params);
if (boundaryResponse?.TenantBoundary?.[0]) {
// TODO @nitish add more info in the logger about validation
logger.info(`boundary found for the code ${boundary?.code}`)
logger.debug("Boundary found " +getFormattedStringForDebug(boundaryResponse?.TenantBoundary?.[0]?.boundary));
if (boundaryResponse?.TenantBoundary?.[0]?.boundary?.[0]?.children) {
for (const childBoundary of boundaryResponse.TenantBoundary[0]?.boundary?.[0].children) {
await processBoundary(childBoundary, boundaryCodes, boundaries, request, true, boundary?.code);
}
}
if (includeAllChildren && boundaryResponse?.children && Array.isArray(boundaryResponse?.children) && boundaryResponse?.children?.length > 0) {
for (const child of boundaryResponse.children) {
processBoundary(child, boundaries, true, boundaryCodes);
}
}
}

async function addBoundaries(request: any) {
async function addBoundaries(request: any, boundaryResponse: any, boundaryChildren: any) {
var { boundaries } = request?.body?.CampaignDetails;
var boundaryCodes = new Set(boundaries.map((boundary: any) => boundary.code));
for (const boundary of boundaries) {
await processBoundary(boundary, boundaryCodes, boundaries, request, false);
}
await processBoundary(boundaryResponse, boundaries, boundaryChildren[boundaryResponse?.code], boundaryCodes);
request.body.CampaignDetails.boundaries = boundaries
}

async function addBoundariesForData(request: any, CampaignDetails: any) {
var { boundaries } = CampaignDetails;
var boundaryCodes = new Set(boundaries.map((boundary: any) => boundary.code));
for (const boundary of boundaries) {
await processBoundaryForData(boundary, boundaryCodes, boundaries, request, false);
const rootBoundary = getRootBoundaryCode(boundaries)
if (rootBoundary) {
const params = {
tenantId: request?.body?.ResourceDetails?.tenantId,
codes: rootBoundary,
hierarchyType: request?.body?.ResourceDetails?.hierarchyType,
includeChildren: true
}
const boundaryResponse = await httpRequest(config.host.boundaryHost + config.paths.boundaryRelationship, request.body, params);
if (boundaryResponse?.TenantBoundary?.[0]?.boundary?.[0]) {
var boundaryChildren = boundaries.reduce((acc: any, boundary: any) => {
acc[boundary.code] = boundary?.includeAllChildren;
return acc;
}, {});
var boundaryCodes = new Set(boundaries.map((boundary: any) => boundary.code));
await processBoundary(boundaryResponse?.TenantBoundary?.[0]?.boundary?.[0], boundaries, boundaryChildren[boundaryResponse?.TenantBoundary?.[0]?.boundary?.[0]?.code], boundaryCodes);
CampaignDetails.boundaries = boundaries
}
else {
throwError("COMMON", 500, "INTERNAL_SERVER_ERROR", "Some internal server error occured during boundary validation.");
}
}
else {
throwError("COMMON", 500, "INTERNAL_SERVER_ERROR", "There is no root boundary for this campaign.");
}
CampaignDetails.boundaries = boundaries
}

function reorderBoundariesWithParentFirst(reorderedBoundaries: any[], boundaryProjectMapping: any) {
Expand Down Expand Up @@ -1025,7 +1011,8 @@ async function reorderBoundariesOfDataAndValidate(request: any, localizationMap?
}

async function reorderBoundaries(request: any, localizationMap?: any) {
const rootBoundary = getRootBoundaryCode(request?.body?.CampaignDetails?.boundaries)
var { boundaries } = request?.body?.CampaignDetails;
const rootBoundary = getRootBoundaryCode(boundaries)
request.body.boundaryProjectMapping = {}
if (rootBoundary) {
const params = {
Expand All @@ -1035,16 +1022,25 @@ async function reorderBoundaries(request: any, localizationMap?: any) {
includeChildren: true
}
const boundaryResponse = await httpRequest(config.host.boundaryHost + config.paths.boundaryRelationship, request.body, params);
if (boundaryResponse?.TenantBoundary?.[0]?.boundary) {
if (boundaryResponse?.TenantBoundary?.[0]?.boundary?.[0]) {
const codesTargetMapping = await getCodesTarget(request, localizationMap)
mapTargets(boundaryResponse?.TenantBoundary?.[0]?.boundary, codesTargetMapping)
request.body.CampaignDetails.codesTargetMapping = codesTargetMapping
logger.info("codesTargetMapping ");
logger.debug("codesTargetMapping mapping :: " + getFormattedStringForDebug(codesTargetMapping));
mapBoundariesParent(boundaryResponse?.TenantBoundary?.[0]?.boundary, request, null)
mapBoundariesParent(boundaryResponse?.TenantBoundary?.[0]?.boundary?.[0], request, null)
var boundaryChildren = boundaries.reduce((acc: any, boundary: any) => {
acc[boundary.code] = boundary?.includeAllChildren;
return acc;
}, {});
await addBoundaries(request, boundaryResponse?.TenantBoundary?.[0]?.boundary?.[0], boundaryChildren)
}
else {
throwError("COMMON", 500, "INTERNAL_SERVER_ERROR", "Some internal server error occured during boundary validation.");
}
}
await addBoundaries(request)
else {
throwError("COMMON", 500, "INTERNAL_SERVER_ERROR", "There is no root boundary for this campaign.");
}
logger.info("Boundaries for campaign creation in received")
logger.debug("Boundaries after addition " + getFormattedStringForDebug(request?.body?.CampaignDetails?.boundaries));
reorderBoundariesWithParentFirst(request?.body?.CampaignDetails?.boundaries, request?.body?.boundaryProjectMapping)
Expand Down Expand Up @@ -1157,6 +1153,7 @@ async function createProject(request: any, actionUrl: any, localizationMap?: any
Projects[0].address = { tenantId: tenantId, boundary: boundary?.code, boundaryType: boundary?.type }
if (request?.body?.boundaryProjectMapping?.[boundary?.code]?.parent) {
const parent = request?.body?.boundaryProjectMapping?.[boundary?.code]?.parent
await confirmProjectParentCreation(request, request?.body?.boundaryProjectMapping?.[parent]?.projectId)
Projects[0].parent = request?.body?.boundaryProjectMapping?.[parent]?.projectId
}
else {
Expand All @@ -1171,7 +1168,6 @@ async function createProject(request: any, actionUrl: any, localizationMap?: any
}
]
await projectCreate(projectCreateBody, request)
await new Promise(resolve => setTimeout(resolve, 3000));
}
}
else if ((startDate || endDate) && projectId && actionUrl == "update") {
Expand Down

0 comments on commit 08a9cbe

Please sign in to comment.