Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ env: |
value: {{ index .Values "default-localization-locale-list" | quote }}
- name: DEFAULT_LOCALIZATION_MODULE_CREATE_LIST
value: {{ index .Values "default-localization-module-list" | quote }}
- name: DEV_ENABLED
value: "true"
- name: JAVA_OPTS
value: {{ index .Values "heap" | quote }}
- name: JAVA_ARGS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,18 +97,38 @@ public void executeStartupLogic() throws Exception {
defaultDataRequest.setTargetTenantId(tenantCode);
// Create Schema
dataHandlerService.createMdmsSchemaFromFile(defaultDataRequest);
// Load mdms data
mdmsBulkLoader.loadAllMdmsData(defaultDataRequest.getTargetTenantId(), defaultDataRequest.getRequestInfo());
// create Boundary Data
dataHandlerService.createBoundaryDataFromFile(defaultDataRequest);
// upsert localization
localizationUtil.upsertLocalizationFromFile(defaultDataRequest);
// // create User
// dataHandlerService.createUserFromFile(tenantRequest);

// Load default MDMS data (always)
mdmsBulkLoader.loadAllMdmsData(defaultDataRequest.getTargetTenantId(),
defaultDataRequest.getRequestInfo(),
serviceConfig.getDefaultMdmsDataPath());

// Load default localization (always)
localizationUtil.upsertLocalizationFromFile(defaultDataRequest,
serviceConfig.getDefaultLocalizationDataPath());

// Load boundary, localization, user, employee, and workflow config data only if enabled
if (serviceConfig.isDevEnabled()) {
// Load dev MDMS data
mdmsBulkLoader.loadAllMdmsData(defaultDataRequest.getTargetTenantId(),
defaultDataRequest.getRequestInfo(),
serviceConfig.getDevMdmsDataPath());

// Load dev localization
localizationUtil.upsertLocalizationFromFile(defaultDataRequest,
serviceConfig.getDevLocalizationDataPath());

// // create Boundary Data
// dataHandlerService.createBoundaryDataFromFile(defaultDataRequest);
//
// dataHandlerService.createPgrWorkflowConfig(tenantRequest.getTenant().getCode());
// // create Employee
// dataHandlerService.createEmployeeFromFile(defaultDataRequest.getRequestInfo());
// // create User from dev file
// dataHandlerService.createUserFromFile(tenantRequest, serviceConfig.getDevUserDataFile());
// // create PGR workflow config
// dataHandlerService.createPgrWorkflowConfig(tenantRequest.getTenant().getCode());
// // create Employee from dev file
// dataHandlerService.createEmployeeFromFile(defaultDataRequest.getRequestInfo(),
// serviceConfig.getDevEmployeeDataFile());
}

// dataHandlerService.createTenantConfig(tenantRequest);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,42 @@ public void executeStartupLogic() throws Exception {

// Execute your logic
dataHandlerService.createMdmsSchemaFromFile(defaultDataRequest);
mdmsBulkLoader.loadAllMdmsData(defaultDataRequest.getTargetTenantId(), defaultDataRequest.getRequestInfo());
dataHandlerService.createBoundaryDataFromFile(defaultDataRequest);
localizationUtil.upsertLocalizationFromFile(defaultDataRequest);
dataHandlerService.createUserFromFile(tenantRequest);
dataHandlerService.createPgrWorkflowConfig(tenantRequest.getTenant().getCode());
dataHandlerService.createEmployeeFromFile(defaultDataRequest.getRequestInfo());

// Load default MDMS data (always)
mdmsBulkLoader.loadAllMdmsData(defaultDataRequest.getTargetTenantId(),
defaultDataRequest.getRequestInfo(),
serviceConfig.getDefaultMdmsDataPath());

// Load default localization (always)
localizationUtil.upsertLocalizationFromFile(defaultDataRequest,
serviceConfig.getDefaultLocalizationDataPath());

// Load default user (always)
dataHandlerService.createUserFromFile(tenantRequest, serviceConfig.getDefaultUserDataFile());

// Load default employee (always)
dataHandlerService.createEmployeeFromFile(defaultDataRequest.getRequestInfo(),
serviceConfig.getDefaultEmployeeDataFile());

// Load boundary, localization, user, employee, and workflow config data only if enabled
if (serviceConfig.isDevEnabled()) {
// Load dev MDMS data
mdmsBulkLoader.loadAllMdmsData(defaultDataRequest.getTargetTenantId(),
defaultDataRequest.getRequestInfo(),
serviceConfig.getDevMdmsDataPath());

// Load dev localization
localizationUtil.upsertLocalizationFromFile(defaultDataRequest,
serviceConfig.getDevLocalizationDataPath());

dataHandlerService.createBoundaryDataFromFile(defaultDataRequest);

// Load dev users and employees
dataHandlerService.createUserFromFile(tenantRequest, serviceConfig.getDevUserDataFile());
dataHandlerService.createPgrWorkflowConfig(tenantRequest.getTenant().getCode());
dataHandlerService.createEmployeeFromFile(defaultDataRequest.getRequestInfo(),
serviceConfig.getDevEmployeeDataFile());
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,31 @@ public class ServiceConfiguration {

@Value("${scheduler.max.executions}")
private String maxExecution;

@Value("${dev.enabled}")
private boolean devEnabled;

@Value("${default.mdms.data.path}")
private String defaultMdmsDataPath;

@Value("${default.user.data.file}")
private String defaultUserDataFile;

@Value("${default.employee.data.file}")
private String defaultEmployeeDataFile;

@Value("${dev.mdms.data.path}")
private String devMdmsDataPath;

@Value("${dev.user.data.file}")
private String devUserDataFile;

@Value("${dev.employee.data.file}")
private String devEmployeeDataFile;

@Value("${default.localization.data.path}")
private String defaultLocalizationDataPath;

@Value("${dev.localization.data.path}")
private String devLocalizationDataPath;
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ public void createDefaultData(DefaultDataRequest defaultDataRequest) {
mdmsV2Util.createDefaultMdmsData(defaultMdmsDataRequest);
}



// if (defaultDataRequest.getLocales() != null && defaultDataRequest.getModules() != null) {
// for (String locale : defaultDataRequest.getLocales()) {
// DefaultLocalizationDataRequest defaultLocalizationDataRequest = DefaultLocalizationDataRequest.builder().requestInfo(defaultDataRequest.getRequestInfo()).targetTenantId(defaultDataRequest.getTargetTenantId()).locale(locale).modules(defaultDataRequest.getModules()).build();
Expand All @@ -93,7 +95,7 @@ public void createDefaultData(DefaultDataRequest defaultDataRequest) {
// }
}

public User createUserFromFile(TenantRequest tenantRequest) throws IOException {
public User createUserFromFile(TenantRequest tenantRequest, String userFilePath) throws IOException {
String tenantCode = tenantRequest.getTenant().getCode();
StringBuilder uri = new StringBuilder(serviceConfig.getUserHost())
.append(serviceConfig.getUserContextPath())
Expand All @@ -102,8 +104,8 @@ public User createUserFromFile(TenantRequest tenantRequest) throws IOException {
ArrayList<User> userList = new ArrayList<>();

try {
log.info("Reading User.json for tenant: {}", tenantCode);
Resource resource = resourceLoader.getResource("classpath:User.json");
log.info("Reading User file from {} for tenant: {}", userFilePath, tenantCode);
Resource resource = resourceLoader.getResource(userFilePath);
String rawJson = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);

rawJson = rawJson.replace("{tenantid}", tenantCode);
Expand Down Expand Up @@ -151,13 +153,14 @@ public User createUserFromFile(TenantRequest tenantRequest) throws IOException {
}


public void createEmployeeFromFile(RequestInfo requestInfo) throws IOException {
public void createEmployeeFromFile(RequestInfo requestInfo, String employeeFilePath) throws IOException {
String uri = serviceConfig.getHrmsHost() + serviceConfig.getHrmsCreatePath();
String userUpdateUrl = serviceConfig.getUserHost() +serviceConfig.getUserContextPath() + serviceConfig.getUserUpdateEndpoint();
String tenantId = requestInfo.getUserInfo().getTenantId();

try {
Resource resource = resourceLoader.getResource("classpath:HRMS.json");
log.info("Reading Employee file from {}", employeeFilePath);
Resource resource = resourceLoader.getResource(employeeFilePath);
String rawJson = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);

// Replace placeholders with tenant ID
Expand Down Expand Up @@ -603,4 +606,86 @@ public void defaultEmployeeSetup(String tenantId, String emailId) {
createDefaultEmployee(tenantId, emailId, ASSIGNER, "John Smith");
}

/**
* Load production tenant data (mdmsData, localisations, and schema)
* This method loads production data for a new tenant
* Uses all default schemas automatically
* @param newTenantRequest - Request containing tenant information (no schema codes needed)
*/
public void loadNewTenantProductionData(NewTenantRequest newTenantRequest) {
try {
String targetTenantId = newTenantRequest.getTargetTenantId();
RequestInfo requestInfo = newTenantRequest.getRequestInfo();

log.info("Loading production tenant data for new tenant: {}", targetTenantId);

// Ensure UserInfo is present (create dummy if needed)
if (requestInfo.getUserInfo() == null) {
org.egov.common.contract.request.User dummyUser = new org.egov.common.contract.request.User();
dummyUser.setId(1L);
dummyUser.setUserName("system");
dummyUser.setTenantId(targetTenantId);
requestInfo.setUserInfo(dummyUser);
log.info("Created dummy user info for tenant: {}", targetTenantId);
} else {
requestInfo.getUserInfo().setTenantId(targetTenantId);
}
Comment on lines +630 to +632
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Mutating the caller's RequestInfo object may cause unintended side effects.

Calling requestInfo.getUserInfo().setTenantId(targetTenantId) modifies the object passed by the caller. If the caller reuses this RequestInfo for other operations, they may get unexpected behavior. Consider creating a copy or documenting this mutation as intentional.


// Create DefaultDataRequest with all default schemas
DefaultDataRequest defaultDataRequest = DefaultDataRequest.builder()
.requestInfo(requestInfo)
.targetTenantId(targetTenantId)
.schemaCodes(serviceConfig.getDefaultMdmsSchemaList())
.onlySchemas(Boolean.FALSE)
.locales(serviceConfig.getDefaultLocalizationLocaleList())
.modules(serviceConfig.getDefaultLocalizationModuleList())
.build();

log.info("Step 1: Creating MDMS schemas for tenant: {}", targetTenantId);
// 1. Create Schema from file
createMdmsSchemaFromFile(defaultDataRequest);
log.info("✓ Schemas created for new tenant: {}", targetTenantId);

log.info("Step 2: Loading production MDMS data");
// 2. Load production MDMS data
mdmsBulkLoader.loadAllMdmsData(targetTenantId,
requestInfo,
serviceConfig.getDefaultMdmsDataPath());
log.info("✓ Production MDMS data loaded for new tenant: {}", targetTenantId);

log.info("Step 3: Loading production localization data");
// 3. Load production localization
localizationUtil.upsertLocalizationFromFile(defaultDataRequest,
serviceConfig.getDefaultLocalizationDataPath());
log.info("✓ Production localization data loaded for new tenant: {}", targetTenantId);

log.info("Step 4: Creating tenant config in Tenant Management System");
// 4. Create Tenant Configuration
Tenant newTenant = new Tenant();
newTenant.setCode(targetTenantId);
newTenant.setName(targetTenantId);
newTenant.setEmail("admin@" + targetTenantId + ".com");
Comment on lines +664 to +667
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check NewTenantRequest and Tenant classes structure
rg -n "class NewTenantRequest|class Tenant" --type=java -A 25 | head -100

Repository: egovernments/Citizen-Complaint-Resolution-System

Length of output: 11045


🏁 Script executed:

# Check the context around lines 664-667 in DataHandlerService.java
sed -n '650,680p' utilities/default-data-handler/src/main/java/org/egov/handler/service/DataHandlerService.java

Repository: egovernments/Citizen-Complaint-Resolution-System

Length of output: 1596


🏁 Script executed:

# Check if there are configuration properties or defaults being used elsewhere
rg -n "defaultTenantName|defaultTenantEmail|admin@" --type=java -B 2 -A 2 | head -40

Repository: egovernments/Citizen-Complaint-Resolution-System

Length of output: 822


Add tenant name and email to NewTenantRequest or implement configuration defaults.

The code hardcodes placeholder values (name = targetTenantId and email = "admin@" + targetTenantId + ".com") when creating a new Tenant configuration. These placeholders persist permanently in the Tenant Management System. Since NewTenantRequest currently provides only targetTenantId and RequestInfo, consider either:

  • Adding name and email fields to NewTenantRequest to accept proper tenant metadata from the caller, or
  • Implementing configurable defaults (e.g., via ServiceConfiguration) instead of hardcoding placeholder values.

The Tenant model enforces @NotNull on name and @Email validation on email, making these required fields that should be meaningful for production tenants.

🤖 Prompt for AI Agents
In
utilities/default-data-handler/src/main/java/org/egov/handler/service/DataHandlerService.java
around lines 664 to 667, the code currently assigns placeholder tenant name and
email (name = targetTenantId, email = "admin@...") which violates model
validation and persists meaningless values; update the flow so
newTenant.setName(...) and newTenant.setEmail(...) pull real values instead of
hardcoded ones: either extend NewTenantRequest to include name and email and use
those fields here (validate non-null and email format) or read configurable
defaults from ServiceConfiguration (e.g., defaultTenantName and
defaultTenantEmail) and apply them; ensure the chosen source is validated before
setting on Tenant and update callers/tests accordingly.


TenantRequest tenantRequest = TenantRequest.builder()
.requestInfo(requestInfo)
.tenant(newTenant)
.build();

try {
createTenantConfig(tenantRequest);
log.info("✓ Tenant config created: {}", targetTenantId);
} catch (Exception e) {
log.warn("Could not create tenant config (non-critical): {}", e.getMessage());
}

log.info("========================================");
log.info("✓✓✓ Tenant {} created successfully", targetTenantId);
log.info("Loaded: Schemas + Production MDMS + Production Localization + Tenant Config");
log.info("========================================");
} catch (Exception e) {
log.error("Failed to load production tenant data for tenant: {}", newTenantRequest.getTargetTenantId(), e);
throw new CustomException("TENANT_CREATION_FAILED", "Failed to create new tenant with production data: " + e.getMessage());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ public void createLocalizationData(DefaultLocalizationDataRequest defaultLocaliz
}
}

public void upsertLocalizationFromFile(DefaultDataRequest defaultDataRequest){
public void upsertLocalizationFromFile(DefaultDataRequest defaultDataRequest, String localizationPath){

List<Message> messageList = addMessagesFromFile(defaultDataRequest);
List<Message> messageList = addMessagesFromFile(defaultDataRequest, localizationPath);
defaultDataRequest.getRequestInfo().getUserInfo().setId(128L);

String tenantId = defaultDataRequest.getTargetTenantId();
Expand Down Expand Up @@ -88,14 +88,15 @@ public void upsertLocalizationFromFile(DefaultDataRequest defaultDataRequest){
}
}

public List addMessagesFromFile(DefaultDataRequest defaultDataRequest){
public List<Message> addMessagesFromFile(DefaultDataRequest defaultDataRequest, String localizationPath){
List<Message> messages = new ArrayList<>();
ObjectMapper objectMapper = new ObjectMapper();

try {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

Resource[] resources = resolver.getResources("classpath:localisations/*/*.json");
Resource[] resources = resolver.getResources(localizationPath);
log.info("Loading localization from path: {}", localizationPath);

for (Resource resource : resources) {
try (InputStream inputStream = resource.getInputStream()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ public class MdmsBulkLoader {
private final ServiceConfiguration serviceConfig;


public void loadAllMdmsData(String tenantId, RequestInfo requestInfo) {
public void loadAllMdmsData(String tenantId, RequestInfo requestInfo, String mdmsDataPath) {
try {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

// Match all files inside mdmsData/**.json
Resource[] resources = resolver.getResources("classpath:mdmsData/**/*.json");
// Match all files inside the specified path
Resource[] resources = resolver.getResources(mdmsDataPath);

for (Resource resource : resources) {
String fileName = resource.getFilename();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.egov.handler.web.models.DataSetupRequest;
import org.egov.handler.web.models.DataSetupResponse;
import org.egov.handler.web.models.DefaultDataRequest;
import org.egov.handler.web.models.NewTenantRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand Down Expand Up @@ -45,4 +46,16 @@ public ResponseEntity<DataSetupResponse> DefaultDataCreatePost(@Valid @RequestBo
return new ResponseEntity<>(dataSetupResponse, HttpStatus.ACCEPTED);
}

@RequestMapping(value = "/tenant/new", method = RequestMethod.POST)
public ResponseEntity<DataSetupResponse> createNewTenant(@Valid @RequestBody NewTenantRequest newTenantRequest) {
dataHandlerService.loadNewTenantProductionData(newTenantRequest);
ResponseInfo responseInfo = responseInfoFactory.createResponseInfoFromRequestInfo(newTenantRequest.getRequestInfo(), true);

DataSetupResponse dataSetupResponse = DataSetupResponse.builder()
.responseInfo(responseInfo)
.targetTenantId(newTenantRequest.getTargetTenantId())
.build();
return new ResponseEntity<>(dataSetupResponse, HttpStatus.ACCEPTED);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.egov.handler.web.models;

import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.*;
import org.egov.common.contract.request.RequestInfo;
import org.springframework.validation.annotation.Validated;

@Validated
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class NewTenantRequest {

@JsonProperty("RequestInfo")
@NotNull
@Valid
private RequestInfo requestInfo;

@JsonProperty("targetTenantId")
@NotNull
@Valid
private String targetTenantId;

}
Loading