Skip to content

Commit

Permalink
HCMPRE-218 adding validation for plan config name (egovernments#844)
Browse files Browse the repository at this point in the history
* HCMPRE-218 adding validation for name validation

* HCMPRE-218 adding validation for name validation

* HCMPRE-218 moving "$." into constants

* HCMPRE-218 code review comments

---------

Co-authored-by: kavi_elrey@1993 <[email protected]>
  • Loading branch information
Priyanka-eGov and kavi-egov authored Sep 5, 2024
1 parent f99475a commit 1ed7c59
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ public class ServiceConstants {
public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_CODE = "BOUNDARY_CODE_MAPPING_NOT_FOUND";
public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_MESSAGE = "Boundary Code Mapping is required column is not found.";

public static final String NAME_VALIDATION_LIST_EMPTY_CODE = "NAME_VALIDATION_LIST_EMPTY";
public static final String NAME_VALIDATION_LIST_EMPTY_MESSAGE = "Name Validation list from MDMS is empty";

public static final String NAME_VALIDATION_FAILED_CODE = "NAME_VALIDATION_FAILED";
public static final String NAME_VALIDATION_FAILED_MESSAGE = "Name Validation failed";

public static final String INVALID_PLAN_ID_CODE = "INVALID_PLAN_ID";
public static final String INVALID_PLAN_ID_MESSAGE = "Plan id provided is invalid";

Expand Down Expand Up @@ -121,6 +127,7 @@ public class ServiceConstants {
public static final String DUPLICATE_ACTIVITY_UUIDS_CODE = "DUPLICATE_ACTIVITY_UUIDS";
public static final String DUPLICATE_ACTIVITY_UUIDS_MESSAGE = "Activity UUIDs should be unique";


//mdms constants
public static final String MDMS_PLAN_MODULE_NAME = "hcm-microplanning";
public static final String MDMS_MASTER_ASSUMPTION = "HypothesisAssumptions";
Expand All @@ -129,6 +136,9 @@ public class ServiceConstants {
public static final String MDMS_MASTER_SCHEMAS = "Schemas";
public static final String MDMS_MASTER_METRIC = "Metric";
public static final String MDMS_MASTER_UOM = "Uom";
public static final String MDMS_MASTER_NAME_VALIDATION= "MicroplanNamingRegex";

public static final String JSON_ROOT_PATH = "$.";

public static final String DOT_SEPARATOR = ".";

Expand All @@ -155,4 +165,6 @@ public class ServiceConstants {
public static final String MDMS_SCHEMA_PROPERTIES_IS_REQUIRED = "isRequired";
public static final String BOUNDARY_CODE = "boundaryCode";

public static final String NAME_VALIDATION_DATA = "Data";

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
import digit.config.ServiceConstants;
import digit.repository.PlanConfigurationRepository;
import digit.util.MdmsUtil;
import digit.util.ServiceUtil;
import digit.web.models.*;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand All @@ -29,12 +32,15 @@ public class PlanConfigurationValidator {

private PlanConfigurationRepository planConfigRepository;


private ServiceUtil serviceUtil;
private MultiStateInstanceUtil centralInstanceUtil;

public PlanConfigurationValidator(MdmsUtil mdmsUtil, PlanConfigurationRepository planConfigRepository, MultiStateInstanceUtil centralInstanceUtil) {
public PlanConfigurationValidator(MdmsUtil mdmsUtil, PlanConfigurationRepository planConfigRepository, ServiceUtil serviceUtil, MultiStateInstanceUtil centralInstanceUtil) {
this.mdmsUtil = mdmsUtil;
this.planConfigRepository = planConfigRepository;
this.centralInstanceUtil = centralInstanceUtil;
this.serviceUtil = serviceUtil;
this.centralInstanceUtil = centralInstanceUtil;
}

/**
Expand Down Expand Up @@ -67,11 +73,48 @@ public void validateCreate(PlanConfigurationRequest request) {
// Validate the uniqueness of the 'mappedTo' fields in the resource mappings
validateMappedToUniqueness(planConfiguration.getResourceMapping());

//Validating plan config name against MDMS data
validatePlanConfigName(request, mdmsData);

// Validate the user information in the request
validateUserInfo(request);

}

/**
* Validates the name of the plan configuration against a regex pattern retrieved from MDMS data.
*
* @param request the plan configuration request containing the plan configuration details
* @param mdmsData the MDMS data containing the name validation regex patterns
* @throws CustomException if the JSONPath evaluation fails, the name validation list from MDMS is empty,
* or the plan configuration name validation fails.
*/
public void validatePlanConfigName(PlanConfigurationRequest request, Object mdmsData)
{
PlanConfiguration planConfiguration = request.getPlanConfiguration();

final String jsonPathForNameValidation = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_NAME_VALIDATION + "[*].data";

List<Object> nameValidationListFromMDMS = null;
try {
nameValidationListFromMDMS = JsonPath.read(mdmsData, jsonPathForNameValidation);
} catch (Exception e) {
log.error(jsonPathForNameValidation);
throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE);
}

if (CollectionUtils.isEmpty(nameValidationListFromMDMS)) {
throw new CustomException(NAME_VALIDATION_LIST_EMPTY_CODE, NAME_VALIDATION_LIST_EMPTY_MESSAGE);
}

String regexPattern = (String) nameValidationListFromMDMS.get(0);
if (!serviceUtil.validateStringAgainstRegex(regexPattern, planConfiguration.getName())) {
throw new CustomException(NAME_VALIDATION_FAILED_CODE, NAME_VALIDATION_FAILED_MESSAGE);
}

}


/**
* Validates the assumption values against the assumption keys in the plan configuration.
* If an operation uses an inactive assumption, throws an exception.
Expand Down Expand Up @@ -104,7 +147,7 @@ public void validateAssumptionValue(PlanConfiguration planConfiguration) {
*/
public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) {
PlanConfiguration planConfiguration = request.getPlanConfiguration();
final String jsonPathForAssumption = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]";
final String jsonPathForAssumption = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]";

List<Object> assumptionListFromMDMS = null;
try {
Expand Down Expand Up @@ -153,8 +196,8 @@ public void validateFilestoreId(PlanConfiguration planConfiguration) {
*/
public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) {
PlanConfiguration planConfiguration = request.getPlanConfiguration();
final String jsonPathForTemplateIdentifier = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_UPLOAD_CONFIGURATION + ".*.id";
final String jsonPathForTemplateIdentifierIsRequired = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_UPLOAD_CONFIGURATION + "[?(@.required == true)].id";
final String jsonPathForTemplateIdentifier = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_UPLOAD_CONFIGURATION + ".*.id";
final String jsonPathForTemplateIdentifierIsRequired = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_UPLOAD_CONFIGURATION + "[?(@.required == true)].id";

List<Object> templateIdentifierListFromMDMS = null;
List<Object> requiredTemplateIdentifierFromMDMS = null;
Expand Down Expand Up @@ -221,7 +264,7 @@ public void validateOperationsInputAgainstMDMS(PlanConfigurationRequest request,
.map(File.InputFileTypeEnum::toString)
.collect(Collectors.toList());

final String jsonPathForRuleInputs = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_SCHEMAS;
final String jsonPathForRuleInputs = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_SCHEMAS;
List<Object> ruleInputsListFromMDMS = null;
try {
log.info(jsonPathForRuleInputs);
Expand Down Expand Up @@ -351,9 +394,11 @@ public void validateUpdateRequest(PlanConfigurationRequest request) {
// Validate the uniqueness of the 'mappedTo' fields in the resource mappings
validateMappedToUniqueness(planConfiguration.getResourceMapping());

//Validating plan config name against MDMS data
validatePlanConfigName(request, mdmsData);

// Validate the user information in the request
validateUserInfo(request);

}

/**
Expand Down Expand Up @@ -413,7 +458,7 @@ public void validateResourceMappingAgainstMDMS(PlanConfigurationRequest request,
.map(File.InputFileTypeEnum::toString)
.toList();

final String jsonPathForRuleInputs = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_SCHEMAS;
final String jsonPathForRuleInputs = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_SCHEMAS;
List<Object> ruleInputsListFromMDMS = null;
try {
log.info(jsonPathForRuleInputs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,16 @@ private ModuleDetail getPlanModuleDetail() {
MasterDetail ruleConfigureInputsMasterDetail = MasterDetail.builder().name(MDMS_MASTER_RULE_CONFIGURE_INPUTS).filter(FILTER_DATA).build();
MasterDetail schemaDetails = MasterDetail.builder().name(MDMS_MASTER_SCHEMAS).build();
MasterDetail metricDetails = MasterDetail.builder().name(MDMS_MASTER_METRIC).build();
MasterDetail UnitDetails = MasterDetail.builder().name(MDMS_MASTER_UOM).build();
MasterDetail unitDetails = MasterDetail.builder().name(MDMS_MASTER_UOM).build();
MasterDetail namingRegexDetails = MasterDetail.builder().name(MDMS_MASTER_NAME_VALIDATION).build();

assumptionMasterDetails.add(assumptionMasterDetail);
assumptionMasterDetails.add(uploadConfigMasterDetail);
assumptionMasterDetails.add(ruleConfigureInputsMasterDetail);
assumptionMasterDetails.add(schemaDetails);
assumptionMasterDetails.add(metricDetails);
assumptionMasterDetails.add(UnitDetails);
assumptionMasterDetails.add(unitDetails);
assumptionMasterDetails.add(namingRegexDetails);

return ModuleDetail.builder().masterDetails(assumptionMasterDetails).moduleName(MDMS_PLAN_MODULE_NAME).build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package digit.util;

import org.springframework.stereotype.Component;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class ServiceUtil {

/**
* Validates the given input string against the provided regex pattern.
*
* @param patternString the regex pattern to validate against
* @param inputString the input string to be validated
* @return true if the input string matches the regex pattern, false otherwise
*/
public Boolean validateStringAgainstRegex(String patternString, String inputString) {
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(inputString);
return matcher.matches();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ public class PlanConfiguration {

@JsonProperty("name")
@NotNull
@Size(min = 2, max = 128)
@Pattern(regexp = "^(?!\\p{Punct}+$).*$", message = "Name must not contain only special characters")
@Size(min = 3, max = 128)
private String name = null;

@JsonProperty("executionPlanId")
Expand Down

0 comments on commit 1ed7c59

Please sign in to comment.