From bc419595944ec1b68a3352e5e7dc70447cb00f5f Mon Sep 17 00:00:00 2001 From: Gaurav Kumar Date: Sat, 8 Nov 2025 17:24:45 +0530 Subject: [PATCH] dashboard --- .../Builders/Services/BuilderService.java | 247 ++- .../Controllers/Data_lakeController.java | 23 +- .../tokenFree_Data_lakeController.java | 6 +- .../realnet/DataLake/Entity/Data_lake.java | 16 + .../Services/DataLakeActionService.java | 963 ++++++++++++ .../DataLake/Services/Data_lakeService.java | 1339 ++++++++++------- .../controllers/ChartTemplateController.java | 90 ++ .../controllers/ChartTypeController.java | 83 + .../ComponentPropertyController.java | 92 ++ .../controllers/DynamicFieldController.java | 90 ++ .../controllers/UiComponentController.java | 91 ++ .../entities/ChartTemplate.java | 149 ++ .../DynamicDashbard/entities/ChartType.java | 168 +++ .../entities/ComponentProperty.java | 134 ++ .../entities/DynamicField.java | 179 +++ .../DynamicDashbard/entities/UiComponent.java | 94 ++ .../repositories/ChartTemplateRepository.java | 19 + .../repositories/ChartTypeRepository.java | 18 + .../ComponentPropertyRepository.java | 15 + .../repositories/DynamicFieldRepository.java | 18 + .../repositories/UiComponentRepository.java | 18 + .../services/ChartTemplateService.java | 58 + .../services/ChartTypeService.java | 55 + .../services/ComponentPropertyService.java | 57 + .../services/DynamicFieldService.java | 61 + .../services/UiComponentService.java | 60 + .../Rpt_builder2/Entity/Rpt_builder2_t.java | 13 +- .../Services/Rpt_builder2_Service.java | 25 +- .../Rpt_builder2_lines_Controller.java | 147 +- .../realnet/rb/entity/Rn_report_builder.java | 8 - .../rb/service/Rn_rb_tables_serviceImpl.java | 4 +- .../Rn_report_builder_serviceIpml.java | 339 ++--- .../realnet/scheduler/Entity/JobEntity.java | 79 + .../scheduler/Repository/JobRepository.java | 15 + .../scheduler/controller/JobController.java | 64 + .../services/SmartSchedulerService.java | 249 +++ 36 files changed, 4295 insertions(+), 791 deletions(-) create mode 100644 backend/src/main/java/com/realnet/DataLake/Services/DataLakeActionService.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/controllers/ChartTemplateController.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/controllers/ChartTypeController.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/controllers/ComponentPropertyController.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/controllers/DynamicFieldController.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/controllers/UiComponentController.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/entities/ChartTemplate.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/entities/ChartType.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/entities/ComponentProperty.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/entities/DynamicField.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/entities/UiComponent.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/repositories/ChartTemplateRepository.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/repositories/ChartTypeRepository.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/repositories/ComponentPropertyRepository.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/repositories/DynamicFieldRepository.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/repositories/UiComponentRepository.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/services/ChartTemplateService.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/services/ChartTypeService.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/services/ComponentPropertyService.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/services/DynamicFieldService.java create mode 100644 backend/src/main/java/com/realnet/DynamicDashbard/services/UiComponentService.java create mode 100644 backend/src/main/java/com/realnet/scheduler/Entity/JobEntity.java create mode 100644 backend/src/main/java/com/realnet/scheduler/Repository/JobRepository.java create mode 100644 backend/src/main/java/com/realnet/scheduler/controller/JobController.java create mode 100644 backend/src/main/java/com/realnet/scheduler/services/SmartSchedulerService.java diff --git a/backend/src/main/java/com/realnet/Builders/Services/BuilderService.java b/backend/src/main/java/com/realnet/Builders/Services/BuilderService.java index f9801fb..2ae85df 100644 --- a/backend/src/main/java/com/realnet/Builders/Services/BuilderService.java +++ b/backend/src/main/java/com/realnet/Builders/Services/BuilderService.java @@ -64,10 +64,21 @@ public class BuilderService { @Autowired private AppUserServiceImpl userServiceImpl; +// @Autowired +// private SqlDumpExecutor sqlDumpExecutor; + public void callotherService() throws IOException { executeDump(true); +// String sqlDump = getSqlDump(); // your method to get the dump as string +// +// try (Connection connection = SQLiteUtil.getConnection()) { +// sqlDumpExecutor.executeDump(connection, sqlDump); // your method for executing dump only once +// } catch (SQLException e) { +// e.printStackTrace(); +// } + // ADD OTHER SERVICE System.out.println("dashboard and menu inserted..."); @@ -187,7 +198,7 @@ public class BuilderService { HashMap hashMap = new HashMap<>(); hashMap.put("GetAll", "/" + tableName + "/" + tableName); - hashMap.put("GetById", "/" + tableName + "/" + tableName + "{Id}"); + hashMap.put("GetById", "/" + tableName + "/" + tableName + "/{Id}"); hashMap.put("Post", "/" + tableName + "/" + tableName); hashMap.put("Put", "/" + tableName + "/" + tableName); @@ -232,7 +243,7 @@ public class BuilderService { public ResponseEntity executeDump(Boolean execute) throws IOException { // Check if execution is allowed - System.out.println(" dump executed start.."); + System.out.println(" dump executed start.. \n"); Builder_entity_t entity_t = builderRepository.findByjobTypeAndName("SqlDump", "Execute"); @@ -303,6 +314,238 @@ public class BuilderService { } + public String getSqlDump() { + String sqlDump = "-- SQLite compatible dump\n" + "\n" + "PRAGMA foreign_keys=OFF;\n" + "\n" + + "-- Table: accounts\n" + "DROP TABLE IF EXISTS accounts;\n" + "CREATE TABLE accounts (\n" + + " id INTEGER PRIMARY KEY,\n" + " companyname TEXT,\n" + " email TEXT,\n" + + " managing_work TEXT,\n" + " mobile INTEGER,\n" + " name TEXT,\n" + " pancard TEXT,\n" + + " password TEXT,\n" + " working TEXT\n" + ");\n" + "\n" + + "INSERT INTO accounts VALUES (1,'test','test@gmail.com','w',123456789,'kk','kk','test','w');\n" + "\n" + + "-- Table: app_user_log\n" + "DROP TABLE IF EXISTS app_user_log;\n" + "CREATE TABLE app_user_log (\n" + + " log_id INTEGER PRIMARY KEY,\n" + " created_on TEXT,\n" + " generate_log TEXT,\n" + + " log_file_name TEXT,\n" + " log_level TEXT,\n" + " user_name TEXT UNIQUE\n" + ");\n" + "\n" + + "INSERT INTO app_user_log VALUES (1,'2023-06-09 17:39:20','Y','sysadmin1686312560.log','info','sysadmin');\n" + + "\n" + "-- Table: app_user_log_sequence\n" + "DROP TABLE IF EXISTS app_user_log_sequence;\n" + + "CREATE TABLE app_user_log_sequence (\n" + " next_val INTEGER\n" + ");\n" + "\n" + + "INSERT INTO app_user_log_sequence VALUES (2),(2),(2),(2),(2),(2),(2),(2),(2),(1);\n" + "\n" + + "-- Table: logs\n" + "DROP TABLE IF EXISTS logs;\n" + "CREATE TABLE logs (\n" + + " user_id INTEGER PRIMARY KEY,\n" + " dated TEXT,\n" + " lavel TEXT,\n" + " logger TEXT,\n" + + " message TEXT\n" + ");\n" + "\n" + "-- Table: role\n" + "DROP TABLE IF EXISTS role;\n" + + "CREATE TABLE role (\n" + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + " description TEXT,\n" + + " name TEXT\n" + ");\n" + "\n" + + "INSERT INTO role VALUES (1,'ADMIN','ROLE_ADMIN'),(2,'Developer','ROLE_Developer'),(3,'USER','ROLE_USER'),(5,'DEVEOPS','ROLE_DEVEOPS');\n" + + "\n" + "-- Table: sec_menu_det\n" + "DROP TABLE IF EXISTS sec_menu_det;\n" + + "CREATE TABLE sec_menu_det (\n" + " menu_item_id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + + " created_at TEXT NOT NULL,\n" + " updated_at TEXT NOT NULL,\n" + " item_seq INTEGER,\n" + + " main_menu_action_name TEXT,\n" + " main_menu_icon_name TEXT,\n" + " menu_id INTEGER,\n" + + " menu_item_desc TEXT,\n" + " module_name TEXT,\n" + " status TEXT\n" + ");\n" + "\n" + + "INSERT INTO sec_menu_det VALUES\n" + + "(1116,'2023-01-25 10:25:50','2023-01-25 10:25:50',3000,'security','lock',0,'Security','sec3000','Enable'),\n" + + "(1117,'2023-01-25 10:42:02','2023-02-04 15:34:25',3010,'usermaintance',NULL,1116,'User Maintance','U1000','Enable'),\n" + + "(1118,'2023-01-25 11:12:27','2023-02-04 15:34:36',3020,'usergrpmaintance',NULL,1116,'User Group Maintance','U2000','Enable'),\n" + + "(1523,'2023-02-04 11:15:57','2023-02-04 15:34:45',3030,'menumaintance',NULL,1116,'Menu Maintance','M3000','Enable'),\n" + + "(1524,'2023-02-04 11:16:52','2023-02-04 15:34:54',3040,'menuaccess',NULL,1116,'Menu Access Control','MA4000','Enable'),\n" + + "(1525,'2023-02-04 11:17:31','2023-02-04 15:35:06',3050,'systemparameters',NULL,1116,'System Parameters','SP5000','Enable'),\n" + + "(1526,'2023-02-04 11:18:04','2023-02-04 15:35:14',3060,'accesstype',NULL,1116,'Access Type','A6000','Enable'),\n" + + "(1528,'2023-02-04 13:31:48','2023-02-04 15:33:02',1010,'incident-new',NULL,1527,'Incident','I1000','Enable'),\n" + + "(1529,'2023-02-04 13:33:03','2023-02-04 15:33:12',1020,'incident-overview',NULL,1527,'Overview','O2000','Enable'),\n" + + "(1530,'2023-02-04 13:34:42','2023-02-04 15:33:21',1030,'sureboard2',NULL,1527,'Issueboard','I3000','Enable'),\n" + + "(1531,'2023-02-04 13:35:27','2023-02-04 15:33:36',1040,'change-request',NULL,1527,'Change Request','C4000','Enable'),\n" + + "(1532,'2023-02-04 13:36:01','2023-02-10 02:25:13',1050,'problem-creation',NULL,1527,'Problem Request','P5000','Enable');\n" + + "-- truncated for brevity: continue for all sec_menu_det inserts\n" + "\n" + + "-- Table: sec_user_group\n" + "DROP TABLE IF EXISTS sec_user_group;\n" + + "CREATE TABLE sec_user_group (\n" + " usr_grp INTEGER PRIMARY KEY,\n" + " createby TEXT,\n" + + " createdate TEXT,\n" + " group_desc TEXT,\n" + " group_level INTEGER,\n" + " group_name TEXT,\n" + + " status TEXT,\n" + " updateby TEXT,\n" + " updatedate TEXT\n" + ");\n" + "\n" + + "INSERT INTO sec_user_group VALUES (1,NULL,NULL,'add',30,'sysadmin','E',NULL,'2023-03-01 05:54:10'),(41,NULL,'2023-02-28 13:05:54','check',20,'users','Disable',NULL,'2023-02-28 13:30:14');\n" + + "\n" + "-- Table: sec_user_group_id\n" + "DROP TABLE IF EXISTS sec_user_group_id;\n" + + "CREATE TABLE sec_user_group_id (next_val INTEGER);\n" + "\n" + + "INSERT INTO sec_user_group_id VALUES (59),(59),(40),(40),(40),(40),(40),(40);\n" + "\n" + + "-- Table: department\n" + "DROP TABLE IF EXISTS department;\n" + "CREATE TABLE department (\n" + + " department_code TEXT PRIMARY KEY,\n" + " active TEXT,\n" + " created_by TEXT,\n" + + " created_on TEXT,\n" + " description TEXT,\n" + " id INTEGER,\n" + " updated_by TEXT\n" + ");\n" + + "\n" + "-- Table: position\n" + "DROP TABLE IF EXISTS position;\n" + "CREATE TABLE position (\n" + + " position_code TEXT PRIMARY KEY,\n" + " active TEXT,\n" + " created_by TEXT,\n" + + " created_on TEXT,\n" + " description TEXT,\n" + " updated_by TEXT,\n" + " updated_on TEXT\n" + + ");\n" + "\n" + "-- Table: sys_accounts\n" + "DROP TABLE IF EXISTS sys_accounts;\n" + "\n" + + "CREATE TABLE sys_accounts (\n" + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + + " active INTEGER DEFAULT 0,\n" + " company_name TEXT,\n" + " email TEXT,\n" + " gst_no TEXT,\n" + + " mobile TEXT,\n" + " pancard TEXT,\n" + " working TEXT,\n" + " workspace TEXT\n" + ");\n" + "\n" + + "INSERT INTO sys_accounts VALUES (1,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL);\n" + "" + + + "\n" + "-- Table: sec_users\n" + "DROP TABLE IF EXISTS sec_users;\n" + "\n" + + "CREATE TABLE sec_users (\n" + " user_id INTEGER PRIMARY KEY,\n" + + " is_complete INTEGER NOT NULL,\n" + " about TEXT,\n" + " accesstype TEXT,\n" + + " active INTEGER NOT NULL,\n" + " change_passw TEXT,\n" + " checknumber INTEGER,\n" + + " country TEXT,\n" + " createby TEXT,\n" + " createdate TEXT NOT NULL,\n" + + " customer_id INTEGER,\n" + " days_mth TEXT,\n" + " dep_string TEXT,\n" + " email TEXT,\n" + + " expiry_date TEXT,\n" + " first_login TEXT,\n" + " full_name TEXT,\n" + + " is_blocked INTEGER NOT NULL,\n" + " lang_code TEXT,\n" + " last_pwd_changed_date TEXT,\n" + + " mob_no INTEGER,\n" + " multilingual TEXT,\n" + " multitime TEXT,\n" + " no_days_mth INTEGER,\n" + + " notification TEXT,\n" + " password1 TEXT,\n" + " password2 TEXT,\n" + " password3 TEXT,\n" + + " password4 TEXT,\n" +// + " photo BLOB,\n" + + " photo_name TEXT,\n" + " provider TEXT,\n" + " pwd_changed_cnt INTEGER,\n" + " random_no TEXT,\n" + + " short_name TEXT,\n" + " status TEXT,\n" + " title TEXT,\n" + " updateby TEXT,\n" + + " updatedate TEXT,\n" + " user_passw TEXT,\n" + " user_name TEXT,\n" + " usr_grp_id INTEGER,\n" + + " working TEXT,\n" + " account_id INTEGER,\n" + " department_code TEXT,\n" + + " position_code TEXT,\n" + " usr_grp INTEGER\n" + ");\n" + "\n" + "INSERT INTO sec_users VALUES (\n" + + " 10007307,1,NULL,NULL,1,'test3',NULL,NULL,NULL,'2024-09-03 19:32:38',NULL,NULL,NULL,\n" + + " 'sysadmin',NULL,NULL,'sysadmin',0,NULL,'2024-09-03 19:32:38',1234567890,NULL,NULL,NULL,NULL,\n" + + " 'admin123',NULL,NULL,NULL,NULL,NULL,7,NULL,NULL,NULL,NULL,NULL,NULL,\n" + + " '$2b$10$8iFnL/cKTTmclSD1BZh8UeP0ZKKEzZ2hbTsrRcgy3kMinDRdxN7xe','sysadmin',NULL,NULL,1,NULL,NULL,1\n" + + ");" + + + "-- Table: sec_user_sessions\n" + "DROP TABLE IF EXISTS sec_user_sessions;\n" + + "CREATE TABLE IF NOT EXISTS sec_user_sessions (\n" + " client_ip TEXT NOT NULL,\n" + + " session_id TEXT NOT NULL,\n" + " user_id INTEGER NOT NULL,\n" + " last_access_date TEXT,\n" + + " logintime TEXT,\n" + " logouttime TEXT,\n" + " macid TEXT,\n" + + " PRIMARY KEY (client_ip, session_id, user_id),\n" + + " FOREIGN KEY (user_id) REFERENCES sec_users(user_id)\n" + ");\n" + "\n" + "" + "" + + + "\n" + "-- Table: sec_grp_menu_access\n" + "DROP TABLE IF EXISTS sec_grp_menu_access;\n" + + "CREATE TABLE sec_grp_menu_access (\n" + " menu_item_id INTEGER NOT NULL,\n" + + " usr_grp INTEGER NOT NULL,\n" + " createby TEXT,\n" + " created_at TEXT,\n" + + " isdisable TEXT,\n" + " item_seq INTEGER,\n" + " m_create TEXT,\n" + " m_delete TEXT,\n" + + " m_edit TEXT,\n" + " m_query TEXT,\n" + " m_visible TEXT,\n" + " main_menu_action_name TEXT,\n" + + " main_menu_icon_name TEXT,\n" + " menu_id INTEGER,\n" + " menu_item_desc TEXT,\n" + + " mexport TEXT,\n" + " module_name TEXT,\n" + " status TEXT,\n" + " updateby TEXT,\n" + + " updated_at TEXT,\n" + " PRIMARY KEY (menu_item_id, usr_grp)\n" + ");\n" + "\n" + + "INSERT INTO sec_grp_menu_access VALUES\n" + + "(1116,41,NULL,'2024-01-17 18:56:05','true',3000,'true','true','true','true','true','security','lock',0,'Security','true','sec3000','Enable',NULL,'2024-01-17 18:56:05'),\n" + + "(1117,41,NULL,'2024-01-17 18:56:07','true',3010,'true','true','true','true','true','usermaintance',NULL,1116,'User Maintance','true','U1000','Enable',NULL,'2024-01-17 18:56:07');\n" + + "\n" + "-- Table: sec_users_sequencs\n" + "DROP TABLE IF EXISTS sec_users_sequencs;\n" + + "CREATE TABLE sec_users_sequencs (\n" + " next_val INTEGER\n" + ");\n" + "\n" + + "INSERT INTO sec_users_sequencs VALUES\n" + + "(10007321),(10007300),(10007300),(10007300),(10007300),(10007300),(10007300),(10007300);\n" + "\n" + + "-- Table: sec_workspace\n" + "DROP TABLE IF EXISTS sec_workspace;\n" + + "CREATE TABLE sec_workspace (\n" + " id INTEGER PRIMARY KEY,\n" + " account_id INTEGER,\n" + + " created_at TEXT NOT NULL,\n" + " created_by INTEGER,\n" + " updated_at TEXT NOT NULL,\n" + + " updated_by INTEGER,\n" + " is_active TEXT,\n" + " description TEXT,\n" + " is_default TEXT,\n" + + " name TEXT,\n" + " owner_id TEXT,\n" + " project_id INTEGER\n" + ");\n" + + + "" + "-- Table: sec_workspace_users\n" + "DROP TABLE IF EXISTS sec_workspace_users;\n" + + "CREATE TABLE sec_workspace_users (\n" + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + + " account_id INTEGER,\n" + " created_at TEXT NOT NULL,\n" + " created_by INTEGER,\n" + + " updated_at TEXT NOT NULL,\n" + " updated_by INTEGER,\n" + " project_id INTEGER,\n" + + " user_id INTEGER,\n" + " user_name TEXT,\n" + " user_role TEXT,\n" + + " worksapce_id INTEGER NOT NULL\n" + ");\n" + "\n" + "-- Table: secuser_roles\n" + + "DROP TABLE IF EXISTS secuser_roles;\n" + "CREATE TABLE secuser_roles (\n" + + " secuser_id INTEGER NOT NULL,\n" + " role_id INTEGER NOT NULL,\n" + + " PRIMARY KEY (secuser_id, role_id),\n" + + " FOREIGN KEY (secuser_id) REFERENCES sec_users(user_id),\n" + + " FOREIGN KEY (role_id) REFERENCES role(id)\n" + ");\n" + "\n" + "-- Insert sample data\n" + + "INSERT INTO secuser_roles (secuser_id, role_id) VALUES (10007307, 1);\n" + "\n" + + "-- Table: sys_accounts_users\n" + "DROP TABLE IF EXISTS sys_accounts_users;\n" + + "CREATE TABLE sys_accounts_users (\n" + " sys_accounts_id INTEGER NOT NULL,\n" + + " users_user_id INTEGER NOT NULL,\n" + " UNIQUE(users_user_id),\n" + + " FOREIGN KEY (users_user_id) REFERENCES sec_users(user_id),\n" + + " FOREIGN KEY (sys_accounts_id) REFERENCES sys_accounts(id)\n" + ");\n" + "\n" + + "-- Table: user_list\n" + "DROP TABLE IF EXISTS user_list;\n" + "CREATE TABLE user_list (\n" + + " id INTEGER PRIMARY KEY,\n" + " about TEXT,\n" + " account_id TEXT,\n" + " address1 TEXT,\n" + + " address2 TEXT,\n" + " checknumber TEXT,\n" + " company TEXT,\n" + " country TEXT,\n" + + " created_at TEXT,\n" + " created_by TEXT,\n" + " default_customer_id TEXT,\n" + + " department TEXT,\n" + " dob TEXT,\n" + " email TEXT,\n" + + " enable_beta_testing INTEGER NOT NULL,\n" + " enable_renewal INTEGER NOT NULL,\n" + + " firstname TEXT,\n" + " fullname TEXT,\n" + " gender TEXT,\n" + " is_active INTEGER NOT NULL,\n" + + " is_blocked INTEGER NOT NULL,\n" + " lastname TEXT,\n" + " managing_work TEXT,\n" + + " menu_group INTEGER NOT NULL,\n" + " name TEXT,\n" + " other_roles TEXT,\n" + " pancard TEXT,\n" + + " password TEXT,\n" + " phone TEXT,\n" + " photos TEXT,\n" + " postal TEXT,\n" + " role TEXT,\n" + + " secret_answer TEXT,\n" + " secret_question TEXT,\n" + " security_provider_id TEXT,\n" + + " status TEXT,\n" + " updated_at TEXT,\n" + " updated_by TEXT,\n" + " user_id TEXT,\n" + + " username TEXT,\n" + " working TEXT\n" + ");\n" + "" + "" + "-- Table: userloginhist\n" + + "DROP TABLE IF EXISTS userloginhist;\n" + "CREATE TABLE userloginhist (\n" + " create_by TEXT,\n" + + " create_date TEXT,\n" + " expiry_reminder INTEGER,\n" + " last_login_date TEXT,\n" + + " last_password_chg_date TEXT,\n" + " last_password_fail_no INTEGER,\n" + " update_by TEXT,\n" + + " update_date TEXT,\n" + " user_id INTEGER NOT NULL,\n" + " PRIMARY KEY(user_id),\n" + + " FOREIGN KEY(user_id) REFERENCES sec_users(user_id)\n" + ");\n" + "\n" + "-- Table: userpasswlog\n" + + "DROP TABLE IF EXISTS userpasswlog;\n" + "CREATE TABLE userpasswlog (\n" + + " create_date TEXT NOT NULL,\n" + " user_id INTEGER NOT NULL,\n" + " user_passw TEXT NOT NULL,\n" + + " create_by TEXT,\n" + " update_by TEXT,\n" + " update_date TEXT,\n" + + " PRIMARY KEY(create_date, user_id, user_passw),\n" + + " FOREIGN KEY(user_id) REFERENCES sec_users(user_id)\n" + ");\n" + "\n" + "-- Table: dashboard\n" + + "DROP TABLE IF EXISTS dashboard;\n" + "CREATE TABLE dashboard (\n" + + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + " account_id INTEGER,\n" + + " created_at TEXT NOT NULL,\n" + " created_by INTEGER,\n" + " updated_at TEXT NOT NULL,\n" + + " updated_by INTEGER,\n" + " extn1 TEXT,\n" + " extn2 TEXT,\n" + " extn3 TEXT,\n" + + " extn4 TEXT,\n" + " extn5 TEXT,\n" + " extn6 TEXT,\n" + " extn7 TEXT,\n" + " extn8 TEXT,\n" + + " extn9 TEXT,\n" + " extn10 TEXT,\n" + " extn11 TEXT,\n" + " extn12 TEXT,\n" + " extn13 TEXT,\n" + + " extn14 TEXT,\n" + " extn15 TEXT,\n" + " isdashboard INTEGER NOT NULL,\n" + " model TEXT,\n" + + " name TEXT\n" + ");\n" + "\n" + "-- Insert sample data\n" + + "INSERT INTO dashboard VALUES (1,NULL,'2023-12-04 12:11:04',NULL,'2023-12-04 13:05:56',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,'[{\\\"charttitle\\\":\\\"index1\\\",\\\"type\\\":\\\"Index\\\",\\\"cols\\\":5,\\\"rows\\\":5,\\\"x\\\":0,\\\"y\\\":0,\\\"chartid\\\":3,\\\"component\\\":\\\"Index\\\",\\\"name\\\":\\\"Index\\\",\\\"slices\\\":false,\\\"donut\\\":false,\\\"chartcolor\\\":false,\\\"chartlegend\\\":false,\\\"showlabel\\\":false,\\\"Read Only\\\":false,\\\"selectedIcon\\\":\\\"IconData(U+0EE2A)\\\",\\\"charturl\\\":\\\"\\\",\\\"chartparameter\\\":\\\"\\\",\\\"datasource\\\":\\\"Default\\\"},{\\\"charttitle\\\":\\\"Index2\\\",\\\"type\\\":\\\"Index\\\",\\\"cols\\\":5,\\\"rows\\\":5,\\\"x\\\":0,\\\"y\\\":0,\\\"chartid\\\":4,\\\"component\\\":\\\"Index\\\",\\\"name\\\":\\\"Index\\\"},{\\\"charttitle\\\":\\\"Index3\\\",\\\"type\\\":\\\"Index\\\",\\\"cols\\\":5,\\\"rows\\\":5,\\\"x\\\":0,\\\"y\\\":0,\\\"chartid\\\":5,\\\"component\\\":\\\"Index\\\",\\\"name\\\":\\\"Index\\\"},{\\\"charttitle\\\":\\\"Doughnut Chart\\\",\\\"type\\\":\\\"Doughnut Chart\\\",\\\"cols\\\":5,\\\"rows\\\":5,\\\"x\\\":0,\\\"y\\\":0,\\\"chartid\\\":6,\\\"component\\\":\\\"Doughnut Chart\\\",\\\"name\\\":\\\"Doughnut Chart\\\",\\\"slices\\\":false,\\\"donut\\\":false,\\\"chartcolor\\\":false,\\\"chartlegend\\\":false,\\\"showlabel\\\":false,\\\"Read Only\\\":false,\\\"charturl\\\":\\\"http://43.205.154.152:30179/entityBuilder/Gaurav_testing/3\\\",\\\"chartparameter\\\":\\\"\\\",\\\"datasource\\\":\\\"Default\\\",\\\"selectedIcon\\\":\\\"IconData(U+0EE29)\\\"},{\\\"cols\\\": 4, \\\"rows\\\": 5, \\\"x\\\": 0, \\\"y\\\": 0, \\\"chartid\\\": 1, \\\"name\\\": \\\"Line Chart\\\", \\\"fieldName\\\": null, \\\"showlabel\\\": true, \\\"chartcolor\\\": null, \\\"chartlegend\\\": true, \\\"charturl\\\": \\\"http://43.205.154.152:30179/entityBuilder/Gaurav_testing\\\",\\\"xAxis\\\": \\\"name\\\",\\\"donut\\\": null, \\\"chartparameter\\\": null, \\\"datastore\\\": null,\\\"datasource\\\": null,\\\"id\\\": null,\\\"slices\\\": null,\\\"yAxis\\\": [\\\"pincode\\\"],\\\"charttitle\\\": \\\"Live Details\\\"}]','myfirstdashboard');\n" + + "\n" + "-- Table: dashboard_builder_t\n" + "DROP TABLE IF EXISTS dashboard_builder_t;\n" + + "CREATE TABLE dashboard_builder_t (\n" + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + + " dashboardname TEXT\n" + ");\n" + "\n" + "-- Table: dashboard_schedule_t\n" + + "DROP TABLE IF EXISTS dashboard_schedule_t;\n" + "CREATE TABLE dashboard_schedule_t (\n" + + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + " attachment TEXT,\n" + " cc TEXT,\n" + + " cron TEXT,\n" + " end_time TEXT,\n" + " every TEXT,\n" + " gateway TEXT,\n" + + " gatewaydone TEXT,\n" + " replacement_string TEXT,\n" + " send_to TEXT,\n" + + " start_time TEXT,\n" + " template TEXT,\n" + " type TEXT\n" + ");\n" + "\n" + + "-- Table: dashboardaxis\n" + "DROP TABLE IF EXISTS dashboardaxis;\n" + + "CREATE TABLE dashboardaxis (\n" + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + " april TEXT,\n" + + " feb TEXT,\n" + " jan TEXT,\n" + " march TEXT,\n" + " may TEXT\n" + ");\n" + "\n" + + "INSERT INTO dashboardaxis VALUES \n" + "(1,'5','10','25','3',NULL),\n" + + "(3,'5000','15000','10000','30000',NULL),\n" + "(4,'5000','15000','10000','30000',NULL),\n" + + "(5,'5000','15000','5','30000',NULL),\n" + "(6,'5000','15000','10000','30000','2000'),\n" + + "(7,'23','20','25','30','20'),\n" + "(8,'23','20','25','30','99'),\n" + + "(9,'23','20','25','30','20');\n" + "\n" + "-- Table: dashbord_header\n" + + "DROP TABLE IF EXISTS dashbord_header;\n" + "CREATE TABLE dashbord_header (\n" + + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + " account_id INTEGER,\n" + + " created_at TEXT NOT NULL,\n" + " created_by INTEGER,\n" + " updated_at TEXT NOT NULL,\n" + + " updated_by INTEGER,\n" + " is_build INTEGER,\n" + " dashboard_name TEXT,\n" + + " description TEXT,\n" + " menu_name TEXT,\n" + " module_id INTEGER NOT NULL,\n" + + " object_type TEXT,\n" + " secuirity_profile TEXT,\n" + " sub_object_type TEXT,\n" + + " tech_stack TEXT,\n" + " testing INTEGER NOT NULL,\n" + " is_updated INTEGER,\n" + + " add_to_home INTEGER\n" + ");\n" + "\n" + "INSERT INTO dashbord_header VALUES \n" + + "(1,NULL,'2023-11-23 09:06:59',NULL,'2024-02-05 17:55:17',NULL,0,'Testing Dashboard','This is dashboard for testing purpose and using chart make it dynamic.',NULL,0,NULL,'easy',NULL,NULL,0,0,0);\n" + + "\n" + "-- Table: dashbord_line\n" + "DROP TABLE IF EXISTS dashbord_line;\n" + + "CREATE TABLE dashbord_line (\n" + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + " model TEXT,\n" + + " dashboard_name TEXT\n" + ");\n" + "\n" + "INSERT INTO dashbord_line VALUES \n" + "(1,'FF','TT'),\n" + + "(2,'FFhjfh','TT1'),\n" + + "(13,'[{\\\"cols\\\":3,\\\"rows\\\":5,\\\"x\\\":3,\\\"y\\\":5,\\\"chartid\\\":3,\\\"name\\\":\\\"Doughnut Chart\\\",\\\"component\\\":\\\"Doughnut Chart\\\"},{\\\"cols\\\":3,\\\"rows\\\":5,\\\"x\\\":3,\\\"y\\\":0,\\\"chartid\\\":3,\\\"name\\\":\\\"Line Chart\\\",\\\"component\\\":\\\"Line Chart\\\"},{\\\"cols\\\":4,\\\"rows\\\":6,\\\"x\\\":6,\\\"y\\\":0,\\\"chartid\\\":3,\\\"name\\\":\\\"Bar Chart\\\",\\\"component\\\":\\\"Bar Chart\\\"},{\\\"cols\\\":3,\\\"rows\\\":8,\\\"x\\\":0,\\\"y\\\":0,\\\"chartid\\\":3,\\\"name\\\":\\\"Grid View\\\",\\\"component\\\":\\\"Grid View\\\"}]','Dashtest'),\n" + + "(14,'[{\\\"cols\\\":3,\\\"rows\\\":10,\\\"x\\\":0,\\\"y\\\":0,\\\"chartid\\\":3,\\\"name\\\":\\\"Doughnut Chart\\\",\\\"component\\\":\\\"Doughnut Chart\\\"},{\\\"cols\\\":4,\\\"rows\\\":10,\\\"x\\\":3,\\\"y\\\":0,\\\"chartid\\\":2,\\\"name\\\":\\\"Line Chart\\\",\\\"component\\\":\\\"Line Chart\\\"},{\\\"cols\\\":3,\\\"rows\\\":6,\\\"x\\\":0,\\\"y\\\":10,\\\"chartid\\\":4,\\\"name\\\":\\\"Bar Chart\\\",\\\"component\\\":\\\"Bar Chart\\\"},{\\\"cols\\\":6,\\\"rows\\\":11,\\\"x\\\":7,\\\"y\\\":2,\\\"chartid\\\":11,\\\"name\\\":\\\"Grid View\\\",\\\"component\\\":\\\"Grid View\\\"}]','DashboardTesting');\n" + + "\n" + "-- Table: dashbord1_line\n" + "DROP TABLE IF EXISTS dashbord1_line;\n" + + "CREATE TABLE dashbord1_line (\n" + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + " model TEXT,\n" + + " header_id TEXT,\n" + " account_id INTEGER,\n" + " created_at TEXT NOT NULL,\n" + + " created_by INTEGER,\n" + " updated_at TEXT NOT NULL,\n" + " updated_by INTEGER,\n" + + " dashbord_header_id INTEGER,\n" + + " FOREIGN KEY(dashbord_header_id) REFERENCES dashbord_header(id)\n" + ");\n" + "\n" + + "INSERT INTO dashbord1_line VALUES \n" + + "(1,'{\\\"dashboard\\\":[{\\\"cols\\\":4,\\\"rows\\\":5,\\\"x\\\":0,\\\"y\\\":0,\\\"name\\\":\\\"Radar Chart\\\",\\\"component\\\":\\\"Radar Chart\\\"},{\\\"cols\\\":5,\\\"rows\\\":6,\\\"x\\\":4,\\\"y\\\":0,\\\"chartid\\\":null,\\\"component\\\":\\\"Bubble Chart\\\",\\\"name\\\":\\\"Bubble Chart\\\"}]}',NULL,NULL,'2023-11-23 09:06:59',NULL,'2024-02-02 10:34:37',NULL,1);\n" + + "" + "-- Table: rp_builder\n" + "DROP TABLE IF EXISTS rp_builder;\n" + "CREATE TABLE rp_builder (\n" + + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + " account_id INTEGER,\n" + + " created_at TEXT NOT NULL,\n" + " created_by INTEGER,\n" + " updated_at TEXT NOT NULL,\n" + + " updated_by INTEGER,\n" + " is_build INTEGER,\n" + " description TEXT,\n" + " menu_name TEXT,\n" + + " module_id INTEGER NOT NULL,\n" + " page_size TEXT,\n" + " report_builder_name TEXT,\n" + + " secuirity_profile TEXT,\n" + " tech_stack TEXT,\n" + " is_updated INTEGER\n" + ");\n" + "\n" + + "-- Table: rp_line\n" + "DROP TABLE IF EXISTS rp_line;\n" + "CREATE TABLE rp_line (\n" + + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + " account_id INTEGER,\n" + + " created_at TEXT NOT NULL,\n" + " created_by INTEGER,\n" + " updated_at TEXT NOT NULL,\n" + + " updated_by INTEGER,\n" + " model TEXT,\n" + " header_id TEXT,\n" + " rp_builder_id INTEGER,\n" + + " FOREIGN KEY(rp_builder_id) REFERENCES rp_builder(id)\n" + ");\n" + "\n" + + "-- Table: rpt_builder2_t\n" + "DROP TABLE IF EXISTS rpt_builder2_t;\n" + + "CREATE TABLE rpt_builder2_t (\n" + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + + " active INTEGER,\n" + " description TEXT,\n" + " report_name TEXT,\n" + " is_sql INTEGER\n" + + ");\n" + "\n" + "-- Insert sample data\n" + "INSERT INTO rpt_builder2_t VALUES \n" + + "(1,1,'School Changes Reports','School Report',NULL),\n" + "(2,NULL,NULL,'Urltest1',NULL),\n" + + "(3,1,'test','test',1),\n" + "(4,1,'test','test',0);\n" + "\n" + "-- Table: rpt_builder_t\n" + + "DROP TABLE IF EXISTS rpt_builder_t;\n" + "CREATE TABLE rpt_builder_t (\n" + + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + " std_param_json TEXT,\n" + + " adhoc_param_flag INTEGER NOT NULL,\n" + " adhoc_param_string TEXT,\n" + + " date_param_flag INTEGER NOT NULL,\n" + " folder TEXT,\n" + " name TEXT,\n" + " query TEXT\n" + + ");\n" + "\n" + "-- Table: rpt_builder2_lines_t\n" + "DROP TABLE IF EXISTS rpt_builder2_lines_t;\n" + + "CREATE TABLE rpt_builder2_lines_t (\n" + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + + " header_id TEXT,\n" + " model TEXT,\n" + " rpt_builder2_t_id INTEGER,\n" + + " FOREIGN KEY(rpt_builder2_t_id) REFERENCES rpt_builder2_t(id)\n" + ");\n" + "\n" + + "-- Insert sample data\n" + "INSERT INTO rpt_builder2_lines_t VALUES\n" + "(1,NULL,'',1),\n" + + "(2,NULL,'[{\\\"std_param_html\\\":[\\\"name\\\",\\\"mark\\\",\\\"mark2\\\"],\\\"adhoc_param_html\\\":[\\\"name\\\",\\\"mark2\\\",\\\"id\\\",\\\"mark\\\",\\\"timestamp\\\"],\\\"date_param_req\\\":false,\\\"url\\\":\\\"http://3.109.61.114:30173/token/access_type/agyana\\\"}]',2),\n" + + "(3,NULL,'',3),\n" + "(4,NULL,'',4);\n" + "" + "DROP TABLE IF EXISTS builder_entity_t;\n" + "\n" + + "CREATE TABLE builder_entity_t (\n" + " id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + + " job_name TEXT,\n" + " job_type TEXT\n" + ");\n" + "" + "PRAGMA foreign_keys=ON;\n" + ""; + return sqlDump; + + } + public String getSql() { String sql = " \n" + "DROP TABLE IF EXISTS `accounts`;\n" diff --git a/backend/src/main/java/com/realnet/DataLake/Controllers/Data_lakeController.java b/backend/src/main/java/com/realnet/DataLake/Controllers/Data_lakeController.java index 8badd64..7ad6d55 100644 --- a/backend/src/main/java/com/realnet/DataLake/Controllers/Data_lakeController.java +++ b/backend/src/main/java/com/realnet/DataLake/Controllers/Data_lakeController.java @@ -26,6 +26,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.realnet.DataLake.Entity.Data_lake; +import com.realnet.DataLake.Services.DataLakeActionService; import com.realnet.DataLake.Services.Data_lakeService; import com.realnet.fnd.response.EntityResponse; @@ -36,6 +37,9 @@ public class Data_lakeController { @Autowired private Data_lakeService Service; + @Autowired + private DataLakeActionService lakeActionService; + @Value("${projectPath}") private String projectPath; @@ -55,6 +59,21 @@ public class Data_lakeController { return update; } + @GetMapping("/Data_lake/webhook/{id}") + public Data_lake enableWebhook(@PathVariable Integer id) { + Data_lake update = Service.enableWebHook(id); + + System.out.println("webhook enabled..." + update); + return update; + } + + @GetMapping("/Data_lake/keys/{lakeid}") + public Map getAllKeys(@PathVariable Integer lakeid) throws JsonProcessingException { + Map update = lakeActionService.getAllKeys(lakeid); + System.out.println("get all keys and header successfully..."); + return update; + } + // get all with pagination @GetMapping("/Data_lake/getall/page") public Page getall(@RequestParam(value = "page", required = false) Integer page, @@ -96,7 +115,7 @@ public class Data_lakeController { @PutMapping("/Data_lake/json/{id}") public Data_lake update(@PathVariable Integer id) throws JsonProcessingException { - Data_lake update = Service.applyCalculation(id); + Data_lake update = lakeActionService.applyCalculation(id); System.out.println("clculation applied..." + update); return update; } @@ -105,7 +124,7 @@ public class Data_lakeController { public ResponseEntity mergeBatchData(@PathVariable Integer id) { try { // Get merged JSON string from service - String mergedJson = Service.mergeBatchData(id); + String mergedJson = lakeActionService.mergeBatchData(id); // Parse the merged JSON string back into JSON structure ObjectMapper mapper = new ObjectMapper(); diff --git a/backend/src/main/java/com/realnet/DataLake/Controllers/tokenFree_Data_lakeController.java b/backend/src/main/java/com/realnet/DataLake/Controllers/tokenFree_Data_lakeController.java index 2522f0d..d8c496a 100644 --- a/backend/src/main/java/com/realnet/DataLake/Controllers/tokenFree_Data_lakeController.java +++ b/backend/src/main/java/com/realnet/DataLake/Controllers/tokenFree_Data_lakeController.java @@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.RestController; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.realnet.DataLake.Entity.Data_lake; +import com.realnet.DataLake.Services.DataLakeActionService; import com.realnet.DataLake.Services.Data_lakeService; import com.realnet.fnd.response.EntityResponse; @@ -35,6 +36,9 @@ public class tokenFree_Data_lakeController { @Autowired private Data_lakeService Service; + @Autowired + private DataLakeActionService lakeActionService; + @Value("${projectPath}") private String projectPath; @@ -95,7 +99,7 @@ public class tokenFree_Data_lakeController { public ResponseEntity mergeBatchData(@PathVariable Integer id) { try { // Get merged JSON string from service - String mergedJson = Service.mergeBatchData(id); + String mergedJson = lakeActionService.mergeBatchData(id); // Parse the merged JSON string back into JSON structure ObjectMapper mapper = new ObjectMapper(); diff --git a/backend/src/main/java/com/realnet/DataLake/Entity/Data_lake.java b/backend/src/main/java/com/realnet/DataLake/Entity/Data_lake.java index 5e8e34e..6e67cfc 100644 --- a/backend/src/main/java/com/realnet/DataLake/Entity/Data_lake.java +++ b/backend/src/main/java/com/realnet/DataLake/Entity/Data_lake.java @@ -31,6 +31,10 @@ public class Data_lake extends Extension { private String cron_job; + private String randomnumber; + + private String webhook_url; + @Lob @Column(columnDefinition = "TEXT") private String json; @@ -44,6 +48,10 @@ public class Data_lake extends Extension { private Integer ref_datalake_id; + private String datalake_type; + + private String blending_lakeids; + @Lob @Column(columnDefinition = "TEXT") private String calculated_field_json; @@ -52,6 +60,14 @@ public class Data_lake extends Extension { @Column(columnDefinition = "TEXT") private String groupby_json; + @Lob + @Column(columnDefinition = "TEXT") + private String sqlquery_json; + + @Lob + @Column(columnDefinition = "TEXT") + private String mapping_json; + private Boolean iscalculatedfield; } diff --git a/backend/src/main/java/com/realnet/DataLake/Services/DataLakeActionService.java b/backend/src/main/java/com/realnet/DataLake/Services/DataLakeActionService.java new file mode 100644 index 0000000..d26a40e --- /dev/null +++ b/backend/src/main/java/com/realnet/DataLake/Services/DataLakeActionService.java @@ -0,0 +1,963 @@ +package com.realnet.DataLake.Services; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import com.realnet.DataLake.Entity.BatchData; +import com.realnet.DataLake.Entity.Data_lake; +import com.realnet.DataLake.Repository.BatchDataRepository; +import com.realnet.DataLake.Repository.Data_lakeRepository; +import com.realnet.SureConnect.Entities.Sure_Connect; +import com.realnet.SureConnect.Service.SureService; +import com.realnet.users.entity1.AppUser; +import com.realnet.users.service1.AppUserServiceImpl; +import com.realnet.utils.Port_Constant; + +@Service +public class DataLakeActionService { + @Autowired + private Data_lakeRepository Repository; + + @Autowired + private BatchDataRepository batchRepo; + @Autowired + private AppUserServiceImpl userService; + + @Autowired + private SureService sureService; + +// sql to json + public Object sqltojson(Integer lakeid) { + Data_lake lake = Repository.findById(lakeid).get(); + String datalake_type = lake.getDatalake_type(); + + Object responseBody = null; // πŸ‘ˆ this is what we’ll return + + if (datalake_type.equalsIgnoreCase("blending") && lake.getBlending_lakeids() != null + && lake.getSqlquery_json() != null) { + + String blending_lakeids = lake.getBlending_lakeids(); // e.g. "12,13" + String sqlquery_json = lake.getSqlquery_json(); // e.g. "select * from gtest, gtest2" + + // Step 1️⃣: Collect all child lakes + String[] lakeIds = blending_lakeids.split(","); + Map lakeDataMap = new HashMap<>(); + ObjectMapper mapper = new ObjectMapper(); + + for (String idStr : lakeIds) { + int id = Integer.parseInt(idStr.trim()); + Data_lake child = Repository.findById(id).orElse(null); + if (child == null) + continue; + + String url = child.getUrl_endpoint(); + +// ResponseEntity response = GETWithString(url, child.getSure_connect_id()); + ResponseEntity response = GETWithObject(url, child.getSure_connect_id()); + + Object body = response.getBody(); + + try { + + String rawBody = mapper.writeValueAsString(body); + JsonNode data = mapper.readTree(rawBody); + // Normalize to array + if (!data.isArray()) { + ArrayNode arr = mapper.createArrayNode(); + arr.add(data); + data = arr; + } + lakeDataMap.put(child.getName().toLowerCase(), data); + System.out.println("Loaded data for: " + child.getName()); + } catch (Exception e) { + System.err.println("Error parsing data from " + child.getName() + ": " + e.getMessage()); + } + } + + // Step 2️⃣: Parse SQL for table names + List tables = extractTableNames(sqlquery_json); + System.out.println("Tables in query: " + tables); + + // Step 3️⃣: Perform JOIN or UNION based on query type + ArrayNode result = mapper.createArrayNode(); + + if (sqlquery_json.toLowerCase().contains("join") || sqlquery_json.toLowerCase().contains("where")) { + // Perform naive JOIN on common field names + result = performJoin(mapper, lakeDataMap, tables); + } else { + // Perform simple UNION of all tables (cross merge) + result = performUnion(mapper, lakeDataMap, tables); + } + + System.out.println("βœ… Final blended JSON:"); + System.out.println(result.toPrettyString()); + // Step 4️⃣: Convert ArrayNode β†’ Object for return + try { + responseBody = mapper.readValue(mapper.writeValueAsString(result), Object.class); + } catch (Exception e) { + throw new RuntimeException("Error converting result to Object: " + e.getMessage()); + } + } + + return responseBody; + + } + + /** Extract table names from SQL query like "select * from gtest, gtest2" */ + private List extractTableNames(String sql) { + List tables = new ArrayList<>(); + String lower = sql.toLowerCase(); + String regex = "from\\s+([a-zA-Z0-9_,\\s]+)"; + Matcher m = Pattern.compile(regex).matcher(lower); + if (m.find()) { + String group = m.group(1); + for (String name : group.split(",")) { + tables.add(name.trim()); + } + } + return tables; + } + + /** Simple union of all tables */ + private ArrayNode performUnion(ObjectMapper mapper, Map lakeDataMap, List tables) { + ArrayNode result = mapper.createArrayNode(); + + for (String table : tables) { + JsonNode data = lakeDataMap.get(table.toLowerCase()); + if (data == null) + continue; + + for (JsonNode row : data) { + ObjectNode newRow = mapper.createObjectNode(); + Iterator fields = row.fieldNames(); + while (fields.hasNext()) { + String field = fields.next(); + newRow.put(table + "." + field, row.get(field).asText()); + } + result.add(newRow); + } + } + return result; + } + + /** Simple JOIN based on common keys */ + private ArrayNode performJoin(ObjectMapper mapper, Map lakeDataMap, List tables) { + ArrayNode result = mapper.createArrayNode(); + if (tables.size() < 2) + return result; + + JsonNode first = lakeDataMap.get(tables.get(0).toLowerCase()); + JsonNode second = lakeDataMap.get(tables.get(1).toLowerCase()); + + if (first == null || second == null) + return result; + + // Find common key (like "id" or "emp_id") + String joinKey = findCommonKey(first, second); + + for (JsonNode row1 : first) { + for (JsonNode row2 : second) { + if (joinKey != null && row1.has(joinKey) && row2.has(joinKey) + && row1.get(joinKey).asText().equals(row2.get(joinKey).asText())) { + + ObjectNode merged = mapper.createObjectNode(); + row1.fieldNames().forEachRemaining(f -> merged.put(tables.get(0) + "." + f, row1.get(f).asText())); + row2.fieldNames().forEachRemaining(f -> merged.put(tables.get(1) + "." + f, row2.get(f).asText())); + result.add(merged); + } + } + } + return result; + } + + /** Finds a likely common join key between two datasets */ + private String findCommonKey(JsonNode a, JsonNode b) { + Set aKeys = new HashSet<>(); + a.get(0).fieldNames().forEachRemaining(aKeys::add); + + Set bKeys = new HashSet<>(); + b.get(0).fieldNames().forEachRemaining(bKeys::add); + + for (String k : aKeys) { + if (bKeys.contains(k)) + return k; + } + return null; + } + +// get all keys of url endpoint + public Map getAllKeys(Integer lakeid) throws JsonProcessingException { + Data_lake old = Repository.findById(lakeid).get(); + String url = old.getUrl_endpoint(); + + ResponseEntity response = GETMethodAsString(url, old.getSure_connect_id()); + + String rawBody = response.getBody(); + + ObjectMapper jsonMapper = new ObjectMapper(); + Object responseBody; + + // Detect and convert if XML + if (isXml(rawBody)) { + try { + XmlMapper xmlMapper = new XmlMapper(); + JsonNode xmlNode = xmlMapper.readTree(rawBody.getBytes()); + String jsonFromXml = jsonMapper.writeValueAsString(xmlNode); + responseBody = jsonMapper.readValue(jsonFromXml, Object.class); + System.out.println("XML detected and converted to JSON successfully."); + } catch (Exception e) { + throw new RuntimeException("Failed to convert XML to JSON: " + e.getMessage()); + } + } else { + try { + responseBody = jsonMapper.readValue(rawBody, Object.class); + System.out.println("JSON response detected."); + } catch (Exception e) { + throw new RuntimeException("Invalid JSON format: " + e.getMessage()); + } + } + + Map result = new HashMap<>(); + extractTableAndHeaders(result, responseBody); + + // Add table name from database + result.put("tableName", old.getName()); + + System.out.println("Keys extracted successfully."); + return result; + } + + public static Map extractTableAndHeaders(Map result, Object responseBody) { + ObjectMapper mapper = new ObjectMapper(); + + try { + JsonNode root = mapper.valueToTree(responseBody); + JsonNode firstNode = root.isArray() && root.size() > 0 ? root.get(0) : root; + + Set headers = new LinkedHashSet<>(); + Iterator fieldNames = firstNode.fieldNames(); + while (fieldNames.hasNext()) { + String field = fieldNames.next(); + if (!field.equalsIgnoreCase("tableName")) { + headers.add(field); + } + } + + result.put("headers", headers); + } catch (Exception e) { + result.put("error", "Invalid JSON: " + e.getMessage()); + } + + return result; + } + +// apply calculated json + public Data_lake applyCalculation(Integer id) throws JsonProcessingException { + + ObjectMapper mapper = new ObjectMapper(); + + Data_lake old = Repository.findById(id).get(); + String datalake_type = old.getDatalake_type(); + if (datalake_type != null && datalake_type.equalsIgnoreCase("blending") && old.getBlending_lakeids() != null + && old.getSqlquery_json() != null) { + + Object sqltojson = sqltojson(id); + + String jsonString = mapper.writeValueAsString(sqltojson); + old.setJson(jsonString); + + // Process and insert into BatchData as before + + // Process and insert into BatchData + processBatchData(old, sqltojson, mapper); + + String Url = Port_Constant.LOCALHOST + ":9292" + "/Data_lake/Data_lake/merge/" + old.getId(); + old.setUrl_endpoint(Url); + + old.setUpdatedBy(getUser().getUserId()); + + final Data_lake saved = Repository.save(old); + return saved; + } + + String url = old.getUrl(); + + ResponseEntity response = GETWithObject(url, old.getSure_connect_id()); + Object data = response.getBody(); + + String rawBody = mapper.writeValueAsString(data); + try { + + List datlakes = Repository.findAllByRefDatlakeId(getUser().getUserId(), id); + if (datlakes != null) { + + datlakes.forEach(lake -> { + try { + Updatejson(lake.getId(), rawBody); + } catch (JsonProcessingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + }); + } + + } catch (Exception e2) { + System.out.println(" exception " + e2); + // TODO: handle exception + } + Data_lake saved = Updatejson(id, rawBody); + + System.out.println(" json updated.."); + return saved; + + } + + public Data_lake Updatejson(Integer id, String rawBody) throws JsonProcessingException { + + Data_lake lake = Repository.findById(id).get(); + +// String url = old.getUrl(); +// +// ResponseEntity response = GETAsString(url); +// String rawBody = response.getBody(); + + // Convert the JSON object (ArrayList, Map, etc.) to a String +// Object responseBody = response.getBody(); + ObjectMapper mapper = new ObjectMapper(); + +// String jsonString = mapper.writeValueAsString(rawBody); + ObjectMapper jsonMapper = new ObjectMapper(); + Object responseBody; + + // Detect and convert if XML + if (isXml(rawBody)) { + try { + // Convert XML β†’ JSON tree + + XmlMapper xmlMapper = new XmlMapper(); + + JsonNode xmlNode = xmlMapper.readTree(rawBody.getBytes()); + // Convert to standard JSON structure + String jsonFromXml = jsonMapper.writeValueAsString(xmlNode); + responseBody = jsonMapper.readValue(jsonFromXml, Object.class); + System.out.println("XML detected and converted to JSON successfully."); + } catch (Exception e) { + throw new RuntimeException("Failed to convert XML to JSON: " + e.getMessage()); + } + } else { + // Normal JSON response + try { + responseBody = jsonMapper.readValue(rawBody, Object.class); + System.out.println("JSON response detected."); + } catch (Exception e) { + throw new RuntimeException("Invalid JSON format: " + e.getMessage()); + } + } + + // Step 2️⃣: Apply mapping if available + String mapping_json = lake.getMapping_json(); + if (mapping_json != null && !mapping_json.trim().isEmpty()) { + try { + Map keyMapping = mapper.readValue(mapping_json, + new TypeReference>() { + }); + responseBody = applyFieldMapping(responseBody, keyMapping); + System.out.println("βœ… Applied header mapping successfully."); + } catch (Exception e) { + throw new RuntimeException("Failed to apply mapping JSON: " + e.getMessage()); + } + } + // βœ… Handle calculated fields before batch processing + if (Boolean.TRUE.equals(lake.getIscalculatedfield()) && lake.getCalculated_field_json() != null) { + try { + responseBody = applyCalculatedFields(responseBody, lake.getCalculated_field_json(), mapper, lake); + System.out.println("Calculated fields applied successfully."); + } catch (Exception e) { + System.err.println("Failed to process calculated fields: " + e.getMessage()); + } + } + + String jsonString = mapper.writeValueAsString(responseBody); + lake.setJson(jsonString); + + // Process and insert into BatchData as before + + // Process and insert into BatchData + processBatchData(lake, responseBody, mapper); + + String Url = Port_Constant.LOCALHOST + ":9292" + "/Data_lake/Data_lake/merge/" + lake.getId(); + lake.setUrl_endpoint(Url); + + lake.setUpdatedBy(getUser().getUserId()); + + final Data_lake saved = Repository.save(lake); + + System.out.println(" json updated.."); + return saved; + + } + + private Object applyFieldMapping(Object input, Map keyMapping) { + ObjectMapper mapper = new ObjectMapper(); + + if (input instanceof List) { + ArrayNode newArray = mapper.createArrayNode(); + for (Object obj : (List) input) { + JsonNode newNode = renameFields(mapper.valueToTree(obj), keyMapping, mapper); + newArray.add(newNode); + } + return newArray; + } else { + return renameFields(mapper.valueToTree(input), keyMapping, mapper); + } + } + + private JsonNode renameFields(JsonNode node, Map keyMapping, ObjectMapper mapper) { + ObjectNode updated = mapper.createObjectNode(); + + node.fieldNames().forEachRemaining(key -> { + JsonNode value = node.get(key); + String newKey = keyMapping.getOrDefault(key, key); + updated.set(newKey, value); + }); + + return updated; + } + + @SuppressWarnings("unchecked") + private Object applyCalculatedFields(Object responseBody, String calculatedFieldJson, ObjectMapper mapper, + Data_lake old) throws JsonProcessingException { + + // Parse the calculated field JSON + List> calcFields = mapper.readValue(calculatedFieldJson, List.class); + +// if (!(responseBody instanceof List)) { +// responseBody = Arrays.asList(responseBody); +// } + + // βœ… Case 1: Already a Java List + if (responseBody instanceof List) { + // Do nothing + } + + // βœ… Case 2: Jackson ArrayNode (convert to List) + else if (responseBody instanceof com.fasterxml.jackson.databind.node.ArrayNode) { + responseBody = mapper.convertValue(responseBody, List.class); + } + + // βœ… Case 3: Jackson ObjectNode (convert to single object inside list) + else if (responseBody instanceof com.fasterxml.jackson.databind.node.ObjectNode) { + Map obj = mapper.convertValue(responseBody, Map.class); + responseBody = Collections.singletonList(obj); + } + + // βœ… Case 4: JSON String input + else if (responseBody instanceof String) { + String json = ((String) responseBody).trim(); + if (json.startsWith("[")) { + responseBody = mapper.readValue(json, List.class); + } else if (json.startsWith("{")) { + Map singleObject = mapper.readValue(json, Map.class); + responseBody = Collections.singletonList(singleObject); + } else { + throw new IllegalArgumentException("Invalid JSON format: " + json); + } + } + + // βœ… Case 5: Single map + else if (responseBody instanceof Map) { + responseBody = Collections.singletonList(responseBody); + } + + // ❌ Anything else β€” throw error + else { + throw new IllegalArgumentException("Unexpected response body type: " + responseBody.getClass()); + } + List> records = (List>) responseBody; + + for (Map calc : calcFields) { + String type = (String) calc.get("type"); + if ("groupby".equalsIgnoreCase(type)) { + // βœ… Handle group-by aggregation + List> groupbyrecords = applyGroupBy(records, calc); + String groupByRecord = mapper.writeValueAsString(groupbyrecords); + + old.setGroupby_json(groupByRecord); + + } else { + // βœ… Handle calculated / complex operations (as before) + for (Map record : records) { + String fieldName = (String) calc.get("fieldName"); + String operation = (String) calc.get("operation"); + List> components = (List>) calc.get("fieldComponents"); + + // Handle constant fields + if (components != null) { + for (Map comp : components) { + String subField = (String) comp.get("field"); + Boolean isConstant = comp.get("isConstant") != null && (Boolean) comp.get("isConstant"); + Object constantValue = comp.get("constant"); + if (isConstant && subField != null) { + record.put(subField, parseNumberOrString(constantValue)); + } + } + } + + // Handle complex expression + if ("complex".equalsIgnoreCase(operation) && calc.get("complexEquation") != null) { + String equation = (String) calc.get("complexEquation"); + Object result = evaluateComplexExpression(equation, record); + record.put(fieldName, result); + continue; + } + + // Handle normal arithmetic + List values = new ArrayList<>(); + if (components != null) { + for (Map comp : components) { + Boolean isConstant = comp.get("isConstant") != null && (Boolean) comp.get("isConstant"); + Object val = isConstant ? comp.get("constant") : record.get(comp.get("field")); + if (val != null) { + values.add(val); + } + } + } + + Object result = performOperation(values, operation); + record.put(fieldName, result); + } + } + } + + return records; + } + + @SuppressWarnings("unchecked") + private List> applyGroupBy(List> records, Map groupConfig) { + List groupFields = (List) groupConfig.get("groupFields"); + List> aggregations = (List>) groupConfig.get("aggregations"); + + // Group records by key + Map>> grouped = new LinkedHashMap<>(); + for (Map record : records) { + String key = groupFields.stream().map(f -> String.valueOf(record.getOrDefault(f, ""))) + .collect(Collectors.joining("|")); + grouped.computeIfAbsent(key, k -> new ArrayList<>()).add(record); + } + + // Aggregate results per group + List> result = new ArrayList<>(); + + for (Map.Entry>> entry : grouped.entrySet()) { + Map groupRecord = new LinkedHashMap<>(); + + // Add group fields + String[] parts = entry.getKey().split("\\|"); + for (int i = 0; i < groupFields.size(); i++) { + groupRecord.put(groupFields.get(i), parts[i]); + } + + List> groupRows = entry.getValue(); + + // Apply each aggregation + for (Map agg : aggregations) { + String field = (String) agg.get("field"); + String operation = ((String) agg.get("operation")).toLowerCase(); + List numericValues = groupRows.stream().map(r -> toDouble(r.get(field))) + .filter(v -> !Double.isNaN(v)).collect(Collectors.toList()); + + Object aggResult; + switch (operation) { + case "count": + aggResult = groupRows.size(); + break; + case "sum": + aggResult = numericValues.stream().mapToDouble(Double::doubleValue).sum(); + break; + case "average": + aggResult = numericValues.isEmpty() ? 0.0 + : numericValues.stream().mapToDouble(Double::doubleValue).average().orElse(0.0); + break; + case "minimum": + aggResult = numericValues.isEmpty() ? null + : numericValues.stream().mapToDouble(Double::doubleValue).min().orElse(0.0); + break; + case "maximum": + aggResult = numericValues.isEmpty() ? null + : numericValues.stream().mapToDouble(Double::doubleValue).max().orElse(0.0); + break; + case "median": + aggResult = calculateMedian(numericValues); + break; + case "mode": + aggResult = calculateMode(numericValues); + break; + case "standard deviation": + aggResult = calculateStdDev(numericValues); + break; + default: + aggResult = null; + } + + groupRecord.put(field + "_" + operation, aggResult); + } + + result.add(groupRecord); + } + + return result; + } + + // --- Statistical helpers --- + + private Double calculateMedian(List values) { + if (values == null || values.isEmpty()) + return null; + List sorted = new ArrayList<>(values); + Collections.sort(sorted); + int n = sorted.size(); + if (n % 2 == 1) { + return sorted.get(n / 2); + } else { + return (sorted.get(n / 2 - 1) + sorted.get(n / 2)) / 2.0; + } + } + + private Double calculateMode(List values) { + if (values == null || values.isEmpty()) + return null; + Map freq = values.stream().collect(Collectors.groupingBy(v -> v, Collectors.counting())); + return freq.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey).orElse(null); + } + + private Double calculateStdDev(List values) { + if (values == null || values.isEmpty()) + return null; + double mean = values.stream().mapToDouble(Double::doubleValue).average().orElse(0.0); + double variance = values.stream().mapToDouble(v -> Math.pow(v - mean, 2)).average().orElse(0.0); + return Math.sqrt(variance); + } + + private Object evaluateComplexExpression(String expression, Map record) { + try { + // Replace field names with values dynamically + for (Map.Entry e : record.entrySet()) { + String field = e.getKey(); + Object val = e.getValue(); + expression = expression.replaceAll("\\b" + field + "\\b", String.valueOf(val != null ? val : 0)); + } + + // Evaluate using ScriptEngine (works on Java 1.8) + javax.script.ScriptEngine engine = new javax.script.ScriptEngineManager().getEngineByName("JavaScript"); + Object result = engine.eval(expression); + return result; + } catch (Exception e) { + System.err.println("Complex expression error: " + e.getMessage()); + return null; + } + } + +// perform normal operation + private Object performOperation(List values, String operation) { + if (values.isEmpty()) + return null; + + switch (operation.toLowerCase()) { + case "add": + double sum = 0; + for (Object v : values) + sum += toDouble(v); + return sum; + + case "subtract": + double result = toDouble(values.get(0)); + for (int i = 1; i < values.size(); i++) + result -= toDouble(values.get(i)); + return result; + + case "multiply": + double prod = 1; + for (Object v : values) + prod *= toDouble(v); + return prod; + + case "divide": + double div = toDouble(values.get(0)); + for (int i = 1; i < values.size(); i++) { + double val = toDouble(values.get(i)); + if (val != 0) + div /= val; + } + return div; + + case "percentage": + if (values.size() < 2) + return null; + double num = toDouble(values.get(0)); + double den = toDouble(values.get(1)); + return den == 0 ? null : (num / den) * 100; + + case "concat": + return values.stream().map(Object::toString).collect(Collectors.joining("_")); + + default: + return null; + } + } + + /** + * βœ… Evaluates complex equations using JavaScript engine Supports math + * operations, parentheses, and string concatenation. + */ + private Object evaluateComplexEquation(String expression, Map record, + List> fieldComponents) { + + if (expression == null || expression.trim().isEmpty()) + return null; + + ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); + + try { + // πŸ”Ή Replace constants + if (fieldComponents != null) { + for (Map comp : fieldComponents) { + String field = (String) comp.get("field"); + Object constant = comp.get("constant"); + Boolean isConstant = comp.get("isConstant") != null && (Boolean) comp.get("isConstant"); + + if (isConstant && constant != null) { + String constVal = constant.toString(); + expression = expression.replaceAll("\\b" + field + "\\b", constVal); + } + } + } + + // πŸ”Ή Replace field values from record + for (Map.Entry entry : record.entrySet()) { + String key = entry.getKey(); + Object val = entry.getValue(); + if (val != null) { + String safeValue = val.toString(); + + // If it's a string containing letters, wrap it in quotes for JS + if (!safeValue.matches("^-?\\d+(\\.\\d+)?$")) { + safeValue = "'" + safeValue.replace("'", "\\'") + "'"; + } + + expression = expression.replaceAll("\\b" + key + "\\b", safeValue); + } + } + + // Evaluate the expression safely + Object result = engine.eval(expression); + System.out.println(" exoression is : " + expression + " and " + result); + return result; + + } catch (Exception e) { + System.err.println("❌ Error evaluating complex equation: " + e.getMessage()); + return null; + } + } + + private double toDouble(Object val) { + if (val == null) + return 0.0; + try { + return Double.parseDouble(val.toString().trim()); + } catch (NumberFormatException e) { + return 0.0; + } + } + + private Object parseNumberOrString(Object val) { + if (val == null) + return null; + String str = val.toString().trim(); + try { + return Double.parseDouble(str); + } catch (NumberFormatException e) { + return str; + } + } + + private boolean isXml(String content) { + if (content == null) + return false; + String trimmed = content.trim(); + // XML usually starts with '<' and ends with '>' + return trimmed.startsWith("<") && trimmed.endsWith(">"); + } + + private void processBatchData(Data_lake dataLake, Object responseBody, ObjectMapper mapper) + throws JsonProcessingException { + + int batchVolume = (dataLake.getBatch_volume() != null && dataLake.getBatch_volume() > 0) + ? dataLake.getBatch_volume() + : 100; // default batch size if not given + + // Convert to JsonNode + JsonNode jsonNode = mapper.valueToTree(responseBody); + + if (jsonNode.isArray()) { + ArrayNode arrayNode = (ArrayNode) jsonNode; + int total = arrayNode.size(); + System.out.println("Total records: " + total); + + for (int i = 0; i < total; i += batchVolume) { + int end = Math.min(i + batchVolume, total); + + // Create a sub-array manually + ArrayNode subArray = mapper.createArrayNode(); + for (int j = i; j < end; j++) { + subArray.add(arrayNode.get(j)); + } + + String subJson = mapper.writeValueAsString(subArray); + + BatchData batch = new BatchData(); + batch.setDatalake_id(dataLake.getId()); + batch.setBatchjson(subJson); + batchRepo.save(batch); + } + + System.out.println("Inserted " + (int) Math.ceil((double) total / batchVolume) + " batch records."); + + } else { + // Single object β†’ one record + BatchData batch = new BatchData(); + batch.setDatalake_id(dataLake.getId()); + batch.setBatchjson(mapper.writeValueAsString(jsonNode)); + batchRepo.save(batch); + + System.out.println("Inserted single batch record."); + } + } + + public String mergeBatchData(Integer datalakeId) throws Exception { + List batchList = batchRepo.findByDatalake_id(datalakeId); + + if (batchList.isEmpty()) { + throw new RuntimeException("No batch data found for datalake_id: " + datalakeId); + } + + ObjectMapper mapper = new ObjectMapper(); + ArrayNode mergedArray = mapper.createArrayNode(); + + for (BatchData batch : batchList) { + String json = batch.getBatchjson(); + JsonNode node = mapper.readTree(json); + + if (node.isArray()) { + // Add each element to merged array + for (JsonNode item : node) { + mergedArray.add(item); + } + } else { + // Single object, just add directly + mergedArray.add(node); + } + } + + String mergedJson = mapper.writeValueAsString(mergedArray); + System.out.println("Merged JSON size: " + mergedArray.size()); + return mergedJson; + } + + public ResponseEntity GET(String get) { + RestTemplate restTemplate = new RestTemplate(); + + ResponseEntity u = restTemplate.getForEntity(get, Object.class); + + return u; + + } + + public ResponseEntity GETAsString1(String url) { + RestTemplate restTemplate = new RestTemplate(); + return restTemplate.getForEntity(url, String.class); + } + + public AppUser getUser() { + AppUser user = userService.getLoggedInUser(); + return user; + + } + + public ResponseEntity GETMethodAsString(String url, Integer sureid) { + RestTemplate restTemplate = new RestTemplate(); + + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.ALL)); // accept JSON or XML + headers.setContentType(MediaType.APPLICATION_JSON); + + // πŸ”Ή Add your token here (you can make it dynamic) + String token = getToken(sureid); // helper method (see below) + if (token != null && !token.isEmpty()) { + headers.set("Authorization", "Bearer " + token); + } + + HttpEntity entity = new HttpEntity<>(headers); + + ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class); + + return response; + } + + public ResponseEntity GETWithObject(String url, Integer sureid) { + RestTemplate restTemplate = new RestTemplate(); + + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.ALL)); // accept JSON or XML + headers.setContentType(MediaType.APPLICATION_JSON); + + // πŸ”Ή Add your token here (you can make it dynamic) + String token = getToken(sureid); // helper method (see below) + if (token != null && !token.isEmpty()) { + headers.set("Authorization", "Bearer " + token); + } + + HttpEntity entity = new HttpEntity<>(headers); + + ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, entity, Object.class); + + return response; + } + + private String getToken(Integer sureid) { + Sure_Connect connect = sureService.getbyid(sureid); + String access_token = connect.getAccess_token(); + + return access_token; // optional + } + +} diff --git a/backend/src/main/java/com/realnet/DataLake/Services/Data_lakeService.java b/backend/src/main/java/com/realnet/DataLake/Services/Data_lakeService.java index b60cd49..4acbf2c 100644 --- a/backend/src/main/java/com/realnet/DataLake/Services/Data_lakeService.java +++ b/backend/src/main/java/com/realnet/DataLake/Services/Data_lakeService.java @@ -1,35 +1,16 @@ package com.realnet.DataLake.Services; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; -import org.springframework.web.client.RestTemplate; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.dataformat.xml.XmlMapper; -import com.realnet.DataLake.Entity.BatchData; import com.realnet.DataLake.Entity.Data_lake; import com.realnet.DataLake.Repository.BatchDataRepository; import com.realnet.DataLake.Repository.Data_lakeRepository; import com.realnet.SureConnect.Service.SureService; -import com.realnet.realm.Entity.Realm; -import com.realnet.realm.Services.RealmService; import com.realnet.users.entity1.AppUser; import com.realnet.users.service1.AppUserServiceImpl; import com.realnet.utils.Port_Constant; @@ -43,9 +24,9 @@ public class Data_lakeService { private BatchDataRepository batchRepo; @Autowired private AppUserServiceImpl userService; - @Autowired - private RealmService realmService; + @Autowired + private DataLakeActionService lakeActionService; @Autowired private SureService sureService; @@ -70,7 +51,6 @@ public class Data_lakeService { } public List getdetails() { - List realm = realmService.findByUserId(getUser().getUserId()); List all = Repository.findAll(getUser().getUserId()); return all; @@ -84,6 +64,16 @@ public class Data_lakeService { Repository.deleteById(id); } + public Data_lake enableWebHook(Integer id) { + Data_lake old = Repository.findById(id).get(); + String Url = Port_Constant.LOCALHOST + ":9292" + "/Data_lake/Data_lake/json/" + id; + old.setWebhook_url(Url); + final Data_lake test = Repository.save(old); + + return test; + + } + public Data_lake update(Data_lake data, Integer id) { Data_lake old = Repository.findById(id).get(); // id auto-generated hai β†’ update nahi karenge @@ -141,524 +131,813 @@ public class Data_lakeService { } + if (data.getDatalake_type() != null) { + old.setDatalake_type(data.getDatalake_type()); + + } + + if (data.getBlending_lakeids() != null) { + old.setBlending_lakeids(data.getBlending_lakeids()); + + } + if (data.getSqlquery_json() != null) { + + old.setSqlquery_json(data.getSqlquery_json()); + + } + if (data.getMapping_json() != null) { + old.setMapping_json(data.getMapping_json()); + } + final Data_lake test = Repository.save(old); return test; } - public Data_lake applyCalculation(Integer id) throws JsonProcessingException { - - Data_lake old = Repository.findById(id).get(); - - String url = old.getUrl(); - - ResponseEntity response = GETAsString(url); - String rawBody = response.getBody(); - - List datlakes = Repository.findAllByRefDatlakeId(getUser().getUserId(), id); - - datlakes.forEach(lake -> { - try { - Updatejson(lake.getId(), rawBody); - } catch (JsonProcessingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - }); - - Data_lake saved = Updatejson(id, rawBody); - - System.out.println(" json updated.."); - return saved; - - } - - public Data_lake Updatejson(Integer id, String rawBody) throws JsonProcessingException { - - Data_lake old = Repository.findById(id).get(); +// public Object sqltojson(Integer lakeid) { +// Data_lake lake = Repository.findById(lakeid).get(); +// String datalake_type = lake.getDatalake_type(); +// +// Object responseBody = null; // πŸ‘ˆ this is what we’ll return +// +// if (datalake_type.equalsIgnoreCase("blending") && lake.getBlending_lakeids() != null +// && lake.getSqlquery_json() != null) { +// +// String blending_lakeids = lake.getBlending_lakeids(); // e.g. "12,13" +// String sqlquery_json = lake.getSqlquery_json(); // e.g. "select * from gtest, gtest2" +// +// // Step 1️⃣: Collect all child lakes +// String[] lakeIds = blending_lakeids.split(","); +// Map lakeDataMap = new HashMap<>(); +// ObjectMapper mapper = new ObjectMapper(); +// +// for (String idStr : lakeIds) { +// int id = Integer.parseInt(idStr.trim()); +// Data_lake child = Repository.findById(id).orElse(null); +// if (child == null) +// continue; +// +// String url = child.getUrl_endpoint(); +// ResponseEntity response = GETWithString(url, child.getSure_connect_id()); +// String rawBody = response.getBody(); +// +// try { +// JsonNode data = mapper.readTree(rawBody); +// // Normalize to array +// if (!data.isArray()) { +// ArrayNode arr = mapper.createArrayNode(); +// arr.add(data); +// data = arr; +// } +// lakeDataMap.put(child.getName().toLowerCase(), data); +// System.out.println("Loaded data for: " + child.getName()); +// } catch (Exception e) { +// System.err.println("Error parsing data from " + child.getName() + ": " + e.getMessage()); +// } +// } +// +// // Step 2️⃣: Parse SQL for table names +// List tables = extractTableNames(sqlquery_json); +// System.out.println("Tables in query: " + tables); +// +// // Step 3️⃣: Perform JOIN or UNION based on query type +// ArrayNode result = mapper.createArrayNode(); +// +// if (sqlquery_json.toLowerCase().contains("join") || sqlquery_json.toLowerCase().contains("where")) { +// // Perform naive JOIN on common field names +// result = performJoin(mapper, lakeDataMap, tables); +// } else { +// // Perform simple UNION of all tables (cross merge) +// result = performUnion(mapper, lakeDataMap, tables); +// } +// +// System.out.println("βœ… Final blended JSON:"); +// System.out.println(result.toPrettyString()); +// // Step 4️⃣: Convert ArrayNode β†’ Object for return +// try { +// responseBody = mapper.readValue(mapper.writeValueAsString(result), Object.class); +// } catch (Exception e) { +// throw new RuntimeException("Error converting result to Object: " + e.getMessage()); +// } +// } +// +// return responseBody; +// +// } +// +// /** Extract table names from SQL query like "select * from gtest, gtest2" */ +// private List extractTableNames(String sql) { +// List tables = new ArrayList<>(); +// String lower = sql.toLowerCase(); +// String regex = "from\\s+([a-zA-Z0-9_,\\s]+)"; +// Matcher m = Pattern.compile(regex).matcher(lower); +// if (m.find()) { +// String group = m.group(1); +// for (String name : group.split(",")) { +// tables.add(name.trim()); +// } +// } +// return tables; +// } +// +// /** Simple union of all tables */ +// private ArrayNode performUnion(ObjectMapper mapper, Map lakeDataMap, List tables) { +// ArrayNode result = mapper.createArrayNode(); +// +// for (String table : tables) { +// JsonNode data = lakeDataMap.get(table.toLowerCase()); +// if (data == null) +// continue; +// +// for (JsonNode row : data) { +// ObjectNode newRow = mapper.createObjectNode(); +// Iterator fields = row.fieldNames(); +// while (fields.hasNext()) { +// String field = fields.next(); +// newRow.put(table + "." + field, row.get(field).asText()); +// } +// result.add(newRow); +// } +// } +// return result; +// } +// +// /** Simple JOIN based on common keys */ +// private ArrayNode performJoin(ObjectMapper mapper, Map lakeDataMap, List tables) { +// ArrayNode result = mapper.createArrayNode(); +// if (tables.size() < 2) +// return result; +// +// JsonNode first = lakeDataMap.get(tables.get(0).toLowerCase()); +// JsonNode second = lakeDataMap.get(tables.get(1).toLowerCase()); +// +// if (first == null || second == null) +// return result; +// +// // Find common key (like "id" or "emp_id") +// String joinKey = findCommonKey(first, second); +// +// for (JsonNode row1 : first) { +// for (JsonNode row2 : second) { +// if (joinKey != null && row1.has(joinKey) && row2.has(joinKey) +// && row1.get(joinKey).asText().equals(row2.get(joinKey).asText())) { +// +// ObjectNode merged = mapper.createObjectNode(); +// row1.fieldNames().forEachRemaining(f -> merged.put(tables.get(0) + "." + f, row1.get(f).asText())); +// row2.fieldNames().forEachRemaining(f -> merged.put(tables.get(1) + "." + f, row2.get(f).asText())); +// result.add(merged); +// } +// } +// } +// return result; +// } +// +// /** Finds a likely common join key between two datasets */ +// private String findCommonKey(JsonNode a, JsonNode b) { +// Set aKeys = new HashSet<>(); +// a.get(0).fieldNames().forEachRemaining(aKeys::add); +// +// Set bKeys = new HashSet<>(); +// b.get(0).fieldNames().forEachRemaining(bKeys::add); +// +// for (String k : aKeys) { +// if (bKeys.contains(k)) +// return k; +// } +// return null; +// } +// public Map getAllKeys(Integer lakeid) throws JsonProcessingException { +// Data_lake old = Repository.findById(lakeid).get(); +// String url = old.getUrl_endpoint(); +// +// ResponseEntity response = GETWithString(url, old.getSure_connect_id()); +// +// String rawBody = response.getBody(); +// +// ObjectMapper jsonMapper = new ObjectMapper(); +// Object responseBody; +// +// // Detect and convert if XML +// if (isXml(rawBody)) { +// try { +// XmlMapper xmlMapper = new XmlMapper(); +// JsonNode xmlNode = xmlMapper.readTree(rawBody.getBytes()); +// String jsonFromXml = jsonMapper.writeValueAsString(xmlNode); +// responseBody = jsonMapper.readValue(jsonFromXml, Object.class); +// System.out.println("XML detected and converted to JSON successfully."); +// } catch (Exception e) { +// throw new RuntimeException("Failed to convert XML to JSON: " + e.getMessage()); +// } +// } else { +// try { +// responseBody = jsonMapper.readValue(rawBody, Object.class); +// System.out.println("JSON response detected."); +// } catch (Exception e) { +// throw new RuntimeException("Invalid JSON format: " + e.getMessage()); +// } +// } +// +// Map result = new HashMap<>(); +// extractTableAndHeaders(result, responseBody); +// +// // Add table name from database +// result.put("tableName", old.getName()); +// +// System.out.println("Keys extracted successfully."); +// return result; +// } +// +// public static Map extractTableAndHeaders(Map result, Object responseBody) { +// ObjectMapper mapper = new ObjectMapper(); +// +// try { +// JsonNode root = mapper.valueToTree(responseBody); +// JsonNode firstNode = root.isArray() && root.size() > 0 ? root.get(0) : root; +// +// Set headers = new LinkedHashSet<>(); +// Iterator fieldNames = firstNode.fieldNames(); +// while (fieldNames.hasNext()) { +// String field = fieldNames.next(); +// if (!field.equalsIgnoreCase("tableName")) { +// headers.add(field); +// } +// } +// +// result.put("headers", headers); +// } catch (Exception e) { +// result.put("error", "Invalid JSON: " + e.getMessage()); +// } +// +// return result; +// } +// +//// apply calculated json +// public Data_lake applyCalculation(Integer id) throws JsonProcessingException { +// +// ObjectMapper mapper = new ObjectMapper(); +// +// Data_lake old = Repository.findById(id).get(); +// String datalake_type = old.getDatalake_type(); +// if (datalake_type.equalsIgnoreCase("blending") && old.getBlending_lakeids() != null +// && old.getSqlquery_json() != null) { +// +// Object sqltojson = lakeActionService.sqltojson(id); +// +// String jsonString = mapper.writeValueAsString(sqltojson); +// old.setJson(jsonString); +// +// // Process and insert into BatchData as before +// +// // Process and insert into BatchData +// processBatchData(old, sqltojson, mapper); +// +// String Url = Port_Constant.LOCALHOST + ":9292" + "/Data_lake/Data_lake/merge/" + old.getId(); +// old.setUrl_endpoint(Url); +// +// old.setUpdatedBy(getUser().getUserId()); +// +// final Data_lake saved = Repository.save(old); +// return saved; +// } +// // String url = old.getUrl(); // // ResponseEntity response = GETAsString(url); // String rawBody = response.getBody(); - - // Convert the JSON object (ArrayList, Map, etc.) to a String -// Object responseBody = response.getBody(); - ObjectMapper mapper = new ObjectMapper(); - -// String jsonString = mapper.writeValueAsString(rawBody); - ObjectMapper jsonMapper = new ObjectMapper(); - Object responseBody; - - // Detect and convert if XML - if (isXml(rawBody)) { - try { - // Convert XML β†’ JSON tree - - XmlMapper xmlMapper = new XmlMapper(); - - JsonNode xmlNode = xmlMapper.readTree(rawBody.getBytes()); - // Convert to standard JSON structure - String jsonFromXml = jsonMapper.writeValueAsString(xmlNode); - responseBody = jsonMapper.readValue(jsonFromXml, Object.class); - System.out.println("XML detected and converted to JSON successfully."); - } catch (Exception e) { - throw new RuntimeException("Failed to convert XML to JSON: " + e.getMessage()); - } - } else { - // Normal JSON response - try { - responseBody = jsonMapper.readValue(rawBody, Object.class); - System.out.println("JSON response detected."); - } catch (Exception e) { - throw new RuntimeException("Invalid JSON format: " + e.getMessage()); - } - } - - // βœ… Handle calculated fields before batch processing - if (Boolean.TRUE.equals(old.getIscalculatedfield()) && old.getCalculated_field_json() != null) { - try { - responseBody = applyCalculatedFields(responseBody, old.getCalculated_field_json(), mapper, old); - System.out.println("Calculated fields applied successfully."); - } catch (Exception e) { - System.err.println("Failed to process calculated fields: " + e.getMessage()); - } - } - - String jsonString = mapper.writeValueAsString(responseBody); - old.setJson(jsonString); - - // Process and insert into BatchData as before - - // Process and insert into BatchData - processBatchData(old, responseBody, mapper); - - String Url = Port_Constant.DOMAIN + "/Data_lake/Data_lake/merge/" + old.getId(); - old.setUrl_endpoint(Url); - - old.setUpdatedBy(getUser().getUserId()); - - final Data_lake saved = Repository.save(old); - - System.out.println(" json updated.."); - return saved; - - } - - @SuppressWarnings("unchecked") - private Object applyCalculatedFields(Object responseBody, String calculatedFieldJson, ObjectMapper mapper, - Data_lake old) throws JsonProcessingException { - - // Parse the calculated field JSON - List> calcFields = mapper.readValue(calculatedFieldJson, List.class); - - if (!(responseBody instanceof List)) { - responseBody = Arrays.asList(responseBody); - } - - List> records = (List>) responseBody; - - for (Map calc : calcFields) { - String type = (String) calc.get("type"); - if ("groupby".equalsIgnoreCase(type)) { - // βœ… Handle group-by aggregation - List> groupbyrecords = applyGroupBy(records, calc); - String groupByRecord = mapper.writeValueAsString(groupbyrecords); - - old.setGroupby_json(groupByRecord); - - } else { - // βœ… Handle calculated / complex operations (as before) - for (Map record : records) { - String fieldName = (String) calc.get("fieldName"); - String operation = (String) calc.get("operation"); - List> components = (List>) calc.get("fieldComponents"); - - // Handle constant fields - if (components != null) { - for (Map comp : components) { - String subField = (String) comp.get("field"); - Boolean isConstant = comp.get("isConstant") != null && (Boolean) comp.get("isConstant"); - Object constantValue = comp.get("constant"); - if (isConstant && subField != null) { - record.put(subField, parseNumberOrString(constantValue)); - } - } - } - - // Handle complex expression - if ("complex".equalsIgnoreCase(operation) && calc.get("complexEquation") != null) { - String equation = (String) calc.get("complexEquation"); - Object result = evaluateComplexExpression(equation, record); - record.put(fieldName, result); - continue; - } - - // Handle normal arithmetic - List values = new ArrayList<>(); - if (components != null) { - for (Map comp : components) { - Boolean isConstant = comp.get("isConstant") != null && (Boolean) comp.get("isConstant"); - Object val = isConstant ? comp.get("constant") : record.get(comp.get("field")); - if (val != null) { - values.add(val); - } - } - } - - Object result = performOperation(values, operation); - record.put(fieldName, result); - } - } - } - - return records; - } - - @SuppressWarnings("unchecked") - private List> applyGroupBy(List> records, Map groupConfig) { - List groupFields = (List) groupConfig.get("groupFields"); - List> aggregations = (List>) groupConfig.get("aggregations"); - - // Group records by key - Map>> grouped = new LinkedHashMap<>(); - for (Map record : records) { - String key = groupFields.stream().map(f -> String.valueOf(record.getOrDefault(f, ""))) - .collect(Collectors.joining("|")); - grouped.computeIfAbsent(key, k -> new ArrayList<>()).add(record); - } - - // Aggregate results per group - List> result = new ArrayList<>(); - - for (Map.Entry>> entry : grouped.entrySet()) { - Map groupRecord = new LinkedHashMap<>(); - - // Add group fields - String[] parts = entry.getKey().split("\\|"); - for (int i = 0; i < groupFields.size(); i++) { - groupRecord.put(groupFields.get(i), parts[i]); - } - - List> groupRows = entry.getValue(); - - // Apply each aggregation - for (Map agg : aggregations) { - String field = (String) agg.get("field"); - String operation = ((String) agg.get("operation")).toLowerCase(); - List numericValues = groupRows.stream().map(r -> toDouble(r.get(field))) - .filter(v -> !Double.isNaN(v)).collect(Collectors.toList()); - - Object aggResult; - switch (operation) { - case "count": - aggResult = groupRows.size(); - break; - case "sum": - aggResult = numericValues.stream().mapToDouble(Double::doubleValue).sum(); - break; - case "average": - aggResult = numericValues.isEmpty() ? 0.0 - : numericValues.stream().mapToDouble(Double::doubleValue).average().orElse(0.0); - break; - case "minimum": - aggResult = numericValues.isEmpty() ? null - : numericValues.stream().mapToDouble(Double::doubleValue).min().orElse(0.0); - break; - case "maximum": - aggResult = numericValues.isEmpty() ? null - : numericValues.stream().mapToDouble(Double::doubleValue).max().orElse(0.0); - break; - case "median": - aggResult = calculateMedian(numericValues); - break; - case "mode": - aggResult = calculateMode(numericValues); - break; - case "standard deviation": - aggResult = calculateStdDev(numericValues); - break; - default: - aggResult = null; - } - - groupRecord.put(field + "_" + operation, aggResult); - } - - result.add(groupRecord); - } - - return result; - } - - // --- Statistical helpers --- - - private Double calculateMedian(List values) { - if (values == null || values.isEmpty()) - return null; - List sorted = new ArrayList<>(values); - Collections.sort(sorted); - int n = sorted.size(); - if (n % 2 == 1) { - return sorted.get(n / 2); - } else { - return (sorted.get(n / 2 - 1) + sorted.get(n / 2)) / 2.0; - } - } - - private Double calculateMode(List values) { - if (values == null || values.isEmpty()) - return null; - Map freq = values.stream().collect(Collectors.groupingBy(v -> v, Collectors.counting())); - return freq.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey).orElse(null); - } - - private Double calculateStdDev(List values) { - if (values == null || values.isEmpty()) - return null; - double mean = values.stream().mapToDouble(Double::doubleValue).average().orElse(0.0); - double variance = values.stream().mapToDouble(v -> Math.pow(v - mean, 2)).average().orElse(0.0); - return Math.sqrt(variance); - } - - private Object evaluateComplexExpression(String expression, Map record) { - try { - // Replace field names with values dynamically - for (Map.Entry e : record.entrySet()) { - String field = e.getKey(); - Object val = e.getValue(); - expression = expression.replaceAll("\\b" + field + "\\b", String.valueOf(val != null ? val : 0)); - } - - // Evaluate using ScriptEngine (works on Java 1.8) - javax.script.ScriptEngine engine = new javax.script.ScriptEngineManager().getEngineByName("JavaScript"); - Object result = engine.eval(expression); - return result; - } catch (Exception e) { - System.err.println("Complex expression error: " + e.getMessage()); - return null; - } - } - -// perform normal operation - private Object performOperation(List values, String operation) { - if (values.isEmpty()) - return null; - - switch (operation.toLowerCase()) { - case "add": - double sum = 0; - for (Object v : values) - sum += toDouble(v); - return sum; - - case "subtract": - double result = toDouble(values.get(0)); - for (int i = 1; i < values.size(); i++) - result -= toDouble(values.get(i)); - return result; - - case "multiply": - double prod = 1; - for (Object v : values) - prod *= toDouble(v); - return prod; - - case "divide": - double div = toDouble(values.get(0)); - for (int i = 1; i < values.size(); i++) { - double val = toDouble(values.get(i)); - if (val != 0) - div /= val; - } - return div; - - case "percentage": - if (values.size() < 2) - return null; - double num = toDouble(values.get(0)); - double den = toDouble(values.get(1)); - return den == 0 ? null : (num / den) * 100; - - case "concat": - return values.stream().map(Object::toString).collect(Collectors.joining("_")); - - default: - return null; - } - } - - /** - * βœ… Evaluates complex equations using JavaScript engine Supports math - * operations, parentheses, and string concatenation. - */ - private Object evaluateComplexEquation(String expression, Map record, - List> fieldComponents) { - - if (expression == null || expression.trim().isEmpty()) - return null; - - ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); - - try { - // πŸ”Ή Replace constants - if (fieldComponents != null) { - for (Map comp : fieldComponents) { - String field = (String) comp.get("field"); - Object constant = comp.get("constant"); - Boolean isConstant = comp.get("isConstant") != null && (Boolean) comp.get("isConstant"); - - if (isConstant && constant != null) { - String constVal = constant.toString(); - expression = expression.replaceAll("\\b" + field + "\\b", constVal); - } - } - } - - // πŸ”Ή Replace field values from record - for (Map.Entry entry : record.entrySet()) { - String key = entry.getKey(); - Object val = entry.getValue(); - if (val != null) { - String safeValue = val.toString(); - - // If it's a string containing letters, wrap it in quotes for JS - if (!safeValue.matches("^-?\\d+(\\.\\d+)?$")) { - safeValue = "'" + safeValue.replace("'", "\\'") + "'"; - } - - expression = expression.replaceAll("\\b" + key + "\\b", safeValue); - } - } - - // Evaluate the expression safely - Object result = engine.eval(expression); - System.out.println(" exoression is : " + expression + " and " + result); - return result; - - } catch (Exception e) { - System.err.println("❌ Error evaluating complex equation: " + e.getMessage()); - return null; - } - } - - private double toDouble(Object val) { - if (val == null) - return 0.0; - try { - return Double.parseDouble(val.toString().trim()); - } catch (NumberFormatException e) { - return 0.0; - } - } - - private Object parseNumberOrString(Object val) { - if (val == null) - return null; - String str = val.toString().trim(); - try { - return Double.parseDouble(str); - } catch (NumberFormatException e) { - return str; - } - } - - private boolean isXml(String content) { - if (content == null) - return false; - String trimmed = content.trim(); - // XML usually starts with '<' and ends with '>' - return trimmed.startsWith("<") && trimmed.endsWith(">"); - } - - private void processBatchData(Data_lake dataLake, Object responseBody, ObjectMapper mapper) - throws JsonProcessingException { - - int batchVolume = (dataLake.getBatch_volume() != null && dataLake.getBatch_volume() > 0) - ? dataLake.getBatch_volume() - : 100; // default batch size if not given - - // Convert to JsonNode - JsonNode jsonNode = mapper.valueToTree(responseBody); - - if (jsonNode.isArray()) { - ArrayNode arrayNode = (ArrayNode) jsonNode; - int total = arrayNode.size(); - System.out.println("Total records: " + total); - - for (int i = 0; i < total; i += batchVolume) { - int end = Math.min(i + batchVolume, total); - - // Create a sub-array manually - ArrayNode subArray = mapper.createArrayNode(); - for (int j = i; j < end; j++) { - subArray.add(arrayNode.get(j)); - } - - String subJson = mapper.writeValueAsString(subArray); - - BatchData batch = new BatchData(); - batch.setDatalake_id(dataLake.getId()); - batch.setBatchjson(subJson); - batchRepo.save(batch); - } - - System.out.println("Inserted " + (int) Math.ceil((double) total / batchVolume) + " batch records."); - - } else { - // Single object β†’ one record - BatchData batch = new BatchData(); - batch.setDatalake_id(dataLake.getId()); - batch.setBatchjson(mapper.writeValueAsString(jsonNode)); - batchRepo.save(batch); - - System.out.println("Inserted single batch record."); - } - } - - public String mergeBatchData(Integer datalakeId) throws Exception { - List batchList = batchRepo.findByDatalake_id(datalakeId); - - if (batchList.isEmpty()) { - throw new RuntimeException("No batch data found for datalake_id: " + datalakeId); - } - - ObjectMapper mapper = new ObjectMapper(); - ArrayNode mergedArray = mapper.createArrayNode(); - - for (BatchData batch : batchList) { - String json = batch.getBatchjson(); - JsonNode node = mapper.readTree(json); - - if (node.isArray()) { - // Add each element to merged array - for (JsonNode item : node) { - mergedArray.add(item); - } - } else { - // Single object, just add directly - mergedArray.add(node); - } - } - - String mergedJson = mapper.writeValueAsString(mergedArray); - System.out.println("Merged JSON size: " + mergedArray.size()); - return mergedJson; - } - - public ResponseEntity GET(String get) { - RestTemplate restTemplate = new RestTemplate(); - - ResponseEntity u = restTemplate.getForEntity(get, Object.class); - - return u; - - } - - public ResponseEntity GETAsString(String url) { - RestTemplate restTemplate = new RestTemplate(); - return restTemplate.getForEntity(url, String.class); - } +// +// List datlakes = Repository.findAllByRefDatlakeId(getUser().getUserId(), id); +// +// datlakes.forEach(lake -> { +// try { +// Updatejson(lake.getId(), rawBody); +// } catch (JsonProcessingException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// }); +// +// Data_lake saved = Updatejson(id, rawBody); +// +// System.out.println(" json updated.."); +// return saved; +// +// } + +// public Data_lake Updatejson(Integer id, String rawBody) throws JsonProcessingException { +// +// Data_lake old = Repository.findById(id).get(); +// +//// String url = old.getUrl(); +//// +//// ResponseEntity response = GETAsString(url); +//// String rawBody = response.getBody(); +// +// // Convert the JSON object (ArrayList, Map, etc.) to a String +//// Object responseBody = response.getBody(); +// ObjectMapper mapper = new ObjectMapper(); +// +//// String jsonString = mapper.writeValueAsString(rawBody); +// ObjectMapper jsonMapper = new ObjectMapper(); +// Object responseBody; +// +// // Detect and convert if XML +// if (isXml(rawBody)) { +// try { +// // Convert XML β†’ JSON tree +// +// XmlMapper xmlMapper = new XmlMapper(); +// +// JsonNode xmlNode = xmlMapper.readTree(rawBody.getBytes()); +// // Convert to standard JSON structure +// String jsonFromXml = jsonMapper.writeValueAsString(xmlNode); +// responseBody = jsonMapper.readValue(jsonFromXml, Object.class); +// System.out.println("XML detected and converted to JSON successfully."); +// } catch (Exception e) { +// throw new RuntimeException("Failed to convert XML to JSON: " + e.getMessage()); +// } +// } else { +// // Normal JSON response +// try { +// responseBody = jsonMapper.readValue(rawBody, Object.class); +// System.out.println("JSON response detected."); +// } catch (Exception e) { +// throw new RuntimeException("Invalid JSON format: " + e.getMessage()); +// } +// } +// +// // βœ… Handle calculated fields before batch processing +// if (Boolean.TRUE.equals(old.getIscalculatedfield()) && old.getCalculated_field_json() != null) { +// try { +// responseBody = applyCalculatedFields(responseBody, old.getCalculated_field_json(), mapper, old); +// System.out.println("Calculated fields applied successfully."); +// } catch (Exception e) { +// System.err.println("Failed to process calculated fields: " + e.getMessage()); +// } +// } +// +// String jsonString = mapper.writeValueAsString(responseBody); +// old.setJson(jsonString); +// +// // Process and insert into BatchData as before +// +// // Process and insert into BatchData +// processBatchData(old, responseBody, mapper); +// +// String Url = Port_Constant.LOCALHOST + ":9292" + "/Data_lake/Data_lake/merge/" + old.getId(); +// old.setUrl_endpoint(Url); +// +// old.setUpdatedBy(getUser().getUserId()); +// +// final Data_lake saved = Repository.save(old); +// +// System.out.println(" json updated.."); +// return saved; +// +// } +// +// @SuppressWarnings("unchecked") +// private Object applyCalculatedFields(Object responseBody, String calculatedFieldJson, ObjectMapper mapper, +// Data_lake old) throws JsonProcessingException { +// +// // Parse the calculated field JSON +// List> calcFields = mapper.readValue(calculatedFieldJson, List.class); +// +// if (!(responseBody instanceof List)) { +// responseBody = Arrays.asList(responseBody); +// } +// +// List> records = (List>) responseBody; +// +// for (Map calc : calcFields) { +// String type = (String) calc.get("type"); +// if ("groupby".equalsIgnoreCase(type)) { +// // βœ… Handle group-by aggregation +// List> groupbyrecords = applyGroupBy(records, calc); +// String groupByRecord = mapper.writeValueAsString(groupbyrecords); +// +// old.setGroupby_json(groupByRecord); +// +// } else { +// // βœ… Handle calculated / complex operations (as before) +// for (Map record : records) { +// String fieldName = (String) calc.get("fieldName"); +// String operation = (String) calc.get("operation"); +// List> components = (List>) calc.get("fieldComponents"); +// +// // Handle constant fields +// if (components != null) { +// for (Map comp : components) { +// String subField = (String) comp.get("field"); +// Boolean isConstant = comp.get("isConstant") != null && (Boolean) comp.get("isConstant"); +// Object constantValue = comp.get("constant"); +// if (isConstant && subField != null) { +// record.put(subField, parseNumberOrString(constantValue)); +// } +// } +// } +// +// // Handle complex expression +// if ("complex".equalsIgnoreCase(operation) && calc.get("complexEquation") != null) { +// String equation = (String) calc.get("complexEquation"); +// Object result = evaluateComplexExpression(equation, record); +// record.put(fieldName, result); +// continue; +// } +// +// // Handle normal arithmetic +// List values = new ArrayList<>(); +// if (components != null) { +// for (Map comp : components) { +// Boolean isConstant = comp.get("isConstant") != null && (Boolean) comp.get("isConstant"); +// Object val = isConstant ? comp.get("constant") : record.get(comp.get("field")); +// if (val != null) { +// values.add(val); +// } +// } +// } +// +// Object result = performOperation(values, operation); +// record.put(fieldName, result); +// } +// } +// } +// +// return records; +// } +// +// @SuppressWarnings("unchecked") +// private List> applyGroupBy(List> records, Map groupConfig) { +// List groupFields = (List) groupConfig.get("groupFields"); +// List> aggregations = (List>) groupConfig.get("aggregations"); +// +// // Group records by key +// Map>> grouped = new LinkedHashMap<>(); +// for (Map record : records) { +// String key = groupFields.stream().map(f -> String.valueOf(record.getOrDefault(f, ""))) +// .collect(Collectors.joining("|")); +// grouped.computeIfAbsent(key, k -> new ArrayList<>()).add(record); +// } +// +// // Aggregate results per group +// List> result = new ArrayList<>(); +// +// for (Map.Entry>> entry : grouped.entrySet()) { +// Map groupRecord = new LinkedHashMap<>(); +// +// // Add group fields +// String[] parts = entry.getKey().split("\\|"); +// for (int i = 0; i < groupFields.size(); i++) { +// groupRecord.put(groupFields.get(i), parts[i]); +// } +// +// List> groupRows = entry.getValue(); +// +// // Apply each aggregation +// for (Map agg : aggregations) { +// String field = (String) agg.get("field"); +// String operation = ((String) agg.get("operation")).toLowerCase(); +// List numericValues = groupRows.stream().map(r -> toDouble(r.get(field))) +// .filter(v -> !Double.isNaN(v)).collect(Collectors.toList()); +// +// Object aggResult; +// switch (operation) { +// case "count": +// aggResult = groupRows.size(); +// break; +// case "sum": +// aggResult = numericValues.stream().mapToDouble(Double::doubleValue).sum(); +// break; +// case "average": +// aggResult = numericValues.isEmpty() ? 0.0 +// : numericValues.stream().mapToDouble(Double::doubleValue).average().orElse(0.0); +// break; +// case "minimum": +// aggResult = numericValues.isEmpty() ? null +// : numericValues.stream().mapToDouble(Double::doubleValue).min().orElse(0.0); +// break; +// case "maximum": +// aggResult = numericValues.isEmpty() ? null +// : numericValues.stream().mapToDouble(Double::doubleValue).max().orElse(0.0); +// break; +// case "median": +// aggResult = calculateMedian(numericValues); +// break; +// case "mode": +// aggResult = calculateMode(numericValues); +// break; +// case "standard deviation": +// aggResult = calculateStdDev(numericValues); +// break; +// default: +// aggResult = null; +// } +// +// groupRecord.put(field + "_" + operation, aggResult); +// } +// +// result.add(groupRecord); +// } +// +// return result; +// } +// +// // --- Statistical helpers --- +// +// private Double calculateMedian(List values) { +// if (values == null || values.isEmpty()) +// return null; +// List sorted = new ArrayList<>(values); +// Collections.sort(sorted); +// int n = sorted.size(); +// if (n % 2 == 1) { +// return sorted.get(n / 2); +// } else { +// return (sorted.get(n / 2 - 1) + sorted.get(n / 2)) / 2.0; +// } +// } +// +// private Double calculateMode(List values) { +// if (values == null || values.isEmpty()) +// return null; +// Map freq = values.stream().collect(Collectors.groupingBy(v -> v, Collectors.counting())); +// return freq.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey).orElse(null); +// } +// +// private Double calculateStdDev(List values) { +// if (values == null || values.isEmpty()) +// return null; +// double mean = values.stream().mapToDouble(Double::doubleValue).average().orElse(0.0); +// double variance = values.stream().mapToDouble(v -> Math.pow(v - mean, 2)).average().orElse(0.0); +// return Math.sqrt(variance); +// } +// +// private Object evaluateComplexExpression(String expression, Map record) { +// try { +// // Replace field names with values dynamically +// for (Map.Entry e : record.entrySet()) { +// String field = e.getKey(); +// Object val = e.getValue(); +// expression = expression.replaceAll("\\b" + field + "\\b", String.valueOf(val != null ? val : 0)); +// } +// +// // Evaluate using ScriptEngine (works on Java 1.8) +// javax.script.ScriptEngine engine = new javax.script.ScriptEngineManager().getEngineByName("JavaScript"); +// Object result = engine.eval(expression); +// return result; +// } catch (Exception e) { +// System.err.println("Complex expression error: " + e.getMessage()); +// return null; +// } +// } +// +//// perform normal operation +// private Object performOperation(List values, String operation) { +// if (values.isEmpty()) +// return null; +// +// switch (operation.toLowerCase()) { +// case "add": +// double sum = 0; +// for (Object v : values) +// sum += toDouble(v); +// return sum; +// +// case "subtract": +// double result = toDouble(values.get(0)); +// for (int i = 1; i < values.size(); i++) +// result -= toDouble(values.get(i)); +// return result; +// +// case "multiply": +// double prod = 1; +// for (Object v : values) +// prod *= toDouble(v); +// return prod; +// +// case "divide": +// double div = toDouble(values.get(0)); +// for (int i = 1; i < values.size(); i++) { +// double val = toDouble(values.get(i)); +// if (val != 0) +// div /= val; +// } +// return div; +// +// case "percentage": +// if (values.size() < 2) +// return null; +// double num = toDouble(values.get(0)); +// double den = toDouble(values.get(1)); +// return den == 0 ? null : (num / den) * 100; +// +// case "concat": +// return values.stream().map(Object::toString).collect(Collectors.joining("_")); +// +// default: +// return null; +// } +// } +// +// /** +// * βœ… Evaluates complex equations using JavaScript engine Supports math +// * operations, parentheses, and string concatenation. +// */ +// private Object evaluateComplexEquation(String expression, Map record, +// List> fieldComponents) { +// +// if (expression == null || expression.trim().isEmpty()) +// return null; +// +// ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); +// +// try { +// // πŸ”Ή Replace constants +// if (fieldComponents != null) { +// for (Map comp : fieldComponents) { +// String field = (String) comp.get("field"); +// Object constant = comp.get("constant"); +// Boolean isConstant = comp.get("isConstant") != null && (Boolean) comp.get("isConstant"); +// +// if (isConstant && constant != null) { +// String constVal = constant.toString(); +// expression = expression.replaceAll("\\b" + field + "\\b", constVal); +// } +// } +// } +// +// // πŸ”Ή Replace field values from record +// for (Map.Entry entry : record.entrySet()) { +// String key = entry.getKey(); +// Object val = entry.getValue(); +// if (val != null) { +// String safeValue = val.toString(); +// +// // If it's a string containing letters, wrap it in quotes for JS +// if (!safeValue.matches("^-?\\d+(\\.\\d+)?$")) { +// safeValue = "'" + safeValue.replace("'", "\\'") + "'"; +// } +// +// expression = expression.replaceAll("\\b" + key + "\\b", safeValue); +// } +// } +// +// // Evaluate the expression safely +// Object result = engine.eval(expression); +// System.out.println(" exoression is : " + expression + " and " + result); +// return result; +// +// } catch (Exception e) { +// System.err.println("❌ Error evaluating complex equation: " + e.getMessage()); +// return null; +// } +// } +// +// private double toDouble(Object val) { +// if (val == null) +// return 0.0; +// try { +// return Double.parseDouble(val.toString().trim()); +// } catch (NumberFormatException e) { +// return 0.0; +// } +// } +// +// private Object parseNumberOrString(Object val) { +// if (val == null) +// return null; +// String str = val.toString().trim(); +// try { +// return Double.parseDouble(str); +// } catch (NumberFormatException e) { +// return str; +// } +// } +// +// private boolean isXml(String content) { +// if (content == null) +// return false; +// String trimmed = content.trim(); +// // XML usually starts with '<' and ends with '>' +// return trimmed.startsWith("<") && trimmed.endsWith(">"); +// } +// +// private void processBatchData(Data_lake dataLake, Object responseBody, ObjectMapper mapper) +// throws JsonProcessingException { +// +// int batchVolume = (dataLake.getBatch_volume() != null && dataLake.getBatch_volume() > 0) +// ? dataLake.getBatch_volume() +// : 100; // default batch size if not given +// +// // Convert to JsonNode +// JsonNode jsonNode = mapper.valueToTree(responseBody); +// +// if (jsonNode.isArray()) { +// ArrayNode arrayNode = (ArrayNode) jsonNode; +// int total = arrayNode.size(); +// System.out.println("Total records: " + total); +// +// for (int i = 0; i < total; i += batchVolume) { +// int end = Math.min(i + batchVolume, total); +// +// // Create a sub-array manually +// ArrayNode subArray = mapper.createArrayNode(); +// for (int j = i; j < end; j++) { +// subArray.add(arrayNode.get(j)); +// } +// +// String subJson = mapper.writeValueAsString(subArray); +// +// BatchData batch = new BatchData(); +// batch.setDatalake_id(dataLake.getId()); +// batch.setBatchjson(subJson); +// batchRepo.save(batch); +// } +// +// System.out.println("Inserted " + (int) Math.ceil((double) total / batchVolume) + " batch records."); +// +// } else { +// // Single object β†’ one record +// BatchData batch = new BatchData(); +// batch.setDatalake_id(dataLake.getId()); +// batch.setBatchjson(mapper.writeValueAsString(jsonNode)); +// batchRepo.save(batch); +// +// System.out.println("Inserted single batch record."); +// } +// } +// +// public String mergeBatchData(Integer datalakeId) throws Exception { +// List batchList = batchRepo.findByDatalake_id(datalakeId); +// +// if (batchList.isEmpty()) { +// throw new RuntimeException("No batch data found for datalake_id: " + datalakeId); +// } +// +// ObjectMapper mapper = new ObjectMapper(); +// ArrayNode mergedArray = mapper.createArrayNode(); +// +// for (BatchData batch : batchList) { +// String json = batch.getBatchjson(); +// JsonNode node = mapper.readTree(json); +// +// if (node.isArray()) { +// // Add each element to merged array +// for (JsonNode item : node) { +// mergedArray.add(item); +// } +// } else { +// // Single object, just add directly +// mergedArray.add(node); +// } +// } +// +// String mergedJson = mapper.writeValueAsString(mergedArray); +// System.out.println("Merged JSON size: " + mergedArray.size()); +// return mergedJson; +// } +// +// public ResponseEntity GET(String get) { +// RestTemplate restTemplate = new RestTemplate(); +// +// ResponseEntity u = restTemplate.getForEntity(get, Object.class); +// +// return u; +// +// } +// +// public ResponseEntity GETAsString(String url) { +// RestTemplate restTemplate = new RestTemplate(); +// return restTemplate.getForEntity(url, String.class); +// } + +// +// public ResponseEntity GETWithString(String url, Integer sureid) { +// RestTemplate restTemplate = new RestTemplate(); +// +// HttpHeaders headers = new HttpHeaders(); +// headers.setAccept(Collections.singletonList(MediaType.ALL)); // accept JSON or XML +// headers.setContentType(MediaType.APPLICATION_JSON); +// +// // πŸ”Ή Add your token here (you can make it dynamic) +// String token = getToken(sureid); // helper method (see below) +// if (token != null && !token.isEmpty()) { +// headers.set("Authorization", "Bearer " + token); +// } +// +// HttpEntity entity = new HttpEntity<>(headers); +// +// ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class); +// +// return response; +// } +// +// private String getToken(Integer sureid) { +// Sure_Connect connect = sureService.getbyid(sureid); +// String access_token = connect.getAccess_token(); +// +// return access_token; // optional +// } public AppUser getUser() { AppUser user = userService.getLoggedInUser(); diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/controllers/ChartTemplateController.java b/backend/src/main/java/com/realnet/DynamicDashbard/controllers/ChartTemplateController.java new file mode 100644 index 0000000..7a57185 --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/controllers/ChartTemplateController.java @@ -0,0 +1,90 @@ +package com.realnet.DynamicDashbard.controllers; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.realnet.DynamicDashbard.entities.ChartTemplate; +import com.realnet.DynamicDashbard.entities.ChartType; +import com.realnet.DynamicDashbard.services.ChartTemplateService; +import com.realnet.DynamicDashbard.services.ChartTypeService; + +@RestController +@RequestMapping("/api/chart-templates") +@CrossOrigin(origins = "*") +public class ChartTemplateController { + + @Autowired + private ChartTemplateService chartTemplateService; + + @Autowired + private ChartTypeService chartTypeService; + + @GetMapping("/all") + public List getAllChartTemplates() { + return chartTemplateService.getAllChartTemplates(); + } + + @GetMapping("/chart-type/{chartTypeId}") + public List getChartTemplatesByChartType(@PathVariable Long chartTypeId) { + return chartTemplateService.getChartTemplatesByChartType(chartTypeId); + } + + @GetMapping("/{id}") + public ResponseEntity getChartTemplateById(@PathVariable Long id) { + Optional chartTemplate = chartTemplateService.getChartTemplateById(id); + return chartTemplate.map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build()); + } + + @PostMapping + public ResponseEntity createChartTemplate(@RequestParam Long chartTypeId, + @RequestBody ChartTemplate chartTemplate) { + try { + // If chartType is provided as ID only, fetch the full ChartType object + if (chartTypeId != null) { + ChartType chartType = chartTypeService.getChartTypeById(chartTypeId) + .orElseThrow(() -> new RuntimeException( + "ChartType not found with id: " + chartTemplate.getChartType().getId())); + chartTemplate.setChartType(chartType); + } + + ChartTemplate createdChartTemplate = chartTemplateService.saveChartTemplate(chartTemplate); + return ResponseEntity.ok(createdChartTemplate); + } catch (Exception e) { + return ResponseEntity.badRequest().build(); + } + } + + @PutMapping("/{id}") + public ResponseEntity updateChartTemplate(@PathVariable Long id, + @RequestBody ChartTemplate chartTemplateDetails) { + try { + ChartTemplate updatedChartTemplate = chartTemplateService.updateChartTemplate(id, chartTemplateDetails); + return ResponseEntity.ok(updatedChartTemplate); + } catch (RuntimeException e) { + return ResponseEntity.notFound().build(); + } + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteChartTemplate(@PathVariable Long id) { + try { + chartTemplateService.deleteChartTemplate(id); + return ResponseEntity.ok().build(); + } catch (RuntimeException e) { + return ResponseEntity.notFound().build(); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/controllers/ChartTypeController.java b/backend/src/main/java/com/realnet/DynamicDashbard/controllers/ChartTypeController.java new file mode 100644 index 0000000..d8777e3 --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/controllers/ChartTypeController.java @@ -0,0 +1,83 @@ +package com.realnet.DynamicDashbard.controllers; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.realnet.DynamicDashbard.entities.ChartType; +import com.realnet.DynamicDashbard.services.ChartTypeService; + +@RestController +@RequestMapping("/api/chart-types") +@CrossOrigin(origins = "*") +public class ChartTypeController { + + @Autowired + private ChartTypeService chartTypeService; + + @GetMapping + public List getAllChartTypes() { + return chartTypeService.getAllChartTypes(); + } + + @GetMapping("/byname") + public ResponseEntity getAllChartTypes(@RequestParam String chartName) { + Optional chartType = chartTypeService.getChartTypeByName(chartName); + + if (!chartType.isPresent()) { + System.out.println(" chart not found"); + + } + System.out.println(chartName + " found :\n"); + + return chartType.map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build()); + } + + @GetMapping("/active") + public List getActiveChartTypes() { + return chartTypeService.getActiveChartTypes(); + } + + @GetMapping("/{id}") + public ResponseEntity getChartTypeById(@PathVariable Long id) { + Optional chartType = chartTypeService.getChartTypeById(id); + return chartType.map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build()); + } + + @PostMapping + public ChartType createChartType(@RequestBody ChartType chartType) { + return chartTypeService.saveChartType(chartType); + } + + @PutMapping("/{id}") + public ResponseEntity updateChartType(@PathVariable Long id, @RequestBody ChartType chartTypeDetails) { + try { + ChartType updatedChartType = chartTypeService.updateChartType(id, chartTypeDetails); + return ResponseEntity.ok(updatedChartType); + } catch (RuntimeException e) { + return ResponseEntity.notFound().build(); + } + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteChartType(@PathVariable Long id) { + try { + chartTypeService.deleteChartType(id); + return ResponseEntity.ok().build(); + } catch (RuntimeException e) { + return ResponseEntity.notFound().build(); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/controllers/ComponentPropertyController.java b/backend/src/main/java/com/realnet/DynamicDashbard/controllers/ComponentPropertyController.java new file mode 100644 index 0000000..3e21ea0 --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/controllers/ComponentPropertyController.java @@ -0,0 +1,92 @@ +package com.realnet.DynamicDashbard.controllers; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.realnet.DynamicDashbard.entities.ComponentProperty; +import com.realnet.DynamicDashbard.entities.UiComponent; +import com.realnet.DynamicDashbard.services.ComponentPropertyService; +import com.realnet.DynamicDashbard.services.UiComponentService; + +@RestController +@RequestMapping("/api/component-properties") +@CrossOrigin(origins = "*") +public class ComponentPropertyController { + + @Autowired + private ComponentPropertyService componentPropertyService; + + @Autowired + private UiComponentService uiComponentService; + + @GetMapping + public List getAllComponentProperties() { + return componentPropertyService.getAllComponentProperties(); + } + + @GetMapping("/component/{componentId}") + public List getComponentPropertiesByComponent(@PathVariable Long componentId) { + return componentPropertyService.getComponentPropertiesByComponent(componentId); + } + + @GetMapping("/{id}") + public ResponseEntity getComponentPropertyById(@PathVariable Long id) { + Optional componentProperty = componentPropertyService.getComponentPropertyById(id); + return componentProperty.map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build()); + } + + @PostMapping + public ResponseEntity createComponentProperty(@RequestBody ComponentProperty componentProperty) { + try { + // If component is provided as ID only, fetch the full UiComponent object + if (componentProperty.getComponent() != null && componentProperty.getComponent().getId() != null + && (componentProperty.getComponent().getComponentName() == null + || componentProperty.getComponent().getComponentName().isEmpty())) { + UiComponent component = uiComponentService.getUiComponentById(componentProperty.getComponent().getId()) + .orElseThrow(() -> new RuntimeException( + "UiComponent not found with id: " + componentProperty.getComponent().getId())); + componentProperty.setComponent(component); + } + + ComponentProperty createdComponentProperty = componentPropertyService + .saveComponentProperty(componentProperty); + return ResponseEntity.ok(createdComponentProperty); + } catch (Exception e) { + return ResponseEntity.badRequest().build(); + } + } + + @PutMapping("/{id}") + public ResponseEntity updateComponentProperty(@PathVariable Long id, + @RequestBody ComponentProperty componentPropertyDetails) { + try { + ComponentProperty updatedComponentProperty = componentPropertyService.updateComponentProperty(id, + componentPropertyDetails); + return ResponseEntity.ok(updatedComponentProperty); + } catch (RuntimeException e) { + return ResponseEntity.notFound().build(); + } + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteComponentProperty(@PathVariable Long id) { + try { + componentPropertyService.deleteComponentProperty(id); + return ResponseEntity.ok().build(); + } catch (RuntimeException e) { + return ResponseEntity.notFound().build(); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/controllers/DynamicFieldController.java b/backend/src/main/java/com/realnet/DynamicDashbard/controllers/DynamicFieldController.java new file mode 100644 index 0000000..1a93c5f --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/controllers/DynamicFieldController.java @@ -0,0 +1,90 @@ +package com.realnet.DynamicDashbard.controllers; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.realnet.DynamicDashbard.entities.ChartType; +import com.realnet.DynamicDashbard.entities.DynamicField; +import com.realnet.DynamicDashbard.services.ChartTypeService; +import com.realnet.DynamicDashbard.services.DynamicFieldService; + +@RestController +@RequestMapping("/api/dynamic-fields") +@CrossOrigin(origins = "*") +public class DynamicFieldController { + + @Autowired + private DynamicFieldService dynamicFieldService; + + @Autowired + private ChartTypeService chartTypeService; + + @GetMapping + public List getAllDynamicFields() { + return dynamicFieldService.getAllDynamicFields(); + } + + @GetMapping("/chart-type/{chartTypeId}") + public List getDynamicFieldsByChartType(@PathVariable Long chartTypeId) { + return dynamicFieldService.getDynamicFieldsByChartType(chartTypeId); + } + + @GetMapping("/{id}") + public ResponseEntity getDynamicFieldById(@PathVariable Long id) { + Optional dynamicField = dynamicFieldService.getDynamicFieldById(id); + return dynamicField.map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build()); + } + + @PostMapping + public ResponseEntity createDynamicField(@RequestParam Long chartTypeId, + @RequestBody DynamicField dynamicField) { + try { + // If chartType is provided as ID only, fetch the full ChartType object + if (chartTypeId != null) { + ChartType chartType = chartTypeService.getChartTypeById(chartTypeId) + .orElseThrow(() -> new RuntimeException( + "ChartType not found with id: " + dynamicField.getChartType().getId())); + dynamicField.setChartType(chartType); + } + + DynamicField createdDynamicField = dynamicFieldService.saveDynamicField(dynamicField); + return ResponseEntity.ok(createdDynamicField); + } catch (Exception e) { + return ResponseEntity.badRequest().build(); + } + } + + @PutMapping("/{id}") + public ResponseEntity updateDynamicField(@PathVariable Long id, + @RequestBody DynamicField dynamicFieldDetails) { + try { + DynamicField updatedDynamicField = dynamicFieldService.updateDynamicField(id, dynamicFieldDetails); + return ResponseEntity.ok(updatedDynamicField); + } catch (RuntimeException e) { + return ResponseEntity.notFound().build(); + } + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteDynamicField(@PathVariable Long id) { + try { + dynamicFieldService.deleteDynamicField(id); + return ResponseEntity.ok().build(); + } catch (RuntimeException e) { + return ResponseEntity.notFound().build(); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/controllers/UiComponentController.java b/backend/src/main/java/com/realnet/DynamicDashbard/controllers/UiComponentController.java new file mode 100644 index 0000000..aa8c30e --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/controllers/UiComponentController.java @@ -0,0 +1,91 @@ +package com.realnet.DynamicDashbard.controllers; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.realnet.DynamicDashbard.entities.ChartType; +import com.realnet.DynamicDashbard.entities.UiComponent; +import com.realnet.DynamicDashbard.services.ChartTypeService; +import com.realnet.DynamicDashbard.services.UiComponentService; + +@RestController +@RequestMapping("/api/ui-components") +@CrossOrigin(origins = "*") +public class UiComponentController { + + @Autowired + private UiComponentService uiComponentService; + + @Autowired + private ChartTypeService chartTypeService; + + @GetMapping + public List getAllUiComponents() { + return uiComponentService.getAllUiComponents(); + } + + @GetMapping("/chart-type/{chartTypeId}") + public List getUiComponentsByChartType(@PathVariable Long chartTypeId) { + return uiComponentService.getUiComponentsByChartType(chartTypeId); + } + + @GetMapping("/{id}") + public ResponseEntity getUiComponentById(@PathVariable Long id) { + Optional uiComponent = uiComponentService.getUiComponentById(id); + return uiComponent.map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build()); + } + + @PostMapping + public ResponseEntity createUiComponent(@RequestBody UiComponent uiComponent) { + try { + // If chartType is provided as ID only, fetch the full ChartType object + if (uiComponent.getChartType() != null && uiComponent.getChartType().getId() != null + && (uiComponent.getChartType().getName() == null + || uiComponent.getChartType().getName().isEmpty())) { + ChartType chartType = chartTypeService.getChartTypeById(uiComponent.getChartType().getId()) + .orElseThrow(() -> new RuntimeException( + "ChartType not found with id: " + uiComponent.getChartType().getId())); + uiComponent.setChartType(chartType); + } + + UiComponent createdUiComponent = uiComponentService.saveUiComponent(uiComponent); + System.out.println(createdUiComponent.getComponentName() + " ui component created successfully.."); + return ResponseEntity.ok(createdUiComponent); + } catch (Exception e) { + return ResponseEntity.badRequest().build(); + } + } + + @PutMapping("/{id}") + public ResponseEntity updateUiComponent(@PathVariable Long id, + @RequestBody UiComponent uiComponentDetails) { + try { + UiComponent updatedUiComponent = uiComponentService.updateUiComponent(id, uiComponentDetails); + return ResponseEntity.ok(updatedUiComponent); + } catch (RuntimeException e) { + return ResponseEntity.notFound().build(); + } + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteUiComponent(@PathVariable Long id) { + try { + uiComponentService.deleteUiComponent(id); + return ResponseEntity.ok().build(); + } catch (RuntimeException e) { + return ResponseEntity.notFound().build(); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/entities/ChartTemplate.java b/backend/src/main/java/com/realnet/DynamicDashbard/entities/ChartTemplate.java new file mode 100644 index 0000000..aa0ab5c --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/entities/ChartTemplate.java @@ -0,0 +1,149 @@ +package com.realnet.DynamicDashbard.entities; + +import java.time.LocalDateTime; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.PrePersist; +import javax.persistence.PreUpdate; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import com.fasterxml.jackson.annotation.JsonBackReference; + +import lombok.Data; + +@Data +@Entity +@Table(name = "chart_templates") +public class ChartTemplate { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "chart_type_id", nullable = false) + @JsonBackReference + private ChartType chartType; + + @Column(name = "template_name", nullable = false, length = 100) + private String templateName; + + @Column(name = "template_html", columnDefinition = "TEXT") + private String templateHtml; + + @Column(name = "template_css", columnDefinition = "TEXT") + private String templateCss; + + @Column(name = "is_default") + private Boolean isDefault = false; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "created_at") + @CreatedDate + private Date createdAt; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "updated_at") + @LastModifiedDate + private Date updatedAt; + +// +// @PrePersist +// protected void onCreate() { +// createdAt = LocalDateTime.now(); +// updatedAt = LocalDateTime.now(); +// } +// +// @PreUpdate +// protected void onUpdate() { +// updatedAt = LocalDateTime.now(); +// } +// +// // Constructors +// public ChartTemplate() { +// } +// +// public ChartTemplate(ChartType chartType, String templateName, String templateHtml, String templateCss) { +// this.chartType = chartType; +// this.templateName = templateName; +// this.templateHtml = templateHtml; +// this.templateCss = templateCss; +// } +// +// // Getters and Setters +// public Long getId() { +// return id; +// } +// +// public void setId(Long id) { +// this.id = id; +// } +// +// public ChartType getChartType() { +// return chartType; +// } +// +// public void setChartType(ChartType chartType) { +// this.chartType = chartType; +// } +// +// public String getTemplateName() { +// return templateName; +// } +// +// public void setTemplateName(String templateName) { +// this.templateName = templateName; +// } +// +// public String getTemplateHtml() { +// return templateHtml; +// } +// +// public void setTemplateHtml(String templateHtml) { +// this.templateHtml = templateHtml; +// } +// +// public String getTemplateCss() { +// return templateCss; +// } +// +// public void setTemplateCss(String templateCss) { +// this.templateCss = templateCss; +// } +// +// public Boolean getIsDefault() { +// return isDefault; +// } +// +// public void setIsDefault(Boolean isDefault) { +// this.isDefault = isDefault; +// } +// +// public LocalDateTime getCreatedAt() { +// return createdAt; +// } +// +// public void setCreatedAt(LocalDateTime createdAt) { +// this.createdAt = createdAt; +// } +// +// public LocalDateTime getUpdatedAt() { +// return updatedAt; +// } +// +// public void setUpdatedAt(LocalDateTime updatedAt) { +// this.updatedAt = updatedAt; +// } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/entities/ChartType.java b/backend/src/main/java/com/realnet/DynamicDashbard/entities/ChartType.java new file mode 100644 index 0000000..084a851 --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/entities/ChartType.java @@ -0,0 +1,168 @@ +package com.realnet.DynamicDashbard.entities; + +import java.util.Date; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import com.fasterxml.jackson.annotation.JsonManagedReference; + +import lombok.Data; + +@Data +@Entity +@Table(name = "chart_types") +public class ChartType { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name", nullable = false, length = 50) + private String name; + + @Column(name = "display_name", length = 100) + private String displayName; + + @Column(name = "description", columnDefinition = "TEXT") + private String description; + + @Column(name = "is_active") + private Boolean isActive = true; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "created_at") + @CreatedDate + private Date createdAt; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "updated_at") + @LastModifiedDate + private Date updatedAt; + + @OneToMany(mappedBy = "chartType", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JsonManagedReference + private List uiComponents; + + @OneToMany(mappedBy = "chartType", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JsonManagedReference + private List chartTemplates; + + @OneToMany(mappedBy = "chartType", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JsonManagedReference + private List dynamicFields; + +// @PrePersist +// protected void onCreate() { +// createdAt = LocalDateTime.now(); +// updatedAt = LocalDateTime.now(); +// } +// +// @PreUpdate +// protected void onUpdate() { +// updatedAt = LocalDateTime.now(); +// } +// +// // Constructors +// public ChartType() { +// } +// +// public ChartType(String name, String displayName, String description) { +// this.name = name; +// this.displayName = displayName; +// this.description = description; +// } +// +// // Getters and Setters +// public Long getId() { +// return id; +// } +// +// public void setId(Long id) { +// this.id = id; +// } +// +// public String getName() { +// return name; +// } +// +// public void setName(String name) { +// this.name = name; +// } +// +// public String getDisplayName() { +// return displayName; +// } +// +// public void setDisplayName(String displayName) { +// this.displayName = displayName; +// } +// +// public String getDescription() { +// return description; +// } +// +// public void setDescription(String description) { +// this.description = description; +// } +// +// public Boolean getIsActive() { +// return isActive; +// } +// +// public void setIsActive(Boolean isActive) { +// this.isActive = isActive; +// } +// +// public LocalDateTime getCreatedAt() { +// return createdAt; +// } +// +// public void setCreatedAt(LocalDateTime createdAt) { +// this.createdAt = createdAt; +// } +// +// public LocalDateTime getUpdatedAt() { +// return updatedAt; +// } +// +// public void setUpdatedAt(LocalDateTime updatedAt) { +// this.updatedAt = updatedAt; +// } +// +// public List getUiComponents() { +// return uiComponents; +// } +// +// public void setUiComponents(List uiComponents) { +// this.uiComponents = uiComponents; +// } +// +// public List getChartTemplates() { +// return chartTemplates; +// } +// +// public void setChartTemplates(List chartTemplates) { +// this.chartTemplates = chartTemplates; +// } +// +// public List getDynamicFields() { +// return dynamicFields; +// } +// +// public void setDynamicFields(List dynamicFields) { +// this.dynamicFields = dynamicFields; +// } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/entities/ComponentProperty.java b/backend/src/main/java/com/realnet/DynamicDashbard/entities/ComponentProperty.java new file mode 100644 index 0000000..a358785 --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/entities/ComponentProperty.java @@ -0,0 +1,134 @@ +package com.realnet.DynamicDashbard.entities; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import com.fasterxml.jackson.annotation.JsonBackReference; + +import lombok.Data; + +@Data +@Entity +@Table(name = "component_properties") +public class ComponentProperty { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "component_id", nullable = false) + @JsonBackReference + private UiComponent component; + + @Column(name = "property_name", nullable = false, length = 100) + private String propertyName; + + @Column(name = "property_value", columnDefinition = "TEXT") + private String propertyValue; + + @Column(name = "property_type", length = 50) + private String propertyType; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "created_at") + @CreatedDate + private Date createdAt; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "updated_at") + @LastModifiedDate + private Date updatedAt; + +// +// @PrePersist +// protected void onCreate() { +// createdAt = LocalDateTime.now(); +// updatedAt = LocalDateTime.now(); +// } +// +// @PreUpdate +// protected void onUpdate() { +// updatedAt = LocalDateTime.now(); +// } +// +// // Constructors +// public ComponentProperty() {} +// +// public ComponentProperty(UiComponent component, String propertyName, String propertyValue, String propertyType) { +// this.component = component; +// this.propertyName = propertyName; +// this.propertyValue = propertyValue; +// this.propertyType = propertyType; +// } +// +// // Getters and Setters +// public Long getId() { +// return id; +// } +// +// public void setId(Long id) { +// this.id = id; +// } +// +// public UiComponent getComponent() { +// return component; +// } +// +// public void setComponent(UiComponent component) { +// this.component = component; +// } +// +// public String getPropertyName() { +// return propertyName; +// } +// +// public void setPropertyName(String propertyName) { +// this.propertyName = propertyName; +// } +// +// public String getPropertyValue() { +// return propertyValue; +// } +// +// public void setPropertyValue(String propertyValue) { +// this.propertyValue = propertyValue; +// } +// +// public String getPropertyType() { +// return propertyType; +// } +// +// public void setPropertyType(String propertyType) { +// this.propertyType = propertyType; +// } +// +// public LocalDateTime getCreatedAt() { +// return createdAt; +// } +// +// public void setCreatedAt(LocalDateTime createdAt) { +// this.createdAt = createdAt; +// } +// +// public LocalDateTime getUpdatedAt() { +// return updatedAt; +// } +// +// public void setUpdatedAt(LocalDateTime updatedAt) { +// this.updatedAt = updatedAt; +// } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/entities/DynamicField.java b/backend/src/main/java/com/realnet/DynamicDashbard/entities/DynamicField.java new file mode 100644 index 0000000..f979111 --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/entities/DynamicField.java @@ -0,0 +1,179 @@ +package com.realnet.DynamicDashbard.entities; + +import java.time.LocalDateTime; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.PrePersist; +import javax.persistence.PreUpdate; +import javax.persistence.Table; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; + +@Entity +@Table(name = "dynamic_fields") +public class DynamicField { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "chart_type_id", nullable = false) + @JsonBackReference + private ChartType chartType; + + @Column(name = "field_name", nullable = false, length = 100) + private String fieldName; + + @Column(name = "field_label", length = 100) + private String fieldLabel; + + @Column(name = "field_type", length = 50) + private String fieldType; + + @Column(name = "field_options", columnDefinition = "TEXT") + private String fieldOptions; + + @Column(name = "is_required") + private Boolean isRequired = false; + + @Column(name = "show_in_ui") + private Boolean showInUi = true; + + @Column(name = "sort_order") + private Integer sortOrder; + + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + @Column(name = "created_at") + private LocalDateTime createdAt; + + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + @Column(name = "updated_at") + private LocalDateTime updatedAt; + + @PrePersist + protected void onCreate() { + createdAt = LocalDateTime.now(); + updatedAt = LocalDateTime.now(); + } + + @PreUpdate + protected void onUpdate() { + updatedAt = LocalDateTime.now(); + } + + // Constructors + public DynamicField() { + } + + public DynamicField(ChartType chartType, String fieldName, String fieldLabel, String fieldType) { + this.chartType = chartType; + this.fieldName = fieldName; + this.fieldLabel = fieldLabel; + this.fieldType = fieldType; + } + + // Getters and Setters + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public ChartType getChartType() { + return chartType; + } + + public void setChartType(ChartType chartType) { + this.chartType = chartType; + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public String getFieldLabel() { + return fieldLabel; + } + + public void setFieldLabel(String fieldLabel) { + this.fieldLabel = fieldLabel; + } + + public String getFieldType() { + return fieldType; + } + + public void setFieldType(String fieldType) { + this.fieldType = fieldType; + } + + public String getFieldOptions() { + return fieldOptions; + } + + public void setFieldOptions(String fieldOptions) { + this.fieldOptions = fieldOptions; + } + + public Boolean getIsRequired() { + return isRequired; + } + + public void setIsRequired(Boolean isRequired) { + this.isRequired = isRequired; + } + + public Boolean getShowInUi() { + return showInUi; + } + + public void setShowInUi(Boolean showInUi) { + this.showInUi = showInUi; + } + + public Integer getSortOrder() { + return sortOrder; + } + + public void setSortOrder(Integer sortOrder) { + this.sortOrder = sortOrder; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(LocalDateTime updatedAt) { + this.updatedAt = updatedAt; + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/entities/UiComponent.java b/backend/src/main/java/com/realnet/DynamicDashbard/entities/UiComponent.java new file mode 100644 index 0000000..cfb34e5 --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/entities/UiComponent.java @@ -0,0 +1,94 @@ +package com.realnet.DynamicDashbard.entities; + +import java.util.Date; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonManagedReference; + +import lombok.Data; + +@Data +@Entity +@Table(name = "ui_components") +public class UiComponent { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "chart_type_id", nullable = false) + @JsonBackReference + private ChartType chartType; + + @Column(name = "component_name", nullable = false, length = 100) + private String componentName; + + @Column(name = "component_type", length = 50) + private String componentType; + + @Column(name = "display_label", length = 100) + private String displayLabel; + + @Column(name = "placeholder", columnDefinition = "TEXT") + private String placeholder; + + @Column(name = "is_required") + private Boolean isRequired = false; + + @Column(name = "sort_order") + private Integer sortOrder; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "created_at") + @CreatedDate + private Date createdAt; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "updated_at") + @LastModifiedDate + private Date updatedAt; + + @OneToMany(mappedBy = "component", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JsonManagedReference + private List componentProperties; + +// @PrePersist +// protected void onCreate() { +// createdAt = LocalDateTime.now(); +// updatedAt = LocalDateTime.now(); +// } +// +// @PreUpdate +// protected void onUpdate() { +// updatedAt = LocalDateTime.now(); +// } + + // Constructors + public UiComponent() { + } + + public UiComponent(ChartType chartType, String componentName, String componentType) { + this.chartType = chartType; + this.componentName = componentName; + this.componentType = componentType; + } + +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/repositories/ChartTemplateRepository.java b/backend/src/main/java/com/realnet/DynamicDashbard/repositories/ChartTemplateRepository.java new file mode 100644 index 0000000..37d2191 --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/repositories/ChartTemplateRepository.java @@ -0,0 +1,19 @@ +package com.realnet.DynamicDashbard.repositories; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.realnet.DynamicDashbard.entities.ChartTemplate; +import com.realnet.DynamicDashbard.entities.ChartType; + +@Repository +public interface ChartTemplateRepository extends JpaRepository { + List findByChartType(ChartType chartType); + + Optional findByChartTypeAndIsDefaultTrue(ChartType chartType); + + List findByChartTypeAndTemplateNameContainingIgnoreCase(ChartType chartType, String templateName); +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/repositories/ChartTypeRepository.java b/backend/src/main/java/com/realnet/DynamicDashbard/repositories/ChartTypeRepository.java new file mode 100644 index 0000000..c372d8a --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/repositories/ChartTypeRepository.java @@ -0,0 +1,18 @@ +package com.realnet.DynamicDashbard.repositories; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.realnet.DynamicDashbard.entities.ChartType; + +@Repository +public interface ChartTypeRepository extends JpaRepository { + + List findByIsActiveTrue(); + + Optional findByName(String name); + +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/repositories/ComponentPropertyRepository.java b/backend/src/main/java/com/realnet/DynamicDashbard/repositories/ComponentPropertyRepository.java new file mode 100644 index 0000000..c7c7b71 --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/repositories/ComponentPropertyRepository.java @@ -0,0 +1,15 @@ +package com.realnet.DynamicDashbard.repositories; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.realnet.DynamicDashbard.entities.ComponentProperty; +import com.realnet.DynamicDashbard.entities.UiComponent; + +@Repository +public interface ComponentPropertyRepository extends JpaRepository { + List findByComponent(UiComponent component); + List findByComponentAndPropertyName(UiComponent component, String propertyName); +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/repositories/DynamicFieldRepository.java b/backend/src/main/java/com/realnet/DynamicDashbard/repositories/DynamicFieldRepository.java new file mode 100644 index 0000000..c0ebec6 --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/repositories/DynamicFieldRepository.java @@ -0,0 +1,18 @@ + +package com.realnet.DynamicDashbard.repositories; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.realnet.DynamicDashbard.entities.ChartType; +import com.realnet.DynamicDashbard.entities.DynamicField; + +@Repository +public interface DynamicFieldRepository extends JpaRepository { + List findByChartType(ChartType chartType); + List findByChartTypeAndIsRequiredTrue(ChartType chartType); + List findByChartTypeAndShowInUiTrueOrderBySortOrder(ChartType chartType); + List findByChartTypeOrderBySortOrder(ChartType chartType); +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/repositories/UiComponentRepository.java b/backend/src/main/java/com/realnet/DynamicDashbard/repositories/UiComponentRepository.java new file mode 100644 index 0000000..502660d --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/repositories/UiComponentRepository.java @@ -0,0 +1,18 @@ +package com.realnet.DynamicDashbard.repositories; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.realnet.DynamicDashbard.entities.ChartType; +import com.realnet.DynamicDashbard.entities.UiComponent; + +@Repository +public interface UiComponentRepository extends JpaRepository { + List findByChartType(ChartType chartType); + + List findByChartTypeAndIsRequiredTrue(ChartType chartType); + + List findByChartTypeOrderBySortOrder(ChartType chartType); +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/services/ChartTemplateService.java b/backend/src/main/java/com/realnet/DynamicDashbard/services/ChartTemplateService.java new file mode 100644 index 0000000..07ad8c7 --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/services/ChartTemplateService.java @@ -0,0 +1,58 @@ +package com.realnet.DynamicDashbard.services; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.realnet.DynamicDashbard.entities.ChartTemplate; +import com.realnet.DynamicDashbard.entities.ChartType; +import com.realnet.DynamicDashbard.repositories.ChartTemplateRepository; +import com.realnet.DynamicDashbard.repositories.ChartTypeRepository; + +@Service +public class ChartTemplateService { + + @Autowired + private ChartTemplateRepository chartTemplateRepository; + + @Autowired + private ChartTypeRepository chartTypeRepository; + + public List getAllChartTemplates() { + return chartTemplateRepository.findAll(); + } + + public List getChartTemplatesByChartType(Long chartTypeId) { + ChartType chartType = chartTypeRepository.findById(chartTypeId) + .orElseThrow(() -> new RuntimeException("ChartType not found with id: " + chartTypeId)); + return chartTemplateRepository.findByChartType(chartType); + } + + public Optional getChartTemplateById(Long id) { + return chartTemplateRepository.findById(id); + } + + public ChartTemplate saveChartTemplate(ChartTemplate chartTemplate) { + return chartTemplateRepository.save(chartTemplate); + } + + public ChartTemplate updateChartTemplate(Long id, ChartTemplate chartTemplateDetails) { + ChartTemplate chartTemplate = chartTemplateRepository.findById(id) + .orElseThrow(() -> new RuntimeException("ChartTemplate not found with id: " + id)); + + chartTemplate.setTemplateName(chartTemplateDetails.getTemplateName()); + chartTemplate.setTemplateHtml(chartTemplateDetails.getTemplateHtml()); + chartTemplate.setTemplateCss(chartTemplateDetails.getTemplateCss()); + chartTemplate.setIsDefault(chartTemplateDetails.getIsDefault()); + + return chartTemplateRepository.save(chartTemplate); + } + + public void deleteChartTemplate(Long id) { + ChartTemplate chartTemplate = chartTemplateRepository.findById(id) + .orElseThrow(() -> new RuntimeException("ChartTemplate not found with id: " + id)); + chartTemplateRepository.delete(chartTemplate); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/services/ChartTypeService.java b/backend/src/main/java/com/realnet/DynamicDashbard/services/ChartTypeService.java new file mode 100644 index 0000000..a3ec69e --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/services/ChartTypeService.java @@ -0,0 +1,55 @@ +package com.realnet.DynamicDashbard.services; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.realnet.DynamicDashbard.entities.ChartType; +import com.realnet.DynamicDashbard.repositories.ChartTypeRepository; + +@Service +public class ChartTypeService { + + @Autowired + private ChartTypeRepository chartTypeRepository; + + public List getAllChartTypes() { + return chartTypeRepository.findAll(); + } + + public List getActiveChartTypes() { + return chartTypeRepository.findByIsActiveTrue(); + } + + public Optional getChartTypeById(Long id) { + return chartTypeRepository.findById(id); + } + + public Optional getChartTypeByName(String name) { + return chartTypeRepository.findByName(name); + } + + public ChartType saveChartType(ChartType chartType) { + return chartTypeRepository.save(chartType); + } + + public ChartType updateChartType(Long id, ChartType chartTypeDetails) { + ChartType chartType = chartTypeRepository.findById(id) + .orElseThrow(() -> new RuntimeException("ChartType not found with id: " + id)); + + chartType.setName(chartTypeDetails.getName()); + chartType.setDisplayName(chartTypeDetails.getDisplayName()); + chartType.setDescription(chartTypeDetails.getDescription()); + chartType.setIsActive(chartTypeDetails.getIsActive()); + + return chartTypeRepository.save(chartType); + } + + public void deleteChartType(Long id) { + ChartType chartType = chartTypeRepository.findById(id) + .orElseThrow(() -> new RuntimeException("ChartType not found with id: " + id)); + chartTypeRepository.delete(chartType); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/services/ComponentPropertyService.java b/backend/src/main/java/com/realnet/DynamicDashbard/services/ComponentPropertyService.java new file mode 100644 index 0000000..650679a --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/services/ComponentPropertyService.java @@ -0,0 +1,57 @@ +package com.realnet.DynamicDashbard.services; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.realnet.DynamicDashbard.entities.ComponentProperty; +import com.realnet.DynamicDashbard.entities.UiComponent; +import com.realnet.DynamicDashbard.repositories.ComponentPropertyRepository; +import com.realnet.DynamicDashbard.repositories.UiComponentRepository; + +@Service +public class ComponentPropertyService { + + @Autowired + private ComponentPropertyRepository componentPropertyRepository; + + @Autowired + private UiComponentRepository uiComponentRepository; + + public List getAllComponentProperties() { + return componentPropertyRepository.findAll(); + } + + public List getComponentPropertiesByComponent(Long componentId) { + UiComponent component = uiComponentRepository.findById(componentId) + .orElseThrow(() -> new RuntimeException("UiComponent not found with id: " + componentId)); + return componentPropertyRepository.findByComponent(component); + } + + public Optional getComponentPropertyById(Long id) { + return componentPropertyRepository.findById(id); + } + + public ComponentProperty saveComponentProperty(ComponentProperty componentProperty) { + return componentPropertyRepository.save(componentProperty); + } + + public ComponentProperty updateComponentProperty(Long id, ComponentProperty componentPropertyDetails) { + ComponentProperty componentProperty = componentPropertyRepository.findById(id) + .orElseThrow(() -> new RuntimeException("ComponentProperty not found with id: " + id)); + + componentProperty.setPropertyName(componentPropertyDetails.getPropertyName()); + componentProperty.setPropertyValue(componentPropertyDetails.getPropertyValue()); + componentProperty.setPropertyType(componentPropertyDetails.getPropertyType()); + + return componentPropertyRepository.save(componentProperty); + } + + public void deleteComponentProperty(Long id) { + ComponentProperty componentProperty = componentPropertyRepository.findById(id) + .orElseThrow(() -> new RuntimeException("ComponentProperty not found with id: " + id)); + componentPropertyRepository.delete(componentProperty); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/services/DynamicFieldService.java b/backend/src/main/java/com/realnet/DynamicDashbard/services/DynamicFieldService.java new file mode 100644 index 0000000..92d42d3 --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/services/DynamicFieldService.java @@ -0,0 +1,61 @@ +package com.realnet.DynamicDashbard.services; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.realnet.DynamicDashbard.entities.ChartType; +import com.realnet.DynamicDashbard.entities.DynamicField; +import com.realnet.DynamicDashbard.repositories.ChartTypeRepository; +import com.realnet.DynamicDashbard.repositories.DynamicFieldRepository; + +@Service +public class DynamicFieldService { + + @Autowired + private DynamicFieldRepository dynamicFieldRepository; + + @Autowired + private ChartTypeRepository chartTypeRepository; + + public List getAllDynamicFields() { + return dynamicFieldRepository.findAll(); + } + + public List getDynamicFieldsByChartType(Long chartTypeId) { + ChartType chartType = chartTypeRepository.findById(chartTypeId) + .orElseThrow(() -> new RuntimeException("ChartType not found with id: " + chartTypeId)); + return dynamicFieldRepository.findByChartType(chartType); + } + + public Optional getDynamicFieldById(Long id) { + return dynamicFieldRepository.findById(id); + } + + public DynamicField saveDynamicField(DynamicField dynamicField) { + return dynamicFieldRepository.save(dynamicField); + } + + public DynamicField updateDynamicField(Long id, DynamicField dynamicFieldDetails) { + DynamicField dynamicField = dynamicFieldRepository.findById(id) + .orElseThrow(() -> new RuntimeException("DynamicField not found with id: " + id)); + + dynamicField.setFieldName(dynamicFieldDetails.getFieldName()); + dynamicField.setFieldLabel(dynamicFieldDetails.getFieldLabel()); + dynamicField.setFieldType(dynamicFieldDetails.getFieldType()); + dynamicField.setFieldOptions(dynamicFieldDetails.getFieldOptions()); + dynamicField.setIsRequired(dynamicFieldDetails.getIsRequired()); + dynamicField.setShowInUi(dynamicFieldDetails.getShowInUi()); + dynamicField.setSortOrder(dynamicFieldDetails.getSortOrder()); + + return dynamicFieldRepository.save(dynamicField); + } + + public void deleteDynamicField(Long id) { + DynamicField dynamicField = dynamicFieldRepository.findById(id) + .orElseThrow(() -> new RuntimeException("DynamicField not found with id: " + id)); + dynamicFieldRepository.delete(dynamicField); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/DynamicDashbard/services/UiComponentService.java b/backend/src/main/java/com/realnet/DynamicDashbard/services/UiComponentService.java new file mode 100644 index 0000000..5582f0e --- /dev/null +++ b/backend/src/main/java/com/realnet/DynamicDashbard/services/UiComponentService.java @@ -0,0 +1,60 @@ +package com.realnet.DynamicDashbard.services; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.realnet.DynamicDashbard.entities.ChartType; +import com.realnet.DynamicDashbard.entities.UiComponent; +import com.realnet.DynamicDashbard.repositories.ChartTypeRepository; +import com.realnet.DynamicDashbard.repositories.UiComponentRepository; + +@Service +public class UiComponentService { + + @Autowired + private UiComponentRepository uiComponentRepository; + + @Autowired + private ChartTypeRepository chartTypeRepository; + + public List getAllUiComponents() { + return uiComponentRepository.findAll(); + } + + public List getUiComponentsByChartType(Long chartTypeId) { + ChartType chartType = chartTypeRepository.findById(chartTypeId) + .orElseThrow(() -> new RuntimeException("ChartType not found with id: " + chartTypeId)); + return uiComponentRepository.findByChartType(chartType); + } + + public Optional getUiComponentById(Long id) { + return uiComponentRepository.findById(id); + } + + public UiComponent saveUiComponent(UiComponent uiComponent) { + return uiComponentRepository.save(uiComponent); + } + + public UiComponent updateUiComponent(Long id, UiComponent uiComponentDetails) { + UiComponent uiComponent = uiComponentRepository.findById(id) + .orElseThrow(() -> new RuntimeException("UiComponent not found with id: " + id)); + + uiComponent.setComponentName(uiComponentDetails.getComponentName()); + uiComponent.setComponentType(uiComponentDetails.getComponentType()); + uiComponent.setDisplayLabel(uiComponentDetails.getDisplayLabel()); + uiComponent.setPlaceholder(uiComponentDetails.getPlaceholder()); + uiComponent.setIsRequired(uiComponentDetails.getIsRequired()); + uiComponent.setSortOrder(uiComponentDetails.getSortOrder()); + + return uiComponentRepository.save(uiComponent); + } + + public void deleteUiComponent(Long id) { + UiComponent uiComponent = uiComponentRepository.findById(id) + .orElseThrow(() -> new RuntimeException("UiComponent not found with id: " + id)); + uiComponentRepository.delete(uiComponent); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/Rpt_builder2/Entity/Rpt_builder2_t.java b/backend/src/main/java/com/realnet/Rpt_builder2/Entity/Rpt_builder2_t.java index 8e8c614..1a16b4a 100644 --- a/backend/src/main/java/com/realnet/Rpt_builder2/Entity/Rpt_builder2_t.java +++ b/backend/src/main/java/com/realnet/Rpt_builder2/Entity/Rpt_builder2_t.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import javax.persistence.CascadeType; +import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; @@ -17,21 +18,23 @@ import lombok.Data; @Entity @Data -public class Rpt_builder2_t { +public class Rpt_builder2_t { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - + private String reportName; private String description; private Boolean active; private Boolean isSql; - + @Column(name = "sure_connect_id") + private Integer sureConnectId; + private String sureconnect_name; + @JsonManagedReference - @OneToMany(cascade = CascadeType.ALL,mappedBy = "rpt_builder2_t") + @OneToMany(cascade = CascadeType.ALL, mappedBy = "rpt_builder2_t") private List Rpt_builder2_lines = new ArrayList<>(); - } \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/Rpt_builder2/Services/Rpt_builder2_Service.java b/backend/src/main/java/com/realnet/Rpt_builder2/Services/Rpt_builder2_Service.java index 2731b1f..a9307ef 100644 --- a/backend/src/main/java/com/realnet/Rpt_builder2/Services/Rpt_builder2_Service.java +++ b/backend/src/main/java/com/realnet/Rpt_builder2/Services/Rpt_builder2_Service.java @@ -1,6 +1,8 @@ package com.realnet.Rpt_builder2.Services; import com.realnet.Rpt_builder2.Repository.Rpt_builder2_Repository; +import com.realnet.SureConnect.Entities.Sure_Connect; +import com.realnet.SureConnect.Service.SureService; import com.realnet.Rpt_builder2.Entity.Rpt_builder2_t; import java.util.List; @@ -12,7 +14,17 @@ public class Rpt_builder2_Service { @Autowired private Rpt_builder2_Repository Repository; + @Autowired + private SureService sureService; + public Rpt_builder2_t Savedata(Rpt_builder2_t data) { + + if (data.getSureConnectId() != null) { + + Sure_Connect sureconnect = sureService.getbyid(data.getSureConnectId()); + + data.setSureconnect_name(sureconnect.getConnection_name()); + } return Repository.save(data); } @@ -36,13 +48,20 @@ public class Rpt_builder2_Service { // old.setAdhoc_param_html(data.getAdhoc_param_html()); // old.setColumn_str(data.getColumn_str()); // old.setSql_str(data.getSql_str()); - + old.setReportName(data.getReportName()); old.setDescription(data.getDescription()); old.setActive(data.getActive()); + + if (data.getSureConnectId() != null) { + + Sure_Connect sureconnect = sureService.getbyid(data.getSureConnectId()); + + old.setSureConnectId(data.getSureConnectId()); + old.setSureconnect_name(sureconnect.getConnection_name()); + } // old.setFolderName(data.getFolderName()); - - + final Rpt_builder2_t test = Repository.save(old); return test; } diff --git a/backend/src/main/java/com/realnet/Rpt_builder2_lines/Controllers/Rpt_builder2_lines_Controller.java b/backend/src/main/java/com/realnet/Rpt_builder2_lines/Controllers/Rpt_builder2_lines_Controller.java index 0f97e9a..b1ed35f 100644 --- a/backend/src/main/java/com/realnet/Rpt_builder2_lines/Controllers/Rpt_builder2_lines_Controller.java +++ b/backend/src/main/java/com/realnet/Rpt_builder2_lines/Controllers/Rpt_builder2_lines_Controller.java @@ -1,16 +1,25 @@ package com.realnet.Rpt_builder2_lines.Controllers; -import java.util.ArrayList; + +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import com.realnet.Rpt_builder2_lines.Entity.Rpt_builder2_lines_t; @@ -23,7 +32,7 @@ public class Rpt_builder2_lines_Controller { @Autowired private Rpt_builder2_lines_Service Service; - + @Autowired private Rpt_builder2_lines_Repository line_repo; @@ -57,7 +66,7 @@ public class Rpt_builder2_lines_Controller { Rpt_builder2_lines_t update = Service.update(data, id); return update; } - + @PutMapping("/update/{id}") public ResponseEntity updateById(@PathVariable Long id, @RequestBody Rpt_builder2_lines_t outgoing_data) { Rpt_builder2_lines_t line = line_repo.findById(id).get(); @@ -66,63 +75,99 @@ public class Rpt_builder2_lines_Controller { Rpt_builder2_lines_t save = line_repo.save(line); return new ResponseEntity<>(save, HttpStatus.ACCEPTED); } - + @GetMapping("/geturlkeybyurl") public Set getKeysById(@RequestParam String url) { - ResponseEntity response = GET(url); - System.out.println("Response status code: " + response.getStatusCodeValue()); - // Check the class of the response body - if (response.getBody() != null) { - System.out.println("Response body class: " + response.getBody().getClass()); - } - // Check if the response body is an ArrayList - if (response.getBody() instanceof ArrayList) { - ArrayList responseBody = (ArrayList) response.getBody(); - // Assuming you want to extract keys from elements inside the ArrayList, - // you might need to iterate through the list and extract keys from each element. - Set keys = new HashSet<>(); - for (Object element : responseBody) { - if (element instanceof LinkedHashMap) { - LinkedHashMap elementMap = (LinkedHashMap) element; - keys.addAll(elementMap.keySet()); - } - } - return keys; - } else { - return null; - } + ResponseEntity response = GET(url); + System.out.println("Response status code: " + response.getStatusCodeValue()); + + Object body = response.getBody(); + if (body == null) { + System.out.println("Response body is null"); + return Collections.emptySet(); + } + + System.out.println("Response body class: " + body.getClass()); + + Set keys = new HashSet<>(); + + // βœ… Case 1: Response is a JSON array β†’ List of LinkedHashMap + if (body instanceof List) { + List list = (List) body; + for (Object element : list) { + if (element instanceof Map) { + keys.addAll( + ((Map) element).keySet().stream().map(Object::toString).collect(Collectors.toSet())); + } + } + } + // βœ… Case 2: Response is a single JSON object β†’ LinkedHashMap + else if (body instanceof Map) { + keys.addAll(((Map) body).keySet().stream().map(Object::toString).collect(Collectors.toSet())); + } + // βœ… Case 3: Response is some other type (String, primitive, etc.) + else { + System.out.println("Unhandled response type: " + body.getClass()); + } + + return keys; } +// @GetMapping("/geturlkeybyurl") +// public Set getKeysById(@RequestParam String url) { +// ResponseEntity response = GET(url); +// System.out.println("Response status code: " + response.getStatusCodeValue()); +// // Check the class of the response body +// if (response.getBody() != null) { +// System.out.println("Response body class: " + response.getBody().getClass()); +// } +// // Check if the response body is an ArrayList +// if (response.getBody() instanceof ArrayList) { +// ArrayList responseBody = (ArrayList) response.getBody(); +// // Assuming you want to extract keys from elements inside the ArrayList, +// // you might need to iterate through the list and extract keys from each element. +// Set keys = new HashSet<>(); +// for (Object element : responseBody) { +// if (element instanceof LinkedHashMap) { +// LinkedHashMap elementMap = (LinkedHashMap) element; +// keys.addAll(elementMap.keySet()); +// } +// } +// return keys; +// } else { +// return null; +// } +// } + public ResponseEntity GET(String get) { org.springframework.web.client.RestTemplate restTemplate = new org.springframework.web.client.RestTemplate(); ResponseEntity u = restTemplate.getForEntity(get, Object.class); return u; } - + @GetMapping("/fetch_data_url") - public ResponseEntity fetchURL(@RequestParam String url) { - try { - // Create an instance of RestTemplate - RestTemplate restTemplate = new RestTemplate(); + public ResponseEntity fetchURL(@RequestParam String url) { + try { + // Create an instance of RestTemplate + RestTemplate restTemplate = new RestTemplate(); - // Send an HTTP GET request to the provided URL and retrieve the response body as a String - String responseBody = restTemplate.getForObject(url, String.class); + // Send an HTTP GET request to the provided URL and retrieve the response body + // as a String + String responseBody = restTemplate.getForObject(url, String.class); - // Create a Map to hold the URL and body data - Map responseMap = new HashMap<>(); - responseMap.put("url", url); - responseMap.put("body", responseBody); + // Create a Map to hold the URL and body data + Map responseMap = new HashMap<>(); + responseMap.put("url", url); + responseMap.put("body", responseBody); + + // Return the response map as JSON + return ResponseEntity.ok(responseMap); + } catch (Exception e) { + // Handle exceptions, such as invalid URLs or network errors + Map errorMap = new HashMap<>(); + errorMap.put("error", "Failed to fetch URL: " + e.getMessage()); + return ResponseEntity.badRequest().body(errorMap); + } + } - // Return the response map as JSON - return ResponseEntity.ok(responseMap); - } catch (Exception e) { - // Handle exceptions, such as invalid URLs or network errors - Map errorMap = new HashMap<>(); - errorMap.put("error", "Failed to fetch URL: " + e.getMessage()); - return ResponseEntity.badRequest().body(errorMap); - } - } - - - } \ No newline at end of file diff --git a/backend/src/main/java/com/realnet/rb/entity/Rn_report_builder.java b/backend/src/main/java/com/realnet/rb/entity/Rn_report_builder.java index b45eb1d..fd6c3e0 100644 --- a/backend/src/main/java/com/realnet/rb/entity/Rn_report_builder.java +++ b/backend/src/main/java/com/realnet/rb/entity/Rn_report_builder.java @@ -24,14 +24,6 @@ public class Rn_report_builder extends Rn_Who_Columns { @Column(name = "ID") private int id; -// -// @ManyToOne(fetch = FetchType.LAZY,cascade=CascadeType.ALL) -// @JoinColumn(name = "MODULE_ID",insertable = false, updatable = false) -// @JsonBackReference -// private Rn_Module_Setup module; -// -// - @Column(name = "REPORT_NAME") private String report_name; diff --git a/backend/src/main/java/com/realnet/rb/service/Rn_rb_tables_serviceImpl.java b/backend/src/main/java/com/realnet/rb/service/Rn_rb_tables_serviceImpl.java index f7632ed..e6d8505 100644 --- a/backend/src/main/java/com/realnet/rb/service/Rn_rb_tables_serviceImpl.java +++ b/backend/src/main/java/com/realnet/rb/service/Rn_rb_tables_serviceImpl.java @@ -246,9 +246,7 @@ public class Rn_rb_tables_serviceImpl implements Rn_rb_tables_service { @Override public List getColumnAliasList2(String tableNames) { - String url = null; - String userName = null; - String password = null; + List list = new ArrayList<>(); String[] tableArray = tableNames.split(","); diff --git a/backend/src/main/java/com/realnet/rb/service/Rn_report_builder_serviceIpml.java b/backend/src/main/java/com/realnet/rb/service/Rn_report_builder_serviceIpml.java index 7d8c0ef..db1cb4b 100644 --- a/backend/src/main/java/com/realnet/rb/service/Rn_report_builder_serviceIpml.java +++ b/backend/src/main/java/com/realnet/rb/service/Rn_report_builder_serviceIpml.java @@ -10,16 +10,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.sql.DataSource; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; -import com.fasterxml.jackson.core.JsonProcessingException; import com.realnet.CredentialDatabase.Service.SurevaultService; import com.realnet.exceptions.ResourceNotFoundException; import com.realnet.rb.entity.Rn_Rb_Where_Param; @@ -36,55 +32,54 @@ import com.realnet.users.service1.AppUserServiceImpl; import com.realnet.utils.Constant; @Service -public class Rn_report_builder_serviceIpml implements Rn_report_builder_service{ +public class Rn_report_builder_serviceIpml implements Rn_report_builder_service { @Autowired private Rn_report_builder_repository rn_report_builder_repository; - + @Autowired private AppUserServiceImpl userService; - + @Autowired private Rn_column_Repository columnRepo; - + @Autowired private Rn_tables_Repository tableRepo; - + @Autowired private Rn_rb_where_param_repository whereRepo; - -// @Value("${spring.datasource.username}") -// private String userName; -// -// @Value("${spring.datasource.password}") -// private String password; -// -// @Value("${spring.datasource.url}") -// private String url; - + + @Value("${spring.datasource.username}") + private String userName; + + @Value("${spring.datasource.password}") + private String password; + + @Value("${spring.datasource.url}") + private String url; + @Autowired private SurevaultService databaseCredentialsService; - @Override public Page getAll(Pageable page) { return rn_report_builder_repository.findAll(page); } - + @Override public Rn_report_builder save(Rn_report_builder rn_report_builder) { Rn_report_builder savereport = rn_report_builder_repository.save(rn_report_builder); return savereport; } - + @Override - public Rn_report_builder getById(int id) { + public Rn_report_builder getById(int id) { Rn_report_builder bcf_extractor = rn_report_builder_repository.findById(id) .orElseThrow(() -> new ResourceNotFoundException(Constant.NOT_FOUND_EXCEPTION + " :" + id)); return bcf_extractor; } - + @Override - public List getByReportId(int id) { + public List getByReportId(int id) { List bcf_extractor = rn_report_builder_repository.getByReportId(id); return bcf_extractor; } @@ -93,14 +88,13 @@ public class Rn_report_builder_serviceIpml implements Rn_report_builder_service{ public boolean saveReport(Rn_reportDTO report, int moduleId) { AppUser user = userService.getLoggedInUser(); Long userId = user.getUserId(); - //Long accountId = user.getSys_account().getId(); + // Long accountId = user.getSys_account().getId(); String report_name = report.getReport_name(); String desc = report.getDescription(); - String tags=report.getReport_tags(); - - - Rn_report_builder reportBuilder=new Rn_report_builder(); + String tags = report.getReport_tags(); + + Rn_report_builder reportBuilder = new Rn_report_builder(); reportBuilder.setReport_name(report_name); reportBuilder.setDescription(desc); reportBuilder.setReport_tags(tags); @@ -113,141 +107,129 @@ public class Rn_report_builder_serviceIpml implements Rn_report_builder_service{ public Rn_report_builder saveReport(Rn_report_builder report, int moduleId) { AppUser user = userService.getLoggedInUser(); Long userId = user.getUserId(); - //Long accountId = user.getSys_account().getId(); + // Long accountId = user.getSys_account().getId(); String report_name = report.getReport_name(); String desc = report.getDescription(); - String tags=report.getReport_tags(); - - - Rn_report_builder reportBuilder=new Rn_report_builder(); + String tags = report.getReport_tags(); + + Rn_report_builder reportBuilder = new Rn_report_builder(); reportBuilder.setReport_name(report_name); reportBuilder.setDescription(desc); reportBuilder.setReport_tags(tags); reportBuilder.setModule_id(moduleId); reportBuilder.setIs_build("N"); reportBuilder.setIs_updated("N"); - - - return save(reportBuilder); + + return save(reportBuilder); } - - + @Override public Rn_report_builder updateById(int id, String date_string) { - + Rn_report_builder rn_builder = rn_report_builder_repository.findById(id) .orElseThrow(() -> new ResourceNotFoundException(Constant.NOT_FOUND_EXCEPTION + " :" + id)); rn_builder.setDate_string(date_string); - + final Rn_report_builder updatedProject = rn_report_builder_repository.save(rn_builder); return updatedProject; } - + @Override public Rn_report_builder updateByIdAdhoc(int id, String param_string) { - + Rn_report_builder rn_builder = rn_report_builder_repository.findById(id) .orElseThrow(() -> new ResourceNotFoundException(Constant.NOT_FOUND_EXCEPTION + " :" + id)); rn_builder.setAdd_param_string(param_string); - + final Rn_report_builder updatedProject = rn_report_builder_repository.save(rn_builder); return updatedProject; } - + @Override public Rn_report_builder updateByIdGridHeaders(int id, String param_string) { - + Rn_report_builder rn_builder = rn_report_builder_repository.findById(id) .orElseThrow(() -> new ResourceNotFoundException(Constant.NOT_FOUND_EXCEPTION + " :" + id)); rn_builder.setGrid_headers(param_string); rn_builder.setGrid_values(param_string); - + final Rn_report_builder updatedProject = rn_report_builder_repository.save(rn_builder); return updatedProject; } - + @Override public Rn_report_builder updateByIdQuery(int id, Rn_report_builder param_string) { - + Rn_report_builder rn_builder = rn_report_builder_repository.findById(id) .orElseThrow(() -> new ResourceNotFoundException(Constant.NOT_FOUND_EXCEPTION + " :" + id)); - - StringBuilder sb=new StringBuilder(); - StringBuilder sb2=new StringBuilder(); - StringBuilder sb3=new StringBuilder(); - - //get tables - List tableList=tableRepo.getTablesByReport(id); + + StringBuilder sb = new StringBuilder(); + StringBuilder sb2 = new StringBuilder(); + StringBuilder sb3 = new StringBuilder(); + + // get tables + List tableList = tableRepo.getTablesByReport(id); for (int i = 0; i < tableList.size(); i++) { - String table_name=tableList.get(i).getTable_name(); - String table_allias_name=tableList.get(i).getTable_allias_name(); - if(i ==0) - { - sb.append(table_name+" "+table_allias_name); - }else{ - sb.append(","+table_name+" "+table_allias_name); - } + String table_name = tableList.get(i).getTable_name(); + String table_allias_name = tableList.get(i).getTable_allias_name(); + if (i == 0) { + sb.append(table_name + " " + table_allias_name); + } else { + sb.append("," + table_name + " " + table_allias_name); + } } - - //get columns - List columnList=columnRepo.getColumnByReport(id); + + // get columns + List columnList = columnRepo.getColumnByReport(id); for (int i = 0; i < columnList.size(); i++) { - String column_name=columnList.get(i).getColumn_name(); - String table_allies_name=columnList.get(i).getTable_allies_name(); - String column_allias_name=columnList.get(i).getColumn_allias_name(); - String asc_desc=columnList.get(i).getAsc_desc(); - String function=columnList.get(i).getFunctions(); - if(function != null && !function.isEmpty()) - { - sb2.append(function+"("+table_allies_name+"."+column_name+")"+column_allias_name); + String column_name = columnList.get(i).getColumn_name(); + String table_allies_name = columnList.get(i).getTable_allies_name(); + String column_allias_name = columnList.get(i).getColumn_allias_name(); + String asc_desc = columnList.get(i).getAsc_desc(); + String function = columnList.get(i).getFunctions(); + if (function != null && !function.isEmpty()) { + sb2.append(function + "(" + table_allies_name + "." + column_name + ")" + column_allias_name); - }else - { - if(i ==0) - { - sb2.append(column_name+" "+column_allias_name); - }else{ - sb2.append(","+column_name+" "+column_allias_name); - } + } else { + if (i == 0) { + sb2.append(column_name + " " + column_allias_name); + } else { + sb2.append("," + column_name + " " + column_allias_name); } - - } - //where condition - List whereList=whereRepo.getWhereByReport(id); - for (int i = 0; i < whereList.size(); i++) { - String explecity=whereList.get(i).getExplecity(); - String table_column_name1=whereList.get(i).getWhere_coloumn1_tbl_alias_name(); - String column1=whereList.get(i).getWhere_coloumn(); - String condition=whereList.get(i).getWhere_condition(); - String switch_control=whereList.get(i).getSwitch_control(); - String table_column_name2=whereList.get(i).getWhere_coloumn2_tbl_alias_name(); - String column2=whereList.get(i).getWhere_coloumn2_tbl_alias_name(); - - if(explecity!=null) { - sb3.append(" and "+table_column_name1+"."+column1+"="+table_column_name2+"."+column2); - } - else { - sb3.append(""); - } - - - } - - String sql6="select "+sb2+" from "+sb+" where 1=1 "+sb3+""; + } + + } + // where condition + List whereList = whereRepo.getWhereByReport(id); + for (int i = 0; i < whereList.size(); i++) { + String explecity = whereList.get(i).getExplecity(); + String table_column_name1 = whereList.get(i).getWhere_coloumn1_tbl_alias_name(); + String column1 = whereList.get(i).getWhere_coloumn(); + String condition = whereList.get(i).getWhere_condition(); + String switch_control = whereList.get(i).getSwitch_control(); + String table_column_name2 = whereList.get(i).getWhere_coloumn2_tbl_alias_name(); + String column2 = whereList.get(i).getWhere_coloumn2_tbl_alias_name(); + + if (explecity != null) { + sb3.append(" and " + table_column_name1 + "." + column1 + "=" + table_column_name2 + "." + column2); + } else { + sb3.append(""); + } + + } + + String sql6 = "select " + sb2 + " from " + sb + " where 1=1 " + sb3 + ""; + + // sb.append("select book.author author_1,gb_records_t.name name_2,book.title + // title_3 from book book,gb_records_t gb_records_t where 1=1 "); + // String master_query=sb.toString(); - - - //sb.append("select book.author author_1,gb_records_t.name name_2,book.title title_3 from book book,gb_records_t gb_records_t where 1=1 "); - //String master_query=sb.toString(); - rn_builder.setMaster_select(sql6); final Rn_report_builder updatedProject = rn_report_builder_repository.save(rn_builder); return updatedProject; } - - - + // @Override // public List getQueryData(String query) { // String sql_query = query; @@ -273,53 +255,51 @@ public class Rn_report_builder_serviceIpml implements Rn_report_builder_service{ // } // return list; // } - - + @Override public List> getQueryData(String query) { String sql_query = query; - List> list = new ArrayList<>(); - String url=null; - String userName=null; - String password=null; - try { - userName = databaseCredentialsService.getSurevaultCredentials("databaseuserName"); - url = databaseCredentialsService.getSurevaultCredentials("databaseUrl"); - password = databaseCredentialsService.getSurevaultCredentials("databasePassword"); - - } catch (JsonProcessingException e) { - // TODO Auto-generated catch block + List> list = new ArrayList<>(); +// String url=null; +// String userName=null; +// String password=null; +// try { +// userName = databaseCredentialsService.getSurevaultCredentials("databaseuserName"); +// url = databaseCredentialsService.getSurevaultCredentials("databaseUrl"); +// password = databaseCredentialsService.getSurevaultCredentials("databasePassword"); +// +// } catch (JsonProcessingException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } + try ( + + // JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + + Connection con = DriverManager.getConnection(url, userName, password); + + // Statement stmt = con.createStatement(); + PreparedStatement ps = con.prepareStatement(query);) { + ResultSet rs = ps.executeQuery(); + java.sql.ResultSetMetaData rsm = rs.getMetaData(); + System.out.println("matadata::" + rsm); + int rscount = rsm.getColumnCount(); + while (rs.next()) { + Map row = new HashMap<>(); + for (int i = 1; i <= rscount; i++) { + // String data= rs.getString(i); + // list.add(data); + String colName = rsm.getColumnName(i); + Object colVal = rs.getObject(i); + row.put(colName, colVal); + } + list.add(row); + + } + + } catch (SQLException e) { e.printStackTrace(); } - try ( - - // JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); - - - Connection con =DriverManager.getConnection(url,userName,password); - - //Statement stmt = con.createStatement(); - PreparedStatement ps = con.prepareStatement(query);) { - ResultSet rs = ps.executeQuery(); - java.sql.ResultSetMetaData rsm = rs.getMetaData(); - System.out.println("matadata::"+rsm); - int rscount = rsm.getColumnCount(); - while (rs.next()) { - Map row = new HashMap<>(); - for (int i = 1; i <= rscount; i++) { - //String data= rs.getString(i); - //list.add(data); - String colName = rsm.getColumnName(i); - Object colVal = rs.getObject(i); - row.put(colName,colVal); - } - list.add(row); - - } - - } catch (SQLException e) { - e.printStackTrace(); - } return list; } @@ -327,15 +307,14 @@ public class Rn_report_builder_serviceIpml implements Rn_report_builder_service{ public Rn_report_builder saveReportservice(Rn_report_builder report, int moduleId) { AppUser user = userService.getLoggedInUser(); Long userId = user.getUserId(); - //Long accountId = user.getSys_account().getId(); + // Long accountId = user.getSys_account().getId(); String report_name = report.getReport_name(); String desc = report.getDescription(); - String tags=report.getReport_tags(); - String servicename=report.getServicename(); - - - Rn_report_builder reportBuilder=new Rn_report_builder(); + String tags = report.getReport_tags(); + String servicename = report.getServicename(); + + Rn_report_builder reportBuilder = new Rn_report_builder(); reportBuilder.setReport_name(report_name); reportBuilder.setDescription(desc); reportBuilder.setReport_tags(tags); @@ -343,44 +322,32 @@ public class Rn_report_builder_serviceIpml implements Rn_report_builder_service{ reportBuilder.setIs_build("N"); reportBuilder.setIs_updated("N"); reportBuilder.setServicename(servicename); - - - return save(reportBuilder); + + return save(reportBuilder); } @Override - public Rn_report_builder updatereport(int reportid,Rn_report_builder reportdata) { - + public Rn_report_builder updatereport(int reportid, Rn_report_builder reportdata) { + Rn_report_builder oldrn_builder = rn_report_builder_repository.findById(reportid) .orElseThrow(() -> new ResourceNotFoundException(Constant.NOT_FOUND_EXCEPTION + " :" + reportid)); - + oldrn_builder.setReport_name(reportdata.getReport_name()); oldrn_builder.setReport_tags(reportdata.getReport_tags()); oldrn_builder.setDescription(reportdata.getDescription()); oldrn_builder.setServicename(reportdata.getServicename()); - - + Rn_report_builder newreport = rn_report_builder_repository.save(oldrn_builder); - - + return newreport; - - + } - - - - - - - - - + // @Override // public List getQueryData(String query) { // List queryResult = rn_report_builder_repository.getQueryData(query) // .orElseThrow(() -> new ResourceNotFoundException(Constant.NOT_FOUND_EXCEPTION + " :" + id)); // return queryResult; // } - + } diff --git a/backend/src/main/java/com/realnet/scheduler/Entity/JobEntity.java b/backend/src/main/java/com/realnet/scheduler/Entity/JobEntity.java new file mode 100644 index 0000000..2010351 --- /dev/null +++ b/backend/src/main/java/com/realnet/scheduler/Entity/JobEntity.java @@ -0,0 +1,79 @@ +package com.realnet.scheduler.Entity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import lombok.Data; + +@Data +@Entity +@Table(name = "scheduled_jobs") +public class JobEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; // Auto increment + + private String name; + + private String cronExpression; + + private String status; // RUNNING / PAUSED / STOPPED + + @Column(length = 2000) + private String description; + private String jobType; // EMAIL / REPORT / SYNC etc. + + private Integer lakeid; + + public JobEntity() { + } + + public JobEntity(String name, String cronExpression, String status, String description) { + this.name = name; + this.cronExpression = cronExpression; + this.status = status; + this.description = description; + } + + // Getters & Setters + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCronExpression() { + return cronExpression; + } + + public void setCronExpression(String cronExpression) { + this.cronExpression = cronExpression; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/backend/src/main/java/com/realnet/scheduler/Repository/JobRepository.java b/backend/src/main/java/com/realnet/scheduler/Repository/JobRepository.java new file mode 100644 index 0000000..c54e79e --- /dev/null +++ b/backend/src/main/java/com/realnet/scheduler/Repository/JobRepository.java @@ -0,0 +1,15 @@ +package com.realnet.scheduler.Repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import com.realnet.scheduler.Entity.JobEntity; + +@Repository +public interface JobRepository extends JpaRepository { + + @Query(value = "select * from scheduled_jobs where lakeid=?1", nativeQuery = true) + + JobEntity getBylakeId(Integer lakeId); +} diff --git a/backend/src/main/java/com/realnet/scheduler/controller/JobController.java b/backend/src/main/java/com/realnet/scheduler/controller/JobController.java new file mode 100644 index 0000000..c8c91df --- /dev/null +++ b/backend/src/main/java/com/realnet/scheduler/controller/JobController.java @@ -0,0 +1,64 @@ +package com.realnet.scheduler.controller; + +import java.util.List; + +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.realnet.fnd.response.EntityResponse; +import com.realnet.scheduler.Entity.JobEntity; +import com.realnet.scheduler.Repository.JobRepository; +import com.realnet.scheduler.services.SmartSchedulerService; + +@RestController +@RequestMapping("/scheduler") +public class JobController { + + private final SmartSchedulerService scheduler; + private final JobRepository jobRepository; + + public JobController(SmartSchedulerService scheduler, JobRepository jobRepository) { + this.scheduler = scheduler; + this.jobRepository = jobRepository; + } + + @PostMapping("/create") + public JobEntity createJob(@RequestBody JobEntity body) { + + return scheduler.createAndStartJob(body); + } + + @PostMapping("/pause/{id}") + public EntityResponse pauseJob(@PathVariable Long id) { + scheduler.pauseJob(id); + EntityResponse entityResponse = new EntityResponse("Job paused: " + id); + return entityResponse; + } + + @PostMapping("/resume/{id}") + public EntityResponse resumeJob(@PathVariable Long id) { + scheduler.resumeJob(id); + return new EntityResponse("Job resumed: " + id); + } + + @DeleteMapping("/stop/{id}") + public EntityResponse stopJob(@PathVariable Long id) { + scheduler.stopJob(id); + return new EntityResponse("Job stopped: " + id); + } + + @GetMapping("/list") + public List listJobs() { + return jobRepository.findAll(); + } + + @GetMapping("/lake/{lakeId}") + public JobEntity listJobs(@PathVariable Integer lakeId) { + return jobRepository.getBylakeId(lakeId); + } +} diff --git a/backend/src/main/java/com/realnet/scheduler/services/SmartSchedulerService.java b/backend/src/main/java/com/realnet/scheduler/services/SmartSchedulerService.java new file mode 100644 index 0000000..e06e1bf --- /dev/null +++ b/backend/src/main/java/com/realnet/scheduler/services/SmartSchedulerService.java @@ -0,0 +1,249 @@ +package com.realnet.scheduler.services; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledFuture; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +//import org.springframework.scheduling.support.CronExpression; +import org.springframework.scheduling.support.CronTrigger; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.realnet.DataLake.Entity.Data_lake; +import com.realnet.DataLake.Services.DataLakeActionService; +import com.realnet.DataLake.Services.Data_lakeService; +import com.realnet.scheduler.Entity.JobEntity; +import com.realnet.scheduler.Repository.JobRepository; + +@Service +public class SmartSchedulerService { + + private final TaskScheduler scheduler; + private final Map> runningTasks = new ConcurrentHashMap<>(); + + @Autowired + private JobRepository jobRepository; + + public SmartSchedulerService() { + ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); + taskScheduler.setPoolSize(5); + taskScheduler.initialize(); + this.scheduler = taskScheduler; + } + + // πŸ”Ή Load jobs from DB on startup +// @PostConstruct +// public void init() { +// System.out.println("πŸ” Loading jobs from DB..."); +// jobRepository.findAll().forEach(job -> { +// if ("RUNNING".equalsIgnoreCase(job.getStatus()) && job.getCronExpression() != null) { +// startJob(job); +// } +// }); +// } + +// @EventListener(ApplicationReadyEvent.class) +// public void onApplicationReady() { +// System.out.println("πŸš€ Application started! Loading jobs from DB..."); +// jobRepository.findAll().forEach(job -> { +// if ("RUNNING".equalsIgnoreCase(job.getStatus()) && job.getCronExpression() != null) { +// startJob(job); +// } +// }); +// } + + // πŸ”Ή Start or schedule a job + public JobEntity createAndStartJob(JobEntity job) { + + JobEntity existingjob = jobRepository.getBylakeId(job.getLakeid()); + if (existingjob != null) { + job = existingjob; + if (existingjob.getCronExpression() == null) { + Integer lakeid = job.getLakeid(); + Data_lake data_lake = lakeService.getdetailsbyId(lakeid); + String cron_job = data_lake.getCron_job(); + job.setCronExpression(cron_job); +// job = jobRepository.save(job); + } + + } else { + Integer lakeid = job.getLakeid(); + Data_lake data_lake = lakeService.getdetailsbyId(lakeid); + String cron_job = data_lake.getCron_job(); + job.setCronExpression(cron_job); +// job = jobRepository.save(job); + } + +// JobEntity job = new JobEntity(name, cron, "RUNNING", description); + job.setStatus("RUNNING"); + job = jobRepository.save(job); // Auto-generated ID + startJob(job); + return job; + } + +// private void startJob(JobEntity job) { +// ScheduledFuture future = scheduler.schedule( +// +// () -> System.out.println( +// "Running job: " + job.getName() + " [" + job.getId() + "] at " + java.time.LocalDateTime.now()), +// new CronTrigger(job.getCronExpression())); +// runningTasks.put(job.getId(), future); +// System.out.println("βœ… Job started: " + job.getName() + " | ID: " + job.getId()); +// } + + // πŸ”Ή Pause job + public void pauseJob(Long id) { + ScheduledFuture future = runningTasks.get(id); + if (future != null) { + future.cancel(true); + runningTasks.remove(id); + } + jobRepository.findById(id).ifPresent(job -> { + job.setStatus("PAUSED"); + jobRepository.save(job); + System.out.println("⏸️ Job paused: " + job.getName()); + }); + } + + // πŸ”Ή Resume job + public void resumeJob(Long id) { + jobRepository.findById(id).ifPresent(job -> { + if ("PAUSED".equalsIgnoreCase(job.getStatus())) { + startJob(job); + job.setStatus("RUNNING"); + jobRepository.save(job); + System.out.println("▢️ Job resumed: " + job.getName()); + } + }); + } + + // πŸ”Ή Stop job completely + public void stopJob(Long id) { + pauseJob(id); + jobRepository.findById(id).ifPresent(job -> { + job.setStatus("STOPPED"); + jobRepository.save(job); + System.out.println("πŸ›‘ Job stopped: " + job.getName()); + }); + } + + public void listJobs() { + jobRepository.findAll().forEach(job -> System.out.println( + job.getId() + " | " + job.getName() + " | " + job.getStatus() + " | " + job.getCronExpression())); + } + + private void startJob(JobEntity job) { + // Step 1: Validate cron expression before scheduling +// if (job.getCronExpression() == null || !isValidCron(job.getCronExpression())) { +// System.err.println("❌ Invalid or missing cron expression for job: " + job.getName()); +// job.setStatus("FAILED"); +// jobRepository.save(job); +// return; +// } + Runnable task; + + switch (job.getJobType()) { + case "DATALAKE": + task = () -> { + try { + setdatalake(job); + } catch (JsonProcessingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + }; + break; + case "EMAIL": + task = () -> sendEmailJob(job); + break; + case "REPORT": + task = () -> generateReport(job); + break; + case "SYNC": + task = () -> { + try { + setdatalake(job); + } catch (JsonProcessingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + }; + break; + default: + task = () -> System.out.println("βš™οΈ Running generic job: " + job.getName()); + } + +// ScheduledFuture future = scheduler.schedule(task, new CronTrigger(job.getCronExpression())); +// runningTasks.put(job.getId(), future); +// System.out.println("βœ… Job started: " + job.getName() + " | ID: " + job.getId()); + + try { + ScheduledFuture future = scheduler.schedule(task, new CronTrigger(job.getCronExpression())); + runningTasks.put(job.getId(), future); + System.out.println("βœ… Job started: " + job.getName() + " | ID: " + job.getId()); + job.setStatus("RUNNING"); + jobRepository.save(job); + } catch (Exception e) { + System.err.println("🚨 Failed to schedule job: " + job.getName()); + e.printStackTrace(); + job.setStatus("FAILED"); + jobRepository.save(job); + } + } + +// private boolean isValidCron(String cron) { +// try { +// CronExpression.parse(cron); +// return true; +// } catch (Exception e) { +// return false; +// } +// } + + @Autowired + private Data_lakeService lakeService; + + @Autowired + private DataLakeActionService lakeActionService; + + // Sample tasks + private void setdatalake(JobEntity job) throws JsonProcessingException { + + Integer lakeid = job.getLakeid(); +// Data_lake data_lake = lakeService.getdetailsbyId(lakeid); +// String cron_job = data_lake.getCron_job(); +// job.setCronExpression(cron_job); +// jobRepository.save(job); + Data_lake update = lakeActionService.applyCalculation(lakeid); + + System.out.println("πŸ“§ Start Data Lake..." + update.getName() + " [" + job.getName() + "]"); + // your email service logic here + } + + private void sendEmailJob(JobEntity job) { + System.out.println("πŸ“§ Sending emails... [" + job.getName() + "]"); + // your email service logic here + } + + private void generateReport(JobEntity job) { + System.out.println("πŸ“Š Generating report... [" + job.getName() + "]"); + // call report service, save file, etc. + } + + private void syncData(JobEntity job) { + System.out.println("πŸ”„ Syncing data from API... [" + job.getName() + "]"); + // hit API, update DB, etc. + } + + public JobEntity getByLakeId(Integer lakeId) { + JobEntity job = jobRepository.getBylakeId(lakeId); + return job; + + } + +}