Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HCMPRE-169 code review comments #835

Merged
merged 6 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions health-services/plan-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.egov.services</groupId>
<artifactId>services-common</artifactId>
<version>2.9.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<repositories>
<repository>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

@Import({ TracerConfiguration.class })
@SpringBootApplication
@ComponentScan(basePackages = { "digit", "digit.web.controllers" , "digit.config"})
@ComponentScan(basePackages = { "digit", "digit.web.controllers" , "digit.config", "org.egov.common.utils"})
public class Main {

public static void main(String[] args) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,25 @@ public class ServiceConstants {
public static final String ASSUMPTION_VALUE_NOT_FOUND_MESSAGE = "Operation's Assumption value not found in active assumptions list ";

public static final String FILESTORE_ID_INVALID_CODE = "FILESTORE_ID_INVALID";
public static final String FILESTORE_ID_INVALID_MESSAGE = "Resource mapping does not have a Valid File Store Id ";
public static final String FILESTORE_ID_INVALID_MESSAGE = " Resource mapping does not have a Valid File Store Id ";

public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE = "ASSUMPTION_KEY_NOT_FOUND_IN_MDMS";
public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE = "Assumption Key is not present in MDMS";
public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE = "Assumption Key is not present in MDMS ";

public static final String TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS_CODE = "TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS";
public static final String TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS_MESSAGE = "Template Identifier is not present in MDMS";
public static final String TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS_MESSAGE = "Template Identifier is not present in MDMS ";

public static final String REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_CODE = "REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND";
public static final String REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_MESSAGE = "Required Template Identifier is not present in Files";
public static final String REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_MESSAGE = "Required Template Identifier is not present in Files ";

public static final String ONLY_ONE_FILE_OF_REQUIRED_TEMPLATE_IDENTIFIER_CODE = "ONLY_ONE_FILE_OF_REQUIRED_TEMPLATE_IDENTIFIER";
public static final String ONLY_ONE_FILE_OF_REQUIRED_TEMPLATE_IDENTIFIER_MESSAGE = "Only one file of the required template identifier should be present.";
public static final String ONLY_ONE_FILE_OF_REQUIRED_TEMPLATE_IDENTIFIER_MESSAGE = "Only one file of the required template identifier should be present ";

public static final String INPUT_KEY_NOT_FOUND_CODE = "INPUT_KEY_NOT_FOUND";
public static final String INPUT_KEY_NOT_FOUND_MESSAGE = "Operation's Input key not present in MDMS";
public static final String INPUT_KEY_NOT_FOUND_MESSAGE = "Operation's Input key not present in MDMS ";

public static final String LOCALITY_NOT_PRESENT_IN_MAPPED_TO_CODE = "LOCALITY_NOT_PRESENT_IN_MAPPED_TO";
public static final String LOCALITY_NOT_PRESENT_IN_MAPPED_TO_MESSAGE = "Resource Mapping's MappedTo must contain 'Locality'";
public static final String LOCALITY_NOT_PRESENT_IN_MAPPED_TO_MESSAGE = "Resource Mapping's MappedTo must contain 'Locality' ";

public static final String DUPLICATE_MAPPED_TO_VALIDATION_ERROR_CODE = "DUPLICATE_MAPPED_TO_VALIDATION_ERROR";
public static final String DUPLICATE_MAPPED_TO_VALIDATION_ERROR_MESSAGE = "Duplicate MappedTo found in Resource Mapping";
Expand Down Expand Up @@ -76,6 +76,8 @@ 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 INVALID_PLAN_ID_CODE = "INVALID_PLAN_ID";
public static final String INVALID_PLAN_ID_MESSAGE = "Plan id provided is invalid";
//mdms constants
public static final String MDMS_PLAN_MODULE_NAME = "hcm-microplanning";
public static final String MDMS_MASTER_ASSUMPTION = "HypothesisAssumptions";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ public interface PlanConfigurationRepository {

public void update(PlanConfigurationRequest planConfigurationRequest);

public Integer count(PlanConfigurationSearchCriteria planConfigurationSearchCriteria);

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import digit.config.Configuration;
import digit.kafka.Producer;
import digit.repository.PlanConfigurationRepository;
import digit.repository.impl.PlanConfigurationRepositoryImpl;
import digit.service.enrichment.EnrichmentService;
import digit.service.validator.PlanConfigurationValidator;
Expand All @@ -26,12 +27,12 @@ public class PlanConfigurationService {

private PlanConfigurationValidator validator;

private PlanConfigurationRepositoryImpl repository;
private PlanConfigurationRepository repository;

private ResponseInfoFactory responseInfoFactory;

public PlanConfigurationService(Producer producer, EnrichmentService enrichmentService, Configuration config
, PlanConfigurationValidator validator, PlanConfigurationRepositoryImpl repository, ResponseInfoFactory responseInfoFactory) {
, PlanConfigurationValidator validator, PlanConfigurationRepository repository, ResponseInfoFactory responseInfoFactory) {
this.producer = producer;
this.enrichmentService = enrichmentService;
this.config = config;
Expand All @@ -45,12 +46,17 @@ public PlanConfigurationService(Producer producer, EnrichmentService enrichmentS
* @param request The request containing the plan configuration details.
* @return The created plan configuration request.
*/
public PlanConfigurationRequest create(PlanConfigurationRequest request) {
public PlanConfigurationResponse create(PlanConfigurationRequest request) {
enrichmentService.enrichPlanConfigurationBeforeValidation(request);
validator.validateCreate(request);
enrichmentService.enrichCreate(request);
repository.create(request);
return request;
PlanConfigurationResponse response = PlanConfigurationResponse.builder()
.planConfiguration(Collections.singletonList(request.getPlanConfiguration()))
.responseInfo(responseInfoFactory
.createResponseInfoFromRequestInfo(request.getRequestInfo(), true))
.build();
return response;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,16 @@
import digit.repository.PlanRepository;
import digit.util.MdmsUtil;
import digit.web.models.*;
import org.egov.common.utils.MultiStateInstanceUtil;
import org.egov.tracer.model.CustomException;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;

import static digit.config.ServiceConstants.INVALID_PLAN_CONFIG_ID_CODE;
import static digit.config.ServiceConstants.INVALID_PLAN_CONFIG_ID_MESSAGE;
import static digit.config.ServiceConstants.JSONPATH_ERROR_CODE;
import static digit.config.ServiceConstants.JSONPATH_ERROR_MESSAGE;
import static digit.config.ServiceConstants.MDMS_MASTER_METRIC;
import static digit.config.ServiceConstants.MDMS_MASTER_UOM;
import static digit.config.ServiceConstants.MDMS_PLAN_MODULE_NAME;
import static digit.config.ServiceConstants.METRIC_NOT_FOUND_IN_MDMS_CODE;
import static digit.config.ServiceConstants.METRIC_NOT_FOUND_IN_MDMS_MESSAGE;
import static digit.config.ServiceConstants.METRIC_UNIT_NOT_FOUND_IN_MDMS_CODE;
import static digit.config.ServiceConstants.METRIC_UNIT_NOT_FOUND_IN_MDMS_MESSAGE;
import static digit.config.ServiceConstants.*;

@Component
public class PlanValidator {
Expand All @@ -37,18 +25,21 @@ public class PlanValidator {

private MdmsUtil mdmsUtil;

public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil) {
private MultiStateInstanceUtil centralInstanceUtil;

public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil) {
this.planRepository = planRepository;
this.planConfigurationRepository = planConfigurationRepository;
this.mdmsUtil = mdmsUtil;
this.centralInstanceUtil = centralInstanceUtil;
}

/**
* This method performs business validations on plan create requests
* @param request
*/
public void validatePlanCreate(PlanRequest request) {
String rootTenantId = request.getPlan().getTenantId().split("\\.")[0];
String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlan().getTenantId());
Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId);

// Validate activities
Expand Down Expand Up @@ -252,7 +243,7 @@ public void validatePlanUpdate(PlanRequest request) {
// Validate plan existence
validatePlanExistence(request);

String rootTenantId = request.getPlan().getTenantId().split("\\.")[0];
String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlan().getTenantId());
Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId);

// Validate activities
Expand Down Expand Up @@ -290,42 +281,61 @@ public void validatePlanUpdate(PlanRequest request) {

}

/**
* Validates that all target UUIDs within the provided PlanRequest are unique.
*
* @param request the PlanRequest containing the targets to be validated
* @throws CustomException if any target UUIDs are not unique
*/
private void validateTargetUuidUniqueness(PlanRequest request) {
// Collect all target uuids
// Collect all target UUIDs
Set<String> targetUuids = request.getPlan().getTargets().stream()
.map(Target::getId)
.collect(Collectors.toSet());

// If target uuids are not unique, throw an exception
if(targetUuids.size() != request.getPlan().getTargets().size()) {
throw new CustomException("DUPLICATE_TARGET_UUIDS", "Target uuids should be unique");
// If target UUIDs are not unique, throw an exception
if (targetUuids.size() != request.getPlan().getTargets().size()) {
throw new CustomException("DUPLICATE_TARGET_UUIDS", "Target UUIDs should be unique");
Priyanka-eGov marked this conversation as resolved.
Show resolved Hide resolved
}
}

/**
* Validates that all resource UUIDs within the provided PlanRequest are unique.
*
* @param request the PlanRequest containing the resources to be validated
* @throws CustomException if any resource UUIDs are not unique
*/
private void validateResourceUuidUniqueness(PlanRequest request) {
// Collect all resource uuids
// Collect all resource UUIDs
Set<String> resourceUuids = request.getPlan().getResources().stream()
.map(Resource::getId)
.collect(Collectors.toSet());

// If resource uuids are not unique, throw an exception
if(resourceUuids.size() != request.getPlan().getResources().size()) {
throw new CustomException("DUPLICATE_RESOURCE_UUIDS", "Resource uuids should be unique");
// If resource UUIDs are not unique, throw an exception
if (resourceUuids.size() != request.getPlan().getResources().size()) {
throw new CustomException("DUPLICATE_RESOURCE_UUIDS", "Resource UUIDs should be unique");
Priyanka-eGov marked this conversation as resolved.
Show resolved Hide resolved
}
}

/**
* Validates that all activity UUIDs within the provided PlanRequest are unique.
*
* @param request the PlanRequest containing the activities to be validated
* @throws CustomException if any activity UUIDs are not unique
*/
private void validateActivitiesUuidUniqueness(PlanRequest request) {
// Collect all activity uuids
// Collect all activity UUIDs
Set<String> activityUuids = request.getPlan().getActivities().stream()
.map(Activity::getId)
.collect(Collectors.toSet());

// If activity uuids are not unique, throw an exception
if(activityUuids.size() != request.getPlan().getActivities().size()) {
throw new CustomException("DUPLICATE_ACTIVITY_UUIDS", "Activity uuids should be unique");
// If activity UUIDs are not unique, throw an exception
if (activityUuids.size() != request.getPlan().getActivities().size()) {
throw new CustomException("DUPLICATE_ACTIVITY_UUIDS", "Activity UUIDs should be unique");
Priyanka-eGov marked this conversation as resolved.
Show resolved Hide resolved
}
}


/**
* This method validates if the plan id provided in the update request exists
* @param request
Expand All @@ -335,10 +345,21 @@ private void validatePlanExistence(PlanRequest request) {
if(CollectionUtils.isEmpty(planRepository.search(PlanSearchCriteria.builder()
.ids(Collections.singleton(request.getPlan().getId()))
.build()))) {
throw new CustomException("INVALID_PLAN_ID", "Plan id provided is invalid");
throw new CustomException(INVALID_PLAN_ID_CODE, INVALID_PLAN_ID_MESSAGE);
}
}

/**
* Validates the target metrics within the provided PlanRequest against MDMS data.
*
* This method checks each target metric in the plan to ensure it exists in the MDMS data.
* If a metric is not found, it throws a CustomException.
*
* @param request the PlanRequest containing the plan and target metrics to be validated
* @param mdmsData the MDMS data against which the target metrics are validated
* @throws CustomException if there is an error reading the MDMS data using JsonPath
* or if any target metric is not found in the MDMS data
*/
public void validateTargetMetrics(PlanRequest request, Object mdmsData) {
Plan plan = request.getPlan();
final String jsonPathForMetric = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_METRIC + ".*.code";
Expand All @@ -350,34 +371,48 @@ public void validateTargetMetrics(PlanRequest request, Object mdmsData) {
} catch (Exception e) {
throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE);
}

for (Target target : plan.getTargets()) {
if (!metricListFromMDMS.contains(target.getMetric())) {
HashSet<Object> metricSetFromMDMS = new HashSet<>(metricListFromMDMS);
plan.getTargets().stream().forEach(target -> {
if (!metricSetFromMDMS.contains(target.getMetric())) {
throw new CustomException(METRIC_NOT_FOUND_IN_MDMS_CODE, METRIC_NOT_FOUND_IN_MDMS_MESSAGE);
}
}
});

}

/**
* Validates the metric unit details within the provided PlanRequest against MDMS data.
*
* This method extracts metric details from the plan and checks if each metric unit
* is present in the MDMS data. If a metric unit is not found, it throws a CustomException.
*
* @param request the PlanRequest containing the plan and metric details to be validated
* @param mdmsData the MDMS data against which the metric units are validated
* @throws CustomException if there is an error reading the MDMS data using JsonPath
* or if any metric unit is not found in the MDMS data
*/
public void validateMetricDetailUnit(PlanRequest request, Object mdmsData) {
Plan plan = request.getPlan();

List<MetricDetail> metricDetails = plan.getTargets().stream()
.map(Target::getMetricDetail)
.toList();

List<Object> metricUnitListFromMDMS = null;
final String jsonPathForMetricUnit = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_UOM + ".*.code";
List<Object> metricUnitListFromMDMS;
final String jsonPathForMetricUnit = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_UOM + ".*.uomCode";
try {
metricUnitListFromMDMS = JsonPath.read(mdmsData, jsonPathForMetricUnit);
} catch (Exception e) {
throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE);
}

for (MetricDetail metricDetail : metricDetails) {
if (!metricUnitListFromMDMS.contains(metricDetail.getMetricUnit())) {
HashSet<Object> metricUnitSetFromMDMS = new HashSet<>(metricUnitListFromMDMS);
metricDetails.stream().forEach(metricDetail -> {
if (!metricUnitSetFromMDMS.contains(metricDetail.getMetricUnit())) {
throw new CustomException(METRIC_UNIT_NOT_FOUND_IN_MDMS_CODE, METRIC_UNIT_NOT_FOUND_IN_MDMS_MESSAGE);
}
}
});

}

}
Loading
Loading