7 Commits

47 changed files with 2016 additions and 2169 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,8 @@ package com.sgs;
import com.sgs.graphql.activitySubUnit.domain.ActivitySubUnit; import com.sgs.graphql.activitySubUnit.domain.ActivitySubUnit;
import com.sgs.graphql.activitySubUnit.service.ActivitySubUnitService; import com.sgs.graphql.activitySubUnit.service.ActivitySubUnitService;
import com.sgs.graphql.area.domain.Area;
import com.sgs.graphql.area.service.AreaService;
import com.sgs.graphql.city.domain.City; import com.sgs.graphql.city.domain.City;
import com.sgs.graphql.city.repo.CityRepo; import com.sgs.graphql.city.repo.CityRepo;
import com.sgs.graphql.city.service.CityService; import com.sgs.graphql.city.service.CityService;
@@ -73,6 +75,7 @@ public class SgsApplication implements CommandLineRunner {
private final PermissionService permissionService; private final PermissionService permissionService;
private final RoleService roleService; private final RoleService roleService;
private final RoleRepo roleRepo; private final RoleRepo roleRepo;
private final AreaService areaService;
private final NeighborhoodRepo neighborhoodRepo; private final NeighborhoodRepo neighborhoodRepo;
private final NeighborhoodService neighborhoodService; private final NeighborhoodService neighborhoodService;
private final CityService cityService; private final CityService cityService;
@@ -118,7 +121,7 @@ public class SgsApplication implements CommandLineRunner {
@Autowired @Autowired
public SgsApplication(RoleService roleService, PermissionService permissionService, RoleRepo roleRepo, public SgsApplication(RoleService roleService, PermissionService permissionService, RoleRepo roleRepo,
NeighborhoodRepo neighborhoodRepo, NeighborhoodService neighborhoodService, CityService cityService, AreaService areaService, NeighborhoodRepo neighborhoodRepo, NeighborhoodService neighborhoodService, CityService cityService,
CityRepo cityRepo, DistrictRepo districtRepo, DistrictService districtService, CountryRepo countryRepo, CityRepo cityRepo, DistrictRepo districtRepo, DistrictService districtService, CountryRepo countryRepo,
CountryService countryService, OrganizationService organizationService, UserService userService, CountryService countryService, OrganizationService organizationService, UserService userService,
PasswordEncoder passwordEncoder, SectorService sectorService, SubSectorService subSectorService, PasswordEncoder passwordEncoder, SectorService sectorService, SubSectorService subSectorService,
@@ -133,6 +136,7 @@ public class SgsApplication implements CommandLineRunner {
this.roleService = roleService; this.roleService = roleService;
this.permissionService = permissionService; this.permissionService = permissionService;
this.roleRepo = roleRepo; this.roleRepo = roleRepo;
this.areaService = areaService;
this.neighborhoodRepo = neighborhoodRepo; this.neighborhoodRepo = neighborhoodRepo;
this.neighborhoodService = neighborhoodService; this.neighborhoodService = neighborhoodService;
this.cityService = cityService; this.cityService = cityService;
@@ -426,6 +430,10 @@ public class SgsApplication implements CommandLineRunner {
data_center_read.setTag(PermissionName.DATA_CENTER_READ); data_center_read.setTag(PermissionName.DATA_CENTER_READ);
data_center_read.setDescription(PermissionDescription.DATA_CENTER_READ); data_center_read.setDescription(PermissionDescription.DATA_CENTER_READ);
Permission paginate_datacenters_get = new Permission();
paginate_datacenters_get.setTag(PermissionName.PAGINATE_DATACENTERS_GET);
paginate_datacenters_get.setDescription(PermissionDescription.PAGINATE_DATACENTERS_GET);
permissionService.saveAll(List.of( permissionService.saveAll(List.of(
show_graphics, activities_get, paginate_user_histories, activity_sub_units_get, sub_sectors_get, show_graphics, activities_get, paginate_user_histories, activity_sub_units_get, sub_sectors_get,
sectors_get, deleted_items, undelete_items, user_create, user_update, user_delete, paginate_users_get, sectors_get, deleted_items, undelete_items, user_create, user_update, user_delete, paginate_users_get,
@@ -442,7 +450,7 @@ public class SgsApplication implements CommandLineRunner {
question_create, question_delete, question_update, paginate_questions_get, question_create, question_delete, question_update, paginate_questions_get,
published_survey_create, surveys_get, paginate_surveys_get, published_survey_create, surveys_get, paginate_surveys_get,
survey_add, survey_delete, survey_update, settings_access, data_center_create, data_center_delete, survey_add, survey_delete, survey_update, settings_access, data_center_create, data_center_delete,
data_center_update, data_center_read)); data_center_update, data_center_read, paginate_datacenters_get));
} }
public void createDefaultRole() { public void createDefaultRole() {
@@ -771,6 +779,27 @@ public class SgsApplication implements CommandLineRunner {
mailInfoService.save(mailInfo); mailInfoService.save(mailInfo);
} }
public void ensureMissingPermissions() {
// Check if paginate_datacenters_get permission exists
Optional<Permission> datacenterPermission = permissionService.findByTag("paginate_datacenters_get");
if (!datacenterPermission.isPresent()) {
// Create the missing permission
Permission paginate_datacenters_get = new Permission();
paginate_datacenters_get.setTag(PermissionName.PAGINATE_DATACENTERS_GET);
paginate_datacenters_get.setDescription(PermissionDescription.PAGINATE_DATACENTERS_GET);
permissionService.save(paginate_datacenters_get);
}
// Ensure SUPER_ADMIN has all permissions
Optional<Role> superAdminRole = roleRepo.findByTag("SUPER_ADMIN");
if (superAdminRole.isPresent()) {
Role role = superAdminRole.get();
List<Permission> allPermissions = permissionService.findAll();
role.setPermissions(allPermissions);
roleService.save(role);
}
}
@Override @Override
public void run(String... args) throws Exception { public void run(String... args) throws Exception {
if (mailInfoService.findAll().isEmpty()) { if (mailInfoService.findAll().isEmpty()) {
@@ -816,6 +845,8 @@ public class SgsApplication implements CommandLineRunner {
if (roleService.findAll().isEmpty()) { if (roleService.findAll().isEmpty()) {
createDefaultRole(); createDefaultRole();
} }
// Ensure all permissions are created and assigned to SUPER_ADMIN
ensureMissingPermissions();
if (organizationService.findAll().isEmpty()) { if (organizationService.findAll().isEmpty()) {
createDefaultOrganization(); createDefaultOrganization();
} }
@@ -834,18 +865,34 @@ public class SgsApplication implements CommandLineRunner {
if (neighborhoodService.findAll().isEmpty()) { if (neighborhoodService.findAll().isEmpty()) {
createNeighborhoodsFromJson(); createNeighborhoodsFromJson();
} }
// Add new permission if it doesn't exist if (!cityService.findAll().isEmpty()) {
// [Remove Later] createDefaultArea();
if (permissionService.findAll().stream().noneMatch(p -> PermissionName.SETTINGS_ACCESS.equals(p.getTag()))) { }
Permission settingsAccess = new Permission(); }
settingsAccess.setTag(PermissionName.SETTINGS_ACCESS);
settingsAccess.setDescription(PermissionDescription.SETTINGS_ACCESS); void createDefaultArea() {
settingsAccess.setDefault_permission(false); // Check if default area already exists
settingsAccess.setDeleted(false); List<Area> existingAreas = areaService.findAll();
permissionService.save(settingsAccess); boolean defaultAreaExists = existingAreas.stream()
.anyMatch(area -> "Turkiye".equals(area.getTag()) && area.isDefaultArea());
if (!defaultAreaExists) {
Area defaultArea = new Area();
defaultArea.setTag("Turkiye");
defaultArea.setDefaultArea(true);
defaultArea.setDeleted(false);
// Get all cities to add to the default area
List<City> allCities = cityService.findAll();
defaultArea.setCities(allCities);
// Get the Turkey country to add to the default area
List<Country> countries = countryService.findAll();
if (!countries.isEmpty()) {
defaultArea.setCountries(countries);
}
areaService.save(defaultArea);
} }
Permission settings_access = new Permission();
settings_access.setTag(PermissionName.SETTINGS_ACCESS);
settings_access.setDescription(PermissionDescription.SETTINGS_ACCESS);
} }
} }

View File

@@ -2,11 +2,10 @@ package com.sgs.graphql.dataCenter.domain;
import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference; import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.sgs.graphql.area.domain.Area; import com.sgs.graphql.area.domain.Area;
import com.sgs.graphql.city.domain.City;
import com.sgs.graphql.sector.domain.Sector; import com.sgs.graphql.sector.domain.Sector;
import com.sgs.graphql.subSector.domain.SubSector; import com.sgs.graphql.subSector.domain.SubSector;
import com.sgs.graphql.emissionSource.domain.EmissionSource;
import com.sgs.graphql.emissionScope.domain.EmissionScope; import com.sgs.graphql.emissionScope.domain.EmissionScope;
import com.sgs.graphql.consuptionUnit.domain.ConsuptionUnit;
import com.sgs.graphql.activitySubUnit.domain.ActivitySubUnit; import com.sgs.graphql.activitySubUnit.domain.ActivitySubUnit;
import com.sgs.lib.dao.domain.BaseDomain; import com.sgs.lib.dao.domain.BaseDomain;
@@ -14,6 +13,8 @@ import javax.persistence.*;
import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption; import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.ArrayList;
@@ -29,14 +30,14 @@ public class DataCenter extends BaseDomain {
private Integer number; private Integer number;
private Area area; private Area area;
private City city;
private List<Project> projects = new ArrayList<>(); private List<PhysicalMachine> physicalMachines = new ArrayList<>();
private List<DataCenterEmissionSource> dataCenterEmissionSources = new ArrayList<>();
private Sector sector; private Sector sector;
private SubSector subSector; private SubSector subSector;
private EmissionSource emissionSource;
private EmissionScope emissionScope; private EmissionScope emissionScope;
private Double consuptionAmount; private Double consuptionAmount;
private ConsuptionUnit consuptionUnit;
private ActivitySubUnit activitySubUnit; private ActivitySubUnit activitySubUnit;
// New attributes // New attributes
@@ -63,12 +64,23 @@ public class DataCenter extends BaseDomain {
@OneToMany(mappedBy = "dataCenter", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER) @OneToMany(mappedBy = "dataCenter", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
@JsonManagedReference @JsonManagedReference
public List<Project> getProjects() { public List<PhysicalMachine> getPhysicalMachines() {
return projects; return physicalMachines;
} }
public void setProjects(List<Project> projects) { public void setPhysicalMachines(List<PhysicalMachine> physicalMachines) {
this.projects = projects; this.physicalMachines = physicalMachines;
}
@OneToMany(mappedBy = "dataCenter", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
@Fetch(FetchMode.SUBSELECT)
@JsonManagedReference
public List<DataCenterEmissionSource> getDataCenterEmissionSources() {
return dataCenterEmissionSources;
}
public void setDataCenterEmissionSources(List<DataCenterEmissionSource> dataCenterEmissionSources) {
this.dataCenterEmissionSources = dataCenterEmissionSources;
} }
public void setExternalId(Integer externalId) { public void setExternalId(Integer externalId) {
@@ -114,16 +126,6 @@ public class DataCenter extends BaseDomain {
this.consuptionAmount = consuptionAmount; this.consuptionAmount = consuptionAmount;
} }
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "consuption_unit_id")
public ConsuptionUnit getConsuptionUnit() {
return consuptionUnit;
}
public void setConsuptionUnit(ConsuptionUnit consuptionUnit) {
this.consuptionUnit = consuptionUnit;
}
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "area_id") @JoinColumn(name = "area_id")
public Area getArea() { public Area getArea() {
@@ -134,6 +136,16 @@ public class DataCenter extends BaseDomain {
this.area = area; this.area = area;
} }
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "city_id")
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "sub_sector_id") @JoinColumn(name = "sub_sector_id")
public SubSector getSubSector() { public SubSector getSubSector() {
@@ -144,16 +156,6 @@ public class DataCenter extends BaseDomain {
this.subSector = subSector; this.subSector = subSector;
} }
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "emission_source_id")
public EmissionSource getEmissionSource() {
return emissionSource;
}
public void setEmissionSource(EmissionSource emissionSource) {
this.emissionSource = emissionSource;
}
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "activity_sub_unit_id") @JoinColumn(name = "activity_sub_unit_id")
public ActivitySubUnit getActivitySubUnit() { public ActivitySubUnit getActivitySubUnit() {

View File

@@ -0,0 +1,68 @@
package com.sgs.graphql.dataCenter.domain;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.sgs.graphql.emissionSource.domain.EmissionSource;
import com.sgs.graphql.consuptionUnit.domain.ConsuptionUnit;
import com.sgs.lib.dao.domain.BaseDomain;
import javax.persistence.*;
@Entity
@Table(name = "data_center_emission_source")
public class DataCenterEmissionSource extends BaseDomain {
private DataCenter dataCenter;
private EmissionSource emissionSource;
private ConsuptionUnit consuptionUnit;
private Boolean isDefault = false; // To mark which one is the default emission source
private Double percentage; // Percentage allocation for this emission source (optional)
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "data_center_id", nullable = false)
@JsonBackReference
public DataCenter getDataCenter() {
return dataCenter;
}
public void setDataCenter(DataCenter dataCenter) {
this.dataCenter = dataCenter;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "emission_source_id", nullable = false)
public EmissionSource getEmissionSource() {
return emissionSource;
}
public void setEmissionSource(EmissionSource emissionSource) {
this.emissionSource = emissionSource;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "consuption_unit_id", nullable = false)
public ConsuptionUnit getConsuptionUnit() {
return consuptionUnit;
}
public void setConsuptionUnit(ConsuptionUnit consuptionUnit) {
this.consuptionUnit = consuptionUnit;
}
@Column(name = "is_default")
public Boolean getIsDefault() {
return isDefault;
}
public void setIsDefault(Boolean isDefault) {
this.isDefault = isDefault;
}
@Column(name = "percentage")
public Double getPercentage() {
return percentage;
}
public void setPercentage(Double percentage) {
this.percentage = percentage;
}
}

View File

@@ -14,9 +14,10 @@ public class PhysicalMachine extends BaseDomain {
private String name; private String name;
private String ip; private String ip;
private String tag; private String tag;
private String cloudSystem;
private Double power; private Double power;
private List<VM> vms = new ArrayList<>(); private List<VM> vms = new ArrayList<>();
private Project project; private DataCenter dataCenter;
@Column(name = "name") @Column(name = "name")
public String getName() { public String getName() {
@@ -45,6 +46,15 @@ public class PhysicalMachine extends BaseDomain {
this.tag = tag; this.tag = tag;
} }
@Column(name = "cloud_system")
public String getCloudSystem() {
return cloudSystem;
}
public void setCloudSystem(String cloudSystem) {
this.cloudSystem = cloudSystem;
}
@Column(name = "power") @Column(name = "power")
public Double getPower() { public Double getPower() {
return power; return power;
@@ -65,13 +75,13 @@ public class PhysicalMachine extends BaseDomain {
} }
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "project_id") @JoinColumn(name = "data_center_id")
@JsonBackReference @JsonBackReference
public Project getProject() { public DataCenter getDataCenter() {
return project; return dataCenter;
} }
public void setProject(Project project) { public void setDataCenter(DataCenter dataCenter) {
this.project = project; this.dataCenter = dataCenter;
} }
} }

View File

@@ -1,50 +0,0 @@
package com.sgs.graphql.dataCenter.domain;
import java.util.List;
import javax.persistence.*;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.sgs.lib.dao.domain.BaseDomain;
@Entity
@Table(name = "project")
public class Project extends BaseDomain{
private String name;
private List<PhysicalMachine> physicalMachines;
@OneToMany(mappedBy = "project", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
@JsonManagedReference
public List<PhysicalMachine> getPhysicalMachines() {
return physicalMachines;
}
public void setPhysicalMachines(List<PhysicalMachine> physicalMachines) {
this.physicalMachines = physicalMachines;
}
// This creates a foreign key in the `project` table
private DataCenter dataCenter;
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToOne
@JoinColumn(name = "data_center_id")
@JsonBackReference
public DataCenter getDataCenter() {
return dataCenter;
}
public void setDataCenter(DataCenter dataCenter) {
this.dataCenter = dataCenter;
}
}

View File

@@ -23,6 +23,7 @@ public class VM extends BaseDomain {
private String host; private String host;
private String flavorName; private String flavorName;
private String tag; private String tag;
private String project; // UUID of the project this VM belongs to
private String emissionSourceData; // JSON string to store emission source map private String emissionSourceData; // JSON string to store emission source map
private Config config; private Config config;
private PhysicalMachine physicalMachine; private PhysicalMachine physicalMachine;
@@ -100,6 +101,15 @@ public class VM extends BaseDomain {
this.tag = tag; this.tag = tag;
} }
@Column(name = "project")
public String getProject() {
return project;
}
public void setProject(String project) {
this.project = project;
}
@Column(name = "ip") @Column(name = "ip")
public String getIp() { public String getIp() {
return ip; return ip;

View File

@@ -17,7 +17,9 @@ public class DataCenterDto {
private Integer externalId; private Integer externalId;
private Integer number; private Integer number;
private AreaDto area; private AreaDto area;
private Map<String, ProjectDto> projects;
@JsonProperty("physical_machines")
private Map<String, PhysicalMachineDto> physicalMachine;
// Emission calculation fields // Emission calculation fields
private SectorDto sector; private SectorDto sector;
@@ -68,12 +70,12 @@ public class DataCenterDto {
this.area = area; this.area = area;
} }
public Map<String, ProjectDto> getProjects() { public Map<String, PhysicalMachineDto> getPhysicalMachine() {
return projects; return physicalMachine;
} }
public void setProjects(Map<String, ProjectDto> projects) { public void setPhysicalMachine(Map<String, PhysicalMachineDto> physicalMachine) {
this.projects = projects; this.physicalMachine = physicalMachine;
} }
public SectorDto getSector() { public SectorDto getSector() {

View File

@@ -0,0 +1,50 @@
package com.sgs.graphql.dataCenter.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
public class DataCenterEmissionSourceDto {
@JsonProperty("emission_source_id")
private String emissionSourceId;
@JsonProperty("consuption_unit_id")
private String consuptionUnitId;
@JsonProperty("is_default")
private Boolean isDefault = false;
@JsonProperty("percentage")
private Double percentage;
public String getEmissionSourceId() {
return emissionSourceId;
}
public void setEmissionSourceId(String emissionSourceId) {
this.emissionSourceId = emissionSourceId;
}
public String getConsuptionUnitId() {
return consuptionUnitId;
}
public void setConsuptionUnitId(String consuptionUnitId) {
this.consuptionUnitId = consuptionUnitId;
}
public Boolean getIsDefault() {
return isDefault;
}
public void setIsDefault(Boolean isDefault) {
this.isDefault = isDefault;
}
public Double getPercentage() {
return percentage;
}
public void setPercentage(Double percentage) {
this.percentage = percentage;
}
}

View File

@@ -1,24 +0,0 @@
package com.sgs.graphql.dataCenter.dto;
import java.util.Map;
public class MainOptimizationSpaceDto {
private Map<String, VMDto> vms;
private Map<String, PhysicalMachineDto> pms;
public Map<String, VMDto> getVms() {
return vms;
}
public void setVms(Map<String, VMDto> vms) {
this.vms = vms;
}
public Map<String, PhysicalMachineDto> getPms() {
return pms;
}
public void setPms(Map<String, PhysicalMachineDto> pms) {
this.pms = pms;
}
}

View File

@@ -2,6 +2,7 @@ package com.sgs.graphql.dataCenter.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List; import java.util.List;
import java.util.Map;
public class PhysicalMachineDto { public class PhysicalMachineDto {
@JsonProperty("name") @JsonProperty("name")
@@ -10,11 +11,17 @@ public class PhysicalMachineDto {
@JsonProperty("tag") @JsonProperty("tag")
private String tag; private String tag;
@JsonProperty("cloud_system")
private String cloudSystem;
@JsonProperty("power") @JsonProperty("power")
private double power; private double power;
@JsonProperty("confg") // Note: keeping the typo from JSON @JsonProperty("confg") // Note: keeping the typo from JSON
private List<Object> confg; private List<Object> confg;
@JsonProperty("vms")
private Map<String, VMDto> vms;
private String ip; // IP address from the message key private String ip; // IP address from the message key
@@ -34,6 +41,14 @@ public class PhysicalMachineDto {
this.tag = tag; this.tag = tag;
} }
public String getCloudSystem() {
return cloudSystem;
}
public void setCloudSystem(String cloudSystem) {
this.cloudSystem = cloudSystem;
}
public double getPower() { public double getPower() {
return power; return power;
} }
@@ -57,4 +72,12 @@ public class PhysicalMachineDto {
public void setIp(String ip) { public void setIp(String ip) {
this.ip = ip; this.ip = ip;
} }
public Map<String, VMDto> getVms() {
return vms;
}
public void setVms(Map<String, VMDto> vms) {
this.vms = vms;
}
} }

View File

@@ -1,61 +0,0 @@
package com.sgs.graphql.dataCenter.dto;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
public class ProjectDto {
@JsonProperty("main_optimization_space")
private MainOptimizationSpaceDto mainOptimizationSpace;
@JsonProperty("sub_optimization_space")
private SubOptimizationSpaceDto subOptimizationSpace;
// Legacy field - kept for backward compatibility with older message formats
@JsonProperty("physical_machines")
private List<PhysicalMachineDto> physicalMachines;
// These fields are derived from the map key and entity relationships, not from the message
private String id; // This will be set from the map key
private String name; // This will be derived or set separately
public MainOptimizationSpaceDto getMainOptimizationSpace() {
return mainOptimizationSpace;
}
public void setMainOptimizationSpace(MainOptimizationSpaceDto mainOptimizationSpace) {
this.mainOptimizationSpace = mainOptimizationSpace;
}
public SubOptimizationSpaceDto getSubOptimizationSpace() {
return subOptimizationSpace;
}
public void setSubOptimizationSpace(SubOptimizationSpaceDto subOptimizationSpace) {
this.subOptimizationSpace = subOptimizationSpace;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<PhysicalMachineDto> getPhysicalMachines() {
return physicalMachines;
}
public void setPhysicalMachines(List<PhysicalMachineDto> physicalMachines) {
this.physicalMachines = physicalMachines;
}
}

View File

@@ -1,24 +0,0 @@
package com.sgs.graphql.dataCenter.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* DTO for sub_optimization_space in the message format.
* Currently appears to be empty in the message structure.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class SubOptimizationSpaceDto {
// Currently empty based on the message format
// Can be extended if needed in the future
// Add a placeholder field to make Jackson happy
private boolean isEmpty = true;
public boolean isEmpty() {
return isEmpty;
}
public void setEmpty(boolean empty) {
this.isEmpty = empty;
}
}

View File

@@ -26,6 +26,9 @@ public class VMDto {
@JsonProperty("tag") @JsonProperty("tag")
private String tag; private String tag;
@JsonProperty("project")
private String project;
@JsonProperty("confg") // Note: keeping the typo from JSON @JsonProperty("confg") // Note: keeping the typo from JSON
private List<Object> confg; private List<Object> confg;
@@ -101,6 +104,14 @@ public class VMDto {
this.tag = tag; this.tag = tag;
} }
public String getProject() {
return project;
}
public void setProject(String project) {
this.project = project;
}
public List<Object> getConfg() { public List<Object> getConfg() {
return confg; return confg;
} }

View File

@@ -5,6 +5,7 @@ import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Min; import javax.validation.constraints.Min;
import java.util.UUID; import java.util.UUID;
import java.util.List;
public class DataCenterCreateInput extends BaseCreateInput { public class DataCenterCreateInput extends BaseCreateInput {
@NotBlank(message = "Data center adı gereklidir") @NotBlank(message = "Data center adı gereklidir")
@@ -15,17 +16,21 @@ public class DataCenterCreateInput extends BaseCreateInput {
private Integer number; private Integer number;
private Double consuptionAmount; private Double consuptionAmount;
@NotNull(message = "Alan ID gereklidir")
private UUID areaId; private UUID areaId;
private UUID cityId;
@NotNull(message = "Sektör ID gereklidir") @NotNull(message = "Sektör ID gereklidir")
private UUID sectorId; private UUID sectorId;
private UUID subSectorId; private UUID subSectorId;
private UUID emissionSourceId;
private UUID emissionScopeId; private UUID emissionScopeId;
private UUID consuptionUnitId;
private UUID activitySubUnitId; private UUID activitySubUnitId;
// Multiple emission sources support - each with exactly one unit
private List<DataCenterEmissionSourceInput> dataCenterEmissionSources;
// New attributes // New attributes
private String ayposURL; private String ayposURL;
private String address; private String address;
@@ -48,24 +53,24 @@ public class DataCenterCreateInput extends BaseCreateInput {
public UUID getAreaId() { return areaId; } public UUID getAreaId() { return areaId; }
public void setAreaId(UUID areaId) { this.areaId = areaId; } public void setAreaId(UUID areaId) { this.areaId = areaId; }
public UUID getCityId() { return cityId; }
public void setCityId(UUID cityId) { this.cityId = cityId; }
public UUID getSectorId() { return sectorId; } public UUID getSectorId() { return sectorId; }
public void setSectorId(UUID sectorId) { this.sectorId = sectorId; } public void setSectorId(UUID sectorId) { this.sectorId = sectorId; }
public UUID getSubSectorId() { return subSectorId; } public UUID getSubSectorId() { return subSectorId; }
public void setSubSectorId(UUID subSectorId) { this.subSectorId = subSectorId; } public void setSubSectorId(UUID subSectorId) { this.subSectorId = subSectorId; }
public UUID getEmissionSourceId() { return emissionSourceId; }
public void setEmissionSourceId(UUID emissionSourceId) { this.emissionSourceId = emissionSourceId; }
public UUID getEmissionScopeId() { return emissionScopeId; } public UUID getEmissionScopeId() { return emissionScopeId; }
public void setEmissionScopeId(UUID emissionScopeId) { this.emissionScopeId = emissionScopeId; } public void setEmissionScopeId(UUID emissionScopeId) { this.emissionScopeId = emissionScopeId; }
public UUID getConsuptionUnitId() { return consuptionUnitId; }
public void setConsuptionUnitId(UUID consuptionUnitId) { this.consuptionUnitId = consuptionUnitId; }
public UUID getActivitySubUnitId() { return activitySubUnitId; } public UUID getActivitySubUnitId() { return activitySubUnitId; }
public void setActivitySubUnitId(UUID activitySubUnitId) { this.activitySubUnitId = activitySubUnitId; } public void setActivitySubUnitId(UUID activitySubUnitId) { this.activitySubUnitId = activitySubUnitId; }
public List<DataCenterEmissionSourceInput> getDataCenterEmissionSources() { return dataCenterEmissionSources; }
public void setDataCenterEmissionSources(List<DataCenterEmissionSourceInput> dataCenterEmissionSources) { this.dataCenterEmissionSources = dataCenterEmissionSources; }
// New attribute getters and setters // New attribute getters and setters
public String getAyposURL() { return ayposURL; } public String getAyposURL() { return ayposURL; }
public void setAyposURL(String ayposURL) { this.ayposURL = ayposURL; } public void setAyposURL(String ayposURL) { this.ayposURL = ayposURL; }

View File

@@ -0,0 +1,40 @@
package com.sgs.graphql.dataCenter.mutation.input;
public class DataCenterEmissionSourceInput {
private String emissionSourceId;
private String consuptionUnitId;
private Boolean isDefault = false;
private Double percentage;
public String getEmissionSourceId() {
return emissionSourceId;
}
public void setEmissionSourceId(String emissionSourceId) {
this.emissionSourceId = emissionSourceId;
}
public String getConsuptionUnitId() {
return consuptionUnitId;
}
public void setConsuptionUnitId(String consuptionUnitId) {
this.consuptionUnitId = consuptionUnitId;
}
public Boolean getIsDefault() {
return isDefault;
}
public void setIsDefault(Boolean isDefault) {
this.isDefault = isDefault;
}
public Double getPercentage() {
return percentage;
}
public void setPercentage(Double percentage) {
this.percentage = percentage;
}
}

View File

@@ -1,7 +1,7 @@
package com.sgs.graphql.dataCenter.mutation.input; package com.sgs.graphql.dataCenter.mutation.input;
import com.sgs.lib.dao.mutation.input.BaseUpdateInput; import com.sgs.lib.dao.mutation.input.BaseUpdateInput;
import javax.validation.constraints.NotNull; import java.util.List;
import java.util.UUID; import java.util.UUID;
public class DataCenterUpdateInput extends BaseUpdateInput { public class DataCenterUpdateInput extends BaseUpdateInput {
@@ -11,14 +11,15 @@ public class DataCenterUpdateInput extends BaseUpdateInput {
private Double consuptionAmount; private Double consuptionAmount;
private UUID areaId; private UUID areaId;
@NotNull(message = "Sektör ID gereklidir") private UUID cityId;
private UUID sectorId; private UUID sectorId;
private UUID subSectorId; private UUID subSectorId;
private UUID emissionSourceId;
private UUID emissionScopeId; private UUID emissionScopeId;
private UUID consuptionUnitId;
private UUID activitySubUnitId; private UUID activitySubUnitId;
// Multiple emission sources with units
private List<DataCenterEmissionSourceInput> dataCenterEmissionSources;
// New attributes // New attributes
private String ayposURL; private String ayposURL;
private String address; private String address;
@@ -41,24 +42,28 @@ public class DataCenterUpdateInput extends BaseUpdateInput {
public UUID getAreaId() { return areaId; } public UUID getAreaId() { return areaId; }
public void setAreaId(UUID areaId) { this.areaId = areaId; } public void setAreaId(UUID areaId) { this.areaId = areaId; }
public UUID getCityId() { return cityId; }
public void setCityId(UUID cityId) { this.cityId = cityId; }
public UUID getSectorId() { return sectorId; } public UUID getSectorId() { return sectorId; }
public void setSectorId(UUID sectorId) { this.sectorId = sectorId; } public void setSectorId(UUID sectorId) { this.sectorId = sectorId; }
public UUID getSubSectorId() { return subSectorId; } public UUID getSubSectorId() { return subSectorId; }
public void setSubSectorId(UUID subSectorId) { this.subSectorId = subSectorId; } public void setSubSectorId(UUID subSectorId) { this.subSectorId = subSectorId; }
public UUID getEmissionSourceId() { return emissionSourceId; }
public void setEmissionSourceId(UUID emissionSourceId) { this.emissionSourceId = emissionSourceId; }
public UUID getEmissionScopeId() { return emissionScopeId; } public UUID getEmissionScopeId() { return emissionScopeId; }
public void setEmissionScopeId(UUID emissionScopeId) { this.emissionScopeId = emissionScopeId; } public void setEmissionScopeId(UUID emissionScopeId) { this.emissionScopeId = emissionScopeId; }
public UUID getConsuptionUnitId() { return consuptionUnitId; }
public void setConsuptionUnitId(UUID consuptionUnitId) { this.consuptionUnitId = consuptionUnitId; }
public UUID getActivitySubUnitId() { return activitySubUnitId; } public UUID getActivitySubUnitId() { return activitySubUnitId; }
public void setActivitySubUnitId(UUID activitySubUnitId) { this.activitySubUnitId = activitySubUnitId; } public void setActivitySubUnitId(UUID activitySubUnitId) { this.activitySubUnitId = activitySubUnitId; }
public List<DataCenterEmissionSourceInput> getDataCenterEmissionSources() {
return dataCenterEmissionSources;
}
public void setDataCenterEmissionSources(List<DataCenterEmissionSourceInput> dataCenterEmissionSources) {
this.dataCenterEmissionSources = dataCenterEmissionSources;
}
// New attribute getters and setters // New attribute getters and setters
public String getAyposURL() { return ayposURL; } public String getAyposURL() { return ayposURL; }
public void setAyposURL(String ayposURL) { this.ayposURL = ayposURL; } public void setAyposURL(String ayposURL) { this.ayposURL = ayposURL; }

View File

@@ -1,8 +1,10 @@
package com.sgs.graphql.dataCenter.mutation.mapper; package com.sgs.graphql.dataCenter.mutation.mapper;
import com.sgs.graphql.dataCenter.domain.DataCenter; import com.sgs.graphql.dataCenter.domain.DataCenter;
import com.sgs.graphql.dataCenter.domain.DataCenterEmissionSource;
import com.sgs.graphql.dataCenter.mutation.input.DataCenterCreateInput; import com.sgs.graphql.dataCenter.mutation.input.DataCenterCreateInput;
import com.sgs.graphql.dataCenter.mutation.input.DataCenterUpdateInput; import com.sgs.graphql.dataCenter.mutation.input.DataCenterUpdateInput;
import com.sgs.graphql.dataCenter.mutation.input.DataCenterEmissionSourceInput;
import com.sgs.graphql.area.service.AreaService; import com.sgs.graphql.area.service.AreaService;
import com.sgs.graphql.sector.service.SectorService; import com.sgs.graphql.sector.service.SectorService;
import com.sgs.graphql.subSector.service.SubSectorService; import com.sgs.graphql.subSector.service.SubSectorService;
@@ -10,9 +12,13 @@ import com.sgs.graphql.emissionSource.service.EmissionSourceService;
import com.sgs.graphql.emissionScope.service.EmissionScopeService; import com.sgs.graphql.emissionScope.service.EmissionScopeService;
import com.sgs.graphql.consuptionUnit.service.ConsuptionUnitService; import com.sgs.graphql.consuptionUnit.service.ConsuptionUnitService;
import com.sgs.graphql.activitySubUnit.service.ActivitySubUnitService; import com.sgs.graphql.activitySubUnit.service.ActivitySubUnitService;
import com.sgs.graphql.city.service.CityService;
import com.sgs.lib.dao.mutation.mapper.BaseCreateUpdateMapper; import com.sgs.lib.dao.mutation.mapper.BaseCreateUpdateMapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List;
import java.util.ArrayList;
import java.util.UUID;
@Component @Component
public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCenterCreateInput, DataCenterUpdateInput> { public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCenterCreateInput, DataCenterUpdateInput> {
@@ -24,12 +30,13 @@ public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCen
private final EmissionScopeService emissionScopeService; private final EmissionScopeService emissionScopeService;
private final ConsuptionUnitService consuptionUnitService; private final ConsuptionUnitService consuptionUnitService;
private final ActivitySubUnitService activitySubUnitService; private final ActivitySubUnitService activitySubUnitService;
private final CityService cityService;
@Autowired @Autowired
public DataCenterMapper(AreaService areaService, SectorService sectorService, public DataCenterMapper(AreaService areaService, SectorService sectorService,
SubSectorService subSectorService, EmissionSourceService emissionSourceService, SubSectorService subSectorService, EmissionSourceService emissionSourceService,
EmissionScopeService emissionScopeService, ConsuptionUnitService consuptionUnitService, EmissionScopeService emissionScopeService, ConsuptionUnitService consuptionUnitService,
ActivitySubUnitService activitySubUnitService) { ActivitySubUnitService activitySubUnitService, CityService cityService) {
this.areaService = areaService; this.areaService = areaService;
this.sectorService = sectorService; this.sectorService = sectorService;
this.subSectorService = subSectorService; this.subSectorService = subSectorService;
@@ -37,6 +44,7 @@ public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCen
this.emissionScopeService = emissionScopeService; this.emissionScopeService = emissionScopeService;
this.consuptionUnitService = consuptionUnitService; this.consuptionUnitService = consuptionUnitService;
this.activitySubUnitService = activitySubUnitService; this.activitySubUnitService = activitySubUnitService;
this.cityService = cityService;
} }
@Override @Override
@@ -53,6 +61,9 @@ public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCen
if (input.getAreaId() != null) { if (input.getAreaId() != null) {
entity.setArea(areaService.findById(input.getAreaId()).orElse(null)); entity.setArea(areaService.findById(input.getAreaId()).orElse(null));
} }
if (input.getCityId() != null) {
entity.setCity(cityService.findById(input.getCityId()).orElse(null));
}
if (input.getSectorId() != null) { if (input.getSectorId() != null) {
entity.setSector(sectorService.findById(input.getSectorId()).orElse(null)); entity.setSector(sectorService.findById(input.getSectorId()).orElse(null));
@@ -62,18 +73,10 @@ public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCen
entity.setSubSector(subSectorService.findById(input.getSubSectorId()).orElse(null)); entity.setSubSector(subSectorService.findById(input.getSubSectorId()).orElse(null));
} }
if (input.getEmissionSourceId() != null) {
entity.setEmissionSource(emissionSourceService.findById(input.getEmissionSourceId()).orElse(null));
}
if (input.getEmissionScopeId() != null) { if (input.getEmissionScopeId() != null) {
entity.setEmissionScope(emissionScopeService.findById(input.getEmissionScopeId()).orElse(null)); entity.setEmissionScope(emissionScopeService.findById(input.getEmissionScopeId()).orElse(null));
} }
if (input.getConsuptionUnitId() != null) {
entity.setConsuptionUnit(consuptionUnitService.findById(input.getConsuptionUnitId()).orElse(null));
}
if (input.getActivitySubUnitId() != null) { if (input.getActivitySubUnitId() != null) {
entity.setActivitySubUnit(activitySubUnitService.findById(input.getActivitySubUnitId()).orElse(null)); entity.setActivitySubUnit(activitySubUnitService.findById(input.getActivitySubUnitId()).orElse(null));
} }
@@ -84,6 +87,34 @@ public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCen
entity.setLatitude(input.getLatitude()); entity.setLatitude(input.getLatitude());
entity.setLongitude(input.getLongitude()); entity.setLongitude(input.getLongitude());
// Handle multiple emission sources if provided
if (input.getDataCenterEmissionSources() != null && !input.getDataCenterEmissionSources().isEmpty()) {
List<DataCenterEmissionSource> dataCenterEmissionSources = new ArrayList<>();
for (DataCenterEmissionSourceInput emissionSourceInput : input.getDataCenterEmissionSources()) {
DataCenterEmissionSource dcEmissionSource = new DataCenterEmissionSource();
dcEmissionSource.setDataCenter(entity);
// Set EmissionSource
if (emissionSourceInput.getEmissionSourceId() != null) {
dcEmissionSource.setEmissionSource(emissionSourceService.findById(UUID.fromString(emissionSourceInput.getEmissionSourceId())).orElse(null));
}
// Set ConsuptionUnit
if (emissionSourceInput.getConsuptionUnitId() != null) {
dcEmissionSource.setConsuptionUnit(consuptionUnitService.findById(UUID.fromString(emissionSourceInput.getConsuptionUnitId())).orElse(null));
}
// Set optional fields
dcEmissionSource.setIsDefault(emissionSourceInput.getIsDefault() != null ? emissionSourceInput.getIsDefault() : false);
dcEmissionSource.setPercentage(emissionSourceInput.getPercentage());
dataCenterEmissionSources.add(dcEmissionSource);
}
entity.setDataCenterEmissionSources(dataCenterEmissionSources);
}
return entity; return entity;
} }
@@ -110,6 +141,9 @@ public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCen
if (input.getAreaId() != null) { if (input.getAreaId() != null) {
entity.setArea(areaService.findById(input.getAreaId()).orElse(null)); entity.setArea(areaService.findById(input.getAreaId()).orElse(null));
} }
if (input.getCityId() != null) {
entity.setCity(cityService.findById(input.getCityId()).orElse(null));
}
if (input.getSectorId() != null) { if (input.getSectorId() != null) {
entity.setSector(sectorService.findById(input.getSectorId()).orElse(null)); entity.setSector(sectorService.findById(input.getSectorId()).orElse(null));
@@ -119,22 +153,40 @@ public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCen
entity.setSubSector(subSectorService.findById(input.getSubSectorId()).orElse(null)); entity.setSubSector(subSectorService.findById(input.getSubSectorId()).orElse(null));
} }
if (input.getEmissionSourceId() != null) {
entity.setEmissionSource(emissionSourceService.findById(input.getEmissionSourceId()).orElse(null));
}
if (input.getEmissionScopeId() != null) { if (input.getEmissionScopeId() != null) {
entity.setEmissionScope(emissionScopeService.findById(input.getEmissionScopeId()).orElse(null)); entity.setEmissionScope(emissionScopeService.findById(input.getEmissionScopeId()).orElse(null));
} }
if (input.getConsuptionUnitId() != null) {
entity.setConsuptionUnit(consuptionUnitService.findById(input.getConsuptionUnitId()).orElse(null));
}
if (input.getActivitySubUnitId() != null) { if (input.getActivitySubUnitId() != null) {
entity.setActivitySubUnit(activitySubUnitService.findById(input.getActivitySubUnitId()).orElse(null)); entity.setActivitySubUnit(activitySubUnitService.findById(input.getActivitySubUnitId()).orElse(null));
} }
// Handle multiple emission sources update if provided
if (input.getDataCenterEmissionSources() != null) {
// Clear existing emission sources and add new ones
entity.getDataCenterEmissionSources().clear();
List<DataCenterEmissionSource> dataCenterEmissionSources = new ArrayList<>();
for (DataCenterEmissionSourceInput emissionSourceInput : input.getDataCenterEmissionSources()) {
DataCenterEmissionSource dcEmissionSource = new DataCenterEmissionSource();
dcEmissionSource.setDataCenter(entity);
if (emissionSourceInput.getEmissionSourceId() != null) {
dcEmissionSource.setEmissionSource(emissionSourceService.findById(UUID.fromString(emissionSourceInput.getEmissionSourceId())).orElse(null));
}
if (emissionSourceInput.getConsuptionUnitId() != null) {
dcEmissionSource.setConsuptionUnit(consuptionUnitService.findById(UUID.fromString(emissionSourceInput.getConsuptionUnitId())).orElse(null));
}
dcEmissionSource.setIsDefault(emissionSourceInput.getIsDefault() != null ? emissionSourceInput.getIsDefault() : false);
dcEmissionSource.setPercentage(emissionSourceInput.getPercentage());
dataCenterEmissionSources.add(dcEmissionSource);
}
entity.setDataCenterEmissionSources(dataCenterEmissionSources);
}
// New attributes (partial update - only if provided) // New attributes (partial update - only if provided)
if (input.getAyposURL() != null) { if (input.getAyposURL() != null) {
entity.setAyposURL(input.getAyposURL()); entity.setAyposURL(input.getAyposURL());

View File

@@ -15,8 +15,10 @@ import org.springframework.stereotype.Component;
import com.sgs.graphql.auth.service.AuthorizationService; import com.sgs.graphql.auth.service.AuthorizationService;
import com.sgs.graphql.dataCenter.domain.DataCenter; import com.sgs.graphql.dataCenter.domain.DataCenter;
import com.sgs.graphql.dataCenter.domain.PhysicalMachine;
import com.sgs.graphql.dataCenter.query.pagination.DataCenterPageable; import com.sgs.graphql.dataCenter.query.pagination.DataCenterPageable;
import com.sgs.graphql.dataCenter.repo.DataCenterRepo; import com.sgs.graphql.dataCenter.repo.DataCenterRepo;
import com.sgs.graphql.dataCenter.repo.PhysicalMachineRepo;
import com.sgs.graphql.dataCenter.repo.criteria.DataCenterCriteria; import com.sgs.graphql.dataCenter.repo.criteria.DataCenterCriteria;
import com.sgs.graphql.dataCenter.service.DataCenterService; import com.sgs.graphql.dataCenter.service.DataCenterService;
import com.sgs.graphql.systemHistory.mutation.SystemLogger; import com.sgs.graphql.systemHistory.mutation.SystemLogger;
@@ -30,13 +32,15 @@ public class DataCenterQueryResolver implements GraphQLQueryResolver {
private final DataCenterService DataCenterService; private final DataCenterService DataCenterService;
private final DataCenterRepo dataCenterRepo; private final DataCenterRepo dataCenterRepo;
private final PhysicalMachineRepo physicalMachineRepo;
private final AuthorizationService authorizationService; private final AuthorizationService authorizationService;
private final SystemLogger systemLogger; private final SystemLogger systemLogger;
@Autowired @Autowired
public DataCenterQueryResolver(AuthorizationService authorizationService, SystemLogger systemLogger, DataCenterService DataCenterService, DataCenterRepo dataCenterRepo) { public DataCenterQueryResolver(AuthorizationService authorizationService, SystemLogger systemLogger, DataCenterService DataCenterService, DataCenterRepo dataCenterRepo, PhysicalMachineRepo physicalMachineRepo) {
this.DataCenterService = DataCenterService; this.DataCenterService = DataCenterService;
this.dataCenterRepo = dataCenterRepo; this.dataCenterRepo = dataCenterRepo;
this.physicalMachineRepo = physicalMachineRepo;
this.authorizationService = authorizationService; this.authorizationService = authorizationService;
this.systemLogger = systemLogger; this.systemLogger = systemLogger;
} }
@@ -66,4 +70,8 @@ public class DataCenterQueryResolver implements GraphQLQueryResolver {
return dataCenterRepo.findByNumber(id).stream().findFirst(); return dataCenterRepo.findByNumber(id).stream().findFirst();
} }
public List<PhysicalMachine> physicalMachines(UUID datacenterId) {
return physicalMachineRepo.findByDatacenterId(datacenterId);
}
} }

View File

@@ -0,0 +1,24 @@
package com.sgs.graphql.dataCenter.repo;
import com.sgs.graphql.dataCenter.domain.DataCenter;
import com.sgs.graphql.dataCenter.domain.DataCenterEmissionSource;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface DataCenterEmissionSourceRepo extends JpaRepository<DataCenterEmissionSource, String> {
List<DataCenterEmissionSource> findByDataCenter(DataCenter dataCenter);
Optional<DataCenterEmissionSource> findByDataCenterAndIsDefaultTrue(DataCenter dataCenter);
@Query("SELECT dces FROM DataCenterEmissionSource dces WHERE dces.dataCenter.id = :dataCenterId")
List<DataCenterEmissionSource> findByDataCenterId(@Param("dataCenterId") String dataCenterId);
void deleteByDataCenter(DataCenter dataCenter);
}

View File

@@ -0,0 +1,22 @@
package com.sgs.graphql.dataCenter.repo;
import com.sgs.graphql.dataCenter.domain.PhysicalMachine;
import com.sgs.lib.dao.repo.BaseRepo;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.UUID;
@Repository
public interface PhysicalMachineRepo extends BaseRepo<PhysicalMachine> {
/**
* Find all physical machines by datacenter ID
* @param datacenterId Datacenter ID
* @return List of physical machines
*/
@Query("SELECT pm FROM PhysicalMachine pm WHERE pm.dataCenter.id = :datacenterId")
List<PhysicalMachine> findByDatacenterId(@Param("datacenterId") UUID datacenterId);
}

View File

@@ -15,7 +15,7 @@ public class VMEmissionSummary {
private Double totalEmission; // Individual record's total emission private Double totalEmission; // Individual record's total emission
private LocalDateTime createdDate; // When this specific record was created private LocalDateTime createdDate; // When this specific record was created
private String physicalMachine; private String physicalMachine;
private String project; private String cloudSystem; // From physical machine
private String dataCenter; private String dataCenter;
// Individual emission values for this specific record // Individual emission values for this specific record
@@ -31,7 +31,7 @@ public class VMEmissionSummary {
public VMEmissionSummary(UUID vmId, String vmName, Double vmPower, String vmStatus, public VMEmissionSummary(UUID vmId, String vmName, Double vmPower, String vmStatus,
Double totalEmission, LocalDateTime createdDate, Double totalEmission, LocalDateTime createdDate,
String physicalMachine, String project, String dataCenter, String physicalMachine, String cloudSystem, String dataCenter,
Double co2, Double ch4, Double n2o) { Double co2, Double ch4, Double n2o) {
this.vmId = vmId; this.vmId = vmId;
this.vmName = vmName; this.vmName = vmName;
@@ -40,7 +40,7 @@ public class VMEmissionSummary {
this.totalEmission = totalEmission; this.totalEmission = totalEmission;
this.createdDate = createdDate; this.createdDate = createdDate;
this.physicalMachine = physicalMachine; this.physicalMachine = physicalMachine;
this.project = project; this.cloudSystem = cloudSystem;
this.dataCenter = dataCenter; this.dataCenter = dataCenter;
this.co2 = co2; this.co2 = co2;
this.ch4 = ch4; this.ch4 = ch4;
@@ -70,8 +70,8 @@ public class VMEmissionSummary {
public String getPhysicalMachine() { return physicalMachine; } public String getPhysicalMachine() { return physicalMachine; }
public void setPhysicalMachine(String physicalMachine) { this.physicalMachine = physicalMachine; } public void setPhysicalMachine(String physicalMachine) { this.physicalMachine = physicalMachine; }
public String getProject() { return project; } public String getCloudSystem() { return cloudSystem; }
public void setProject(String project) { this.project = project; } public void setCloudSystem(String cloudSystem) { this.cloudSystem = cloudSystem; }
public String getDataCenter() { return dataCenter; } public String getDataCenter() { return dataCenter; }
public void setDataCenter(String dataCenter) { this.dataCenter = dataCenter; } public void setDataCenter(String dataCenter) { this.dataCenter = dataCenter; }

View File

@@ -51,9 +51,11 @@ public class MainDataTableQueryResolver implements GraphQLQueryResolver {
/** /**
* GraphQL query to get VM emission summaries with hierarchy information * GraphQL query to get VM emission summaries with hierarchy information
* @param datacenterId Optional datacenter ID to filter VMs by datacenter
* @param projectId Optional project ID to filter VMs by project
* @return List of VM emission summaries including datacenter, project, aggregate, and physical machine info * @return List of VM emission summaries including datacenter, project, aggregate, and physical machine info
*/ */
public List<VMEmissionSummary> vmEmissionSummary() { public List<VMEmissionSummary> vmEmissionSummary(UUID datacenterId) {
return mainDataTableService.getVMEmissionSummaries(); return mainDataTableService.getVMEmissionSummaries(datacenterId);
} }
} }

View File

@@ -9,6 +9,7 @@ import com.sgs.lib.dao.service.BaseService;
import com.sgs.graphql.mainDataTable.dto.VMEmissionSummary; import com.sgs.graphql.mainDataTable.dto.VMEmissionSummary;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -32,31 +33,48 @@ public class MainDataTableService extends BaseService<MainDataTable, MainDataTab
} }
public List<VMEmissionSummary> getVMEmissionSummaries() { public List<VMEmissionSummary> getVMEmissionSummaries() {
return getVMEmissionSummaries(null);
}
public List<VMEmissionSummary> getVMEmissionSummaries(UUID datacenterId) {
List<String> whereConditions = new ArrayList<>();
if (datacenterId != null) {
whereConditions.add("dc.id = decode(replace(:datacenterId, '-', ''), 'hex')");
}
String whereClause = whereConditions.isEmpty() ? "" :
"WHERE " + String.join(" AND ", whereConditions) + " ";
String sql = """ String sql = """
SELECT SELECT
CAST(v.id AS VARCHAR) as vm_id, CAST(v.id AS VARCHAR) as vm_id,
v.name as vm_name, v.vm_name as vm_name,
v.power as vm_power, v.power as vm_power,
v.status as vm_status, v.state as vm_status,
mdt.total_emission, mdt.total_emission,
mdt.created_date, mdt.created_date,
pm.name as physical_machine_name, pm.name as physical_machine_name,
p.name as project_name, pm.cloud_system as cloud_system,
dc.data_center_name as datacenter_name, dc.data_center_name as datacenter_name,
mdt.co2, mdt.co2,
mdt.ch4, mdt.ch4,
mdt.n2o mdt.n2o
FROM main_data_table mdt FROM main_data_table mdt
JOIN vm v ON mdt.vm_id = v.id JOIN vm v ON mdt.vm_id = v.id
LEFT JOIN vms vms_active ON v.active_vms_id = vms_active.id LEFT JOIN physical_machine pm ON v.physical_machine_id = pm.id
LEFT JOIN vms vms_inactive ON v.inactive_vms_id = vms_inactive.id LEFT JOIN data_center dc ON pm.data_center_id = dc.id
LEFT JOIN physical_machine pm ON (pm.vms_id = vms_active.id OR pm.vms_id = vms_inactive.id) """ + whereClause + """
LEFT JOIN project p ON pm.project_id = p.id ORDER BY mdt.created_date DESC, v.vm_name
LEFT JOIN data_center dc ON p.data_center_id = dc.id
ORDER BY mdt.created_date DESC, v.name
"""; """;
Query query = entityManager.createNativeQuery(sql); Query query = entityManager.createNativeQuery(sql);
// Add parameters if provided
if (datacenterId != null) {
query.setParameter("datacenterId", datacenterId.toString());
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Object[]> results = query.getResultList(); List<Object[]> results = query.getResultList();
@@ -80,7 +98,7 @@ public class MainDataTableService extends BaseService<MainDataTable, MainDataTab
} }
summary.setPhysicalMachine((String) row[6]); summary.setPhysicalMachine((String) row[6]);
summary.setProject((String) row[7]); summary.setCloudSystem((String) row[7]);
summary.setDataCenter((String) row[8]); summary.setDataCenter((String) row[8]);
// Individual emission values // Individual emission values

View File

@@ -74,4 +74,5 @@ public class PermissionDescription {
public static final String DATA_CENTER_DELETE = "Veri Merkezi Silme"; public static final String DATA_CENTER_DELETE = "Veri Merkezi Silme";
public static final String DATA_CENTER_UPDATE = "Veri Merkezi Güncelleme"; public static final String DATA_CENTER_UPDATE = "Veri Merkezi Güncelleme";
public static final String DATA_CENTER_READ = "Veri Merkezi Görüntüleme"; public static final String DATA_CENTER_READ = "Veri Merkezi Görüntüleme";
public static final String PAGINATE_DATACENTERS_GET = "Veri Merkezleri Listesi Görüntüleme";
} }

View File

@@ -84,5 +84,6 @@ public class PermissionName {
public static final String DATA_CENTER_DELETE = "data_center_delete"; public static final String DATA_CENTER_DELETE = "data_center_delete";
public static final String DATA_CENTER_UPDATE = "data_center_update"; public static final String DATA_CENTER_UPDATE = "data_center_update";
public static final String DATA_CENTER_READ = "data_center_read"; public static final String DATA_CENTER_READ = "data_center_read";
public static final String PAGINATE_DATACENTERS_GET = "paginate_datacenters_get";
} }

View File

@@ -9,6 +9,8 @@ import com.sgs.lib.dao.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Optional;
@Service @Service
public class PermissionService extends BaseService<Permission, PermissionRepo, PermissionCriteria, PermissionCriteriaSpec> { public class PermissionService extends BaseService<Permission, PermissionRepo, PermissionCriteria, PermissionCriteriaSpec> {
@@ -16,4 +18,8 @@ public class PermissionService extends BaseService<Permission, PermissionRepo, P
public PermissionService(PermissionRepo repository, PermissionCriteriaSpec criteriaSpec) { public PermissionService(PermissionRepo repository, PermissionCriteriaSpec criteriaSpec) {
super(repository, criteriaSpec); super(repository, criteriaSpec);
} }
public Optional<Permission> findByTag(String tag) {
return getRepository().findByTag(tag);
}
} }

View File

@@ -74,19 +74,16 @@ public class MessageListener {
System.out.println(" External ID: " + dto.getId()); System.out.println(" External ID: " + dto.getId());
System.out.println(" Number: " + dto.getNumber()); System.out.println(" Number: " + dto.getNumber());
System.out.println(" Consumption Amount: " + dto.getConsuptionAmount()); System.out.println(" Consumption Amount: " + dto.getConsuptionAmount());
System.out.println(" Projects Count: " + (dto.getProjects() != null ? dto.getProjects().size() : 0)); System.out.println(" Physical Machines Count: " + (dto.getPhysicalMachine() != null ? dto.getPhysicalMachine().size() : 0));
// Log MainOptimizationSpace info for each project // Log Physical Machine info
if (dto.getProjects() != null) { if (dto.getPhysicalMachine() != null) {
for (Map.Entry<String, ProjectDto> projectEntry : dto.getProjects().entrySet()) { for (Map.Entry<String, PhysicalMachineDto> pmEntry : dto.getPhysicalMachine().entrySet()) {
String projectId = projectEntry.getKey(); String pmIp = pmEntry.getKey();
ProjectDto project = projectEntry.getValue(); PhysicalMachineDto pm = pmEntry.getValue();
if (project.getMainOptimizationSpace() != null) { System.out.println(" Physical Machine " + pm.getName() + " (IP: " + pmIp + "):");
MainOptimizationSpaceDto mainOpt = project.getMainOptimizationSpace(); System.out.println(" Power: " + pm.getPower());
System.out.println(" Project " + projectId + ":"); System.out.println(" VMs: " + (pm.getVms() != null ? pm.getVms().size() : 0));
System.out.println(" PMs: " + (mainOpt.getPms() != null ? mainOpt.getPms().size() : 0));
System.out.println(" VMs: " + (mainOpt.getVms() != null ? mainOpt.getVms().size() : 0));
}
} }
} }
@@ -103,18 +100,18 @@ public class MessageListener {
// System.out.println(entity.toString()); // System.out.println(entity.toString());
System.out.println("✅ Raw JSON message:\n" + message); System.out.println("✅ Raw JSON message:\n" + message);
System.out.println("✅ DTO parsed:\n" + objectMapper.writeValueAsString(dto)); //System.out.println("✅ DTO parsed:\n" + objectMapper.writeValueAsString(dto));
//System.out.println("✅ Entity:\n" + objectMapper.writeValueAsString(entity)); //System.out.println("✅ Entity:\n" + objectMapper.writeValueAsString(entity));
System.out.println("🚨 DataCenter name: " + dataCenter.getDataCenter()); System.out.println("🚨 DataCenter name: " + dataCenter.getDataCenter());
System.out.println("🚨 External ID: " + dataCenter.getExternalId()); System.out.println("🚨 External ID: " + dataCenter.getExternalId());
System.out.println("🚨 Projects count: " + (dataCenter.getProjects() != null ? dataCenter.getProjects().size() : 0)); System.out.println("🚨 Physical Machines count: " + (dataCenter.getPhysicalMachines() != null ? dataCenter.getPhysicalMachines().size() : 0));
if (dataCenter.getProjects() != null && !dataCenter.getProjects().isEmpty()) { if (dataCenter.getPhysicalMachines() != null && !dataCenter.getPhysicalMachines().isEmpty()) {
Project firstProject = dataCenter.getProjects().get(0); PhysicalMachine firstPM = dataCenter.getPhysicalMachines().get(0);
System.out.println("🚨 PMs in first project: " + firstProject.getPhysicalMachines().size()); System.out.println("🚨 VMs in first PM: " + firstPM.getVms().size());
// Show VM assignment summary // Show VM assignment summary
int totalVMs = 0; int totalVMs = 0;
for (PhysicalMachine pm : firstProject.getPhysicalMachines()) { for (PhysicalMachine pm : dataCenter.getPhysicalMachines()) {
int vmCount = pm.getVms() != null ? pm.getVms().size() : 0; int vmCount = pm.getVms() != null ? pm.getVms().size() : 0;
totalVMs += vmCount; totalVMs += vmCount;
System.out.println(" PM " + pm.getName() + " (IP: " + pm.getIp() + "): " + vmCount + " VMs"); System.out.println(" PM " + pm.getName() + " (IP: " + pm.getIp() + "): " + vmCount + " VMs");
@@ -157,6 +154,7 @@ public class MessageListener {
entity.setHost(dto.getHost()); entity.setHost(dto.getHost());
entity.setFlavorName(dto.getFlavorName()); entity.setFlavorName(dto.getFlavorName());
entity.setTag(dto.getTag()); entity.setTag(dto.getTag());
entity.setProject(dto.getProject());
// Set calcOn - you may want to derive this from state or other logic // Set calcOn - you may want to derive this from state or other logic
entity.setCalcOn(dto.isCalcOn()); entity.setCalcOn(dto.isCalcOn());
@@ -168,7 +166,7 @@ public class MessageListener {
entity.setEmissionSource(dto.getEmissionSource()); entity.setEmissionSource(dto.getEmissionSource());
// Debug logging // Debug logging
System.out.println("🔍 VM Entity Created: " + dto.getVmName() + " - state = " + dto.getState() + " - calcOn = " + dto.isCalcOn()); System.out.println("🔍 VM Entity Created: " + dto.getVmName() + " - state = " + dto.getState() + " - calcOn = " + dto.isCalcOn() + " - project = " + dto.getProject());
if (dto.getEmissionSource() != null && !dto.getEmissionSource().isEmpty()) { if (dto.getEmissionSource() != null && !dto.getEmissionSource().isEmpty()) {
System.out.println(" Emission Sources: " + dto.getEmissionSource()); System.out.println(" Emission Sources: " + dto.getEmissionSource());
} }
@@ -184,6 +182,7 @@ public class MessageListener {
entity.setName(dto.getName()); entity.setName(dto.getName());
entity.setIp(dto.getIp()); entity.setIp(dto.getIp());
entity.setTag(dto.getTag()); entity.setTag(dto.getTag());
entity.setCloudSystem(dto.getCloudSystem());
entity.setPower(dto.getPower()); entity.setPower(dto.getPower());
// VMs are now processed separately from the new message format // VMs are now processed separately from the new message format
@@ -207,112 +206,43 @@ public class MessageListener {
// ConsuptionUnit, and ActivitySubUnit are no longer received in the message // ConsuptionUnit, and ActivitySubUnit are no longer received in the message
// These will need to be set via the DataCenter CRUD operations // These will need to be set via the DataCenter CRUD operations
// Convert Projects // Convert Physical Machines directly
if (dto.getProjects() != null) { if (dto.getPhysicalMachine() != null) {
List<Project> projects = new ArrayList<>(); List<PhysicalMachine> physicalMachines = new ArrayList<>();
for (Map.Entry<String, ProjectDto> projectEntry : dto.getProjects().entrySet()) { for (Map.Entry<String, PhysicalMachineDto> pmEntry : dto.getPhysicalMachine().entrySet()) {
String projectId = projectEntry.getKey(); String pmIp = pmEntry.getKey();
ProjectDto projectDto = projectEntry.getValue(); PhysicalMachineDto pmDto = pmEntry.getValue();
// Set the project ID and a default name if not provided PhysicalMachine pm = new PhysicalMachine();
projectDto.setId(projectId); pm.setName(pmDto.getName());
if (projectDto.getName() == null || projectDto.getName().isEmpty()) { pm.setIp(pmIp); // Use the IP from the map key
projectDto.setName("Project-" + projectId.substring(0, 8)); // Use first 8 chars of ID as name pm.setTag(pmDto.getTag());
pm.setCloudSystem(pmDto.getCloudSystem());
pm.setPower(pmDto.getPower());
pm.setDataCenter(entity);
// Process VMs for this PM
if (pmDto.getVms() != null) {
List<VM> vms = new ArrayList<>();
for (Map.Entry<String, VMDto> vmEntry : pmDto.getVms().entrySet()) {
String vmIp = vmEntry.getKey();
VMDto vmDto = vmEntry.getValue();
VM vm = toVMEntity(vmDto);
vm.setIp(vmIp); // Use the IP from the map key
vm.setPhysicalMachine(pm);
vms.add(vm);
}
pm.setVms(vms);
} }
Project project = toProjectEntity(projectDto); physicalMachines.add(pm);
project.setDataCenter(entity);
projects.add(project);
} }
entity.setProjects(projects);
}
return entity;
}
public Project toProjectEntity(ProjectDto dto){
if (dto == null)
return null;
Project entity = new Project();
entity.setName(dto.getName());
// Process MainOptimizationSpace instead of physical machines list
if (dto.getMainOptimizationSpace() != null) {
List<PhysicalMachine> physicalMachines = processMainOptimizationSpace(dto.getMainOptimizationSpace());
// Set project reference for each PM
physicalMachines.forEach(pm -> pm.setProject(entity));
entity.setPhysicalMachines(physicalMachines); entity.setPhysicalMachines(physicalMachines);
} }
return entity; return entity;
} }
/**
* Process MainOptimizationSpaceDto and assign VMs to their hosting PMs
*/
private List<PhysicalMachine> processMainOptimizationSpace(MainOptimizationSpaceDto mainOptSpace) {
List<PhysicalMachine> physicalMachines = new ArrayList<>();
if (mainOptSpace.getPms() == null || mainOptSpace.getVms() == null) {
System.out.println("⚠️ MainOptimizationSpace has null PMs or VMs");
return physicalMachines;
}
System.out.println("🔍 Processing MainOptimizationSpace with " +
mainOptSpace.getPms().size() + " PMs and " +
mainOptSpace.getVms().size() + " VMs");
// Convert PMs from DTO to Entity
for (Map.Entry<String, PhysicalMachineDto> pmEntry : mainOptSpace.getPms().entrySet()) {
String pmIp = pmEntry.getKey();
PhysicalMachineDto pmDto = pmEntry.getValue();
// Set the IP from the map key
pmDto.setIp(pmIp);
PhysicalMachine pm = toPhysicalMachineEntity(pmDto);
physicalMachines.add(pm);
System.out.println("✅ Created PM: " + pm.getName() + " (IP: " + pm.getIp() + ")");
}
// Assign VMs to their hosting PMs
for (Map.Entry<String, VMDto> vmEntry : mainOptSpace.getVms().entrySet()) {
String vmIp = vmEntry.getKey();
VMDto vmDto = vmEntry.getValue();
// Set the IP from the map key
vmDto.setIp(vmIp);
VM vm = toVMEntity(vmDto);
// Find the hosting PM by IP
String hostingPmIp = vmDto.getHostingPm();
PhysicalMachine hostingPm = physicalMachines.stream()
.filter(pm -> pm.getIp().equals(hostingPmIp))
.findFirst()
.orElse(null);
if (hostingPm != null) {
// Assign VM to PM
vm.setPhysicalMachine(hostingPm);
if (hostingPm.getVms() == null) {
hostingPm.setVms(new ArrayList<>());
}
hostingPm.getVms().add(vm);
System.out.println("✅ Assigned VM: " + vm.getVmName() + " (IP: " + vm.getIp() +
") to PM: " + hostingPm.getName() + " (IP: " + hostingPm.getIp() + ")");
} else {
System.err.println("❌ Could not find hosting PM with IP: " + hostingPmIp +
" for VM: " + vm.getVmName());
}
}
return physicalMachines;
}
@Transactional @Transactional
public DataCenter createDataCenter(DataCenter newDc) { public DataCenter createDataCenter(DataCenter newDc) {
@@ -335,123 +265,117 @@ public class MessageListener {
// Note: DataCenter name and emission-related fields are no longer updated from the message // Note: DataCenter name and emission-related fields are no longer updated from the message
// These are now managed via DataCenter CRUD operations // These are now managed via DataCenter CRUD operations
for (Project newProject : newDc.getProjects()) { // Ensure datacenter has initialized physical machines list
Optional<Project> existingProjOpt = dc.getProjects().stream() if (dc.getPhysicalMachines() == null) {
.filter(p -> p.getName().equalsIgnoreCase(newProject.getName())) dc.setPhysicalMachines(new ArrayList<>());
.findFirst(); }
Project project; // Process Physical Machines directly from the message structure
if (existingProjOpt.isPresent()) { for (PhysicalMachine newPm : newDc.getPhysicalMachines()) {
project = existingProjOpt.get(); Optional<PhysicalMachine> existingPmOpt = dc.getPhysicalMachines().stream()
project.setName(newProject.getName()); .filter(pm -> pm.getIp().equals(newPm.getIp())) // Match by IP instead of name
System.out.println("✅ Updated existing project: " + project.getName()); .findFirst();
} else {
project = newProject; PhysicalMachine pm;
project.setDataCenter(dc); if (existingPmOpt.isPresent()) {
dc.getProjects().add(project); // Update existing PM
System.out.println("✅ Created new project: " + project.getName()); pm = existingPmOpt.get();
pm.setName(newPm.getName());
pm.setIp(newPm.getIp());
pm.setTag(newPm.getTag());
pm.setCloudSystem(newPm.getCloudSystem());
pm.setPower(newPm.getPower());
System.out.println("✅ Updated existing PM: " + pm.getName() + " (IP: " + pm.getIp() + ") - CloudSystem: " + pm.getCloudSystem());
} else {
// Create new PM
pm = newPm;
pm.setDataCenter(dc);
dc.getPhysicalMachines().add(pm);
System.out.println("✅ Created new PM: " + pm.getName() + " (IP: " + pm.getIp() + ") - CloudSystem: " + pm.getCloudSystem());
}
// Process VMs that are already assigned to this PM
if (newPm.getVms() != null && !newPm.getVms().isEmpty()) {
System.out.println("🔍 Processing " + newPm.getVms().size() + " VMs for PM: " + newPm.getName());
// Ensure PM has VM list initialized
if (pm.getVms() == null) {
pm.setVms(new ArrayList<>());
} }
// Ensure project has initialized physical machines list // Clear existing VMs to replace with new ones
if (project.getPhysicalMachines() == null) { pm.getVms().clear();
project.setPhysicalMachines(new ArrayList<>());
} // Process each VM that's already assigned to this PM
for (VM newVm : newPm.getVms()) {
// Process Physical Machines (VMs are already assigned to PMs from MainOptimizationSpace) if (newVm == null) continue;
for (PhysicalMachine newPm : newProject.getPhysicalMachines()) {
Optional<PhysicalMachine> existingPmOpt = project.getPhysicalMachines().stream() // Find existing VM by vmName
.filter(pm -> pm.getIp().equals(newPm.getIp())) // Match by IP instead of name Optional<VM> existingVmOpt = Optional.empty();
.findFirst(); String vmLookupName = newVm.getVmName();
if (vmLookupName != null) {
PhysicalMachine pm; existingVmOpt = vmRepo.findFirstByVmNameOrderByIdDesc(vmLookupName);
if (existingPmOpt.isPresent()) {
// Update existing PM
pm = existingPmOpt.get();
pm.setName(newPm.getName());
pm.setIp(newPm.getIp());
pm.setTag(newPm.getTag());
pm.setPower(newPm.getPower());
System.out.println("✅ Updated existing PM: " + pm.getName() + " (IP: " + pm.getIp() + ")");
} else {
// Create new PM
pm = newPm;
pm.setProject(project);
project.getPhysicalMachines().add(pm);
System.out.println("✅ Created new PM: " + pm.getName() + " (IP: " + pm.getIp() + ")");
} }
// Process VMs that are already assigned to this PM VM vm;
if (newPm.getVms() != null && !newPm.getVms().isEmpty()) { if (existingVmOpt.isPresent()) {
System.out.println("🔍 Processing " + newPm.getVms().size() + " VMs for PM: " + newPm.getName()); // Update existing VM
vm = existingVmOpt.get();
// Ensure PM has VM list initialized // IMPORTANT: Remove VM from its current Physical Machine first
if (pm.getVms() == null) { if (vm.getPhysicalMachine() != null) {
pm.setVms(new ArrayList<>()); PhysicalMachine currentPM = vm.getPhysicalMachine();
if (currentPM.getVms() != null) {
currentPM.getVms().remove(vm);
System.out.println("🔄 Removed VM " + vm.getVmName() + " from previous PM: " + currentPM.getName());
}
} }
// Clear existing VMs to replace with new ones vm.setState(newVm.getState());
pm.getVms().clear(); vm.setVmName(newVm.getVmName());
vm.setIp(newVm.getIp());
vm.setPower(newVm.getPower());
vm.setCalcOn(newVm.getCalcOn());
vm.setHostingPm(newVm.getHostingPm());
vm.setHost(newVm.getHost());
vm.setFlavorName(newVm.getFlavorName());
vm.setTag(newVm.getTag());
vm.setEmissionSource(newVm.getEmissionSource());
vm.setProject(newVm.getProject());
// Process each VM that's already assigned to this PM System.out.println("✅ Updated existing VM: " + vm.getVmName() + " (IP: " + vm.getIp() + ") - calcOn = " + vm.getCalcOn());
for (VM newVm : newPm.getVms()) { } else {
if (newVm == null) continue; // Use new VM
vm = newVm;
// Find existing VM by vmName
Optional<VM> existingVmOpt = Optional.empty(); System.out.println("✅ Created new VM: " + vm.getVmName() + " (IP: " + vm.getIp() + ") - calcOn = " + vm.getCalcOn());
String vmLookupName = newVm.getVmName(); }
if (vmLookupName != null) {
existingVmOpt = vmRepo.findFirstByVmNameOrderByIdDesc(vmLookupName); // Set physical machine relationship
} vm.setPhysicalMachine(pm);
pm.getVms().add(vm);
VM vm;
if (existingVmOpt.isPresent()) {
// Update existing VM
vm = existingVmOpt.get();
vm.setState(newVm.getState());
vm.setVmName(newVm.getVmName());
vm.setIp(newVm.getIp());
vm.setPower(newVm.getPower());
vm.setCalcOn(newVm.getCalcOn());
vm.setHostingPm(newVm.getHostingPm());
vm.setHost(newVm.getHost());
vm.setFlavorName(newVm.getFlavorName());
vm.setTag(newVm.getTag());
vm.setEmissionSource(newVm.getEmissionSource());
System.out.println("✅ Updated existing VM: " + vm.getVmName() + " (IP: " + vm.getIp() + ") - calcOn = " + vm.getCalcOn());
} else {
// Use new VM
vm = newVm;
System.out.println("✅ Created new VM: " + vm.getVmName() + " (IP: " + vm.getIp() + ") - calcOn = " + vm.getCalcOn());
}
// Set physical machine relationship
vm.setPhysicalMachine(pm);
pm.getVms().add(vm);
// Update config // Update config
if (newVm.getConfig() != null) { if (newVm.getConfig() != null) {
if (vm.getConfig() == null) { if (vm.getConfig() == null) {
vm.setConfig(newVm.getConfig()); vm.setConfig(newVm.getConfig());
vm.getConfig().setVm(vm); vm.getConfig().setVm(vm);
} else { } else {
vm.getConfig().setCpu(newVm.getConfig().getCpu()); vm.getConfig().setCpu(newVm.getConfig().getCpu());
vm.getConfig().setRam(newVm.getConfig().getRam()); vm.getConfig().setRam(newVm.getConfig().getRam());
vm.getConfig().setDisk(newVm.getConfig().getDisk()); vm.getConfig().setDisk(newVm.getConfig().getDisk());
}
}
} }
} }
} }
} }
}
System.out.println("Before Save: DataCenter=" + dc.getDataCenter()); System.out.println("Before Save: DataCenter=" + dc.getDataCenter());
System.out.println("External ID=" + dc.getExternalId()); System.out.println("External ID=" + dc.getExternalId());
System.out.println("Number=" + dc.getNumber()); System.out.println("Number=" + dc.getNumber());
System.out.println("Projects=" + (dc.getProjects() != null ? dc.getProjects().size() : 0)); System.out.println("Physical Machines=" + (dc.getPhysicalMachines() != null ? dc.getPhysicalMachines().size() : 0));
DataCenter saved = dataCenterService.save(dc); DataCenter saved = dataCenterService.save(dc);
System.out.println("✅ Saved: ID=" + saved.getId()); System.out.println("✅ Saved: ID=" + saved.getId());
@@ -525,41 +449,29 @@ public class MessageListener {
int failedCalculations = 0; int failedCalculations = 0;
int totalEmissionSources = 0; int totalEmissionSources = 0;
for (Project project : dataCenter.getProjects()) { for (PhysicalMachine pm : dataCenter.getPhysicalMachines()) {
for (PhysicalMachine pm : project.getPhysicalMachines()) { if (pm.getVms() != null) {
if (pm.getVms() != null) { // Calculate for all VMs (only those with calcOn = true)
// Calculate for all VMs (only those with calcOn = true) for (VM vm : pm.getVms()) {
for (VM vm : pm.getVms()) { totalVMs++;
totalVMs++; if (vm.getCalcOn() != null && vm.getCalcOn()) {
if (vm.getCalcOn() != null && vm.getCalcOn()) { eligibleVMs++;
eligibleVMs++; if (vm.getPower() != null && vm.getPower() > 0) {
if (vm.getPower() != null && vm.getPower() > 0) { System.out.println("✅ Processing VM " + vm.getVmName() + " (calcOn = true)");
System.out.println("✅ Processing VM " + vm.getVmName() + " (calcOn = true)"); processedVMs++;
processedVMs++;
// Check if VM has emission sources
// Check if VM has emission sources Map<String, Integer> emissionSources = vm.getEmissionSource();
Map<String, Integer> emissionSources = vm.getEmissionSource(); if (emissionSources != null && !emissionSources.isEmpty()) {
if (emissionSources != null && !emissionSources.isEmpty()) { // Create separate emission record for each emission source
// Create separate emission record for each emission source System.out.println("🔍 VM has " + emissionSources.size() + " emission sources");
System.out.println("🔍 VM has " + emissionSources.size() + " emission sources"); totalEmissionSources += emissionSources.size();
totalEmissionSources += emissionSources.size(); for (Map.Entry<String, Integer> sourceEntry : emissionSources.entrySet()) {
for (Map.Entry<String, Integer> sourceEntry : emissionSources.entrySet()) { String sourceName = sourceEntry.getKey();
String sourceName = sourceEntry.getKey(); Integer percentage = sourceEntry.getValue();
Integer percentage = sourceEntry.getValue(); System.out.println(" - " + sourceName + ": " + percentage + "%");
System.out.println(" - " + sourceName + ": " + percentage + "%");
boolean success = createVMEmissionRecordForSource(dataCenter, vm, pm, sourceName, percentage);
boolean success = createVMEmissionRecordForSource(dataCenter, vm, project, pm, sourceName, percentage);
if (success) {
successfulCalculations++;
} else {
failedCalculations++;
}
}
} else {
// Fallback to default emission source if VM has no emission sources
System.out.println("⚠️ VM has no emission sources, using default");
totalEmissionSources++;
boolean success = createVMEmissionRecord(dataCenter, vm, project, pm);
if (success) { if (success) {
successfulCalculations++; successfulCalculations++;
} else { } else {
@@ -567,16 +479,26 @@ public class MessageListener {
} }
} }
} else { } else {
System.out.println("⚠️ Skipping VM " + vm.getVmName() + " (calcOn = true) - no power consumption data"); // Fallback to default emission source if VM has no emission sources
System.out.println("⚠️ VM has no emission sources, using default");
totalEmissionSources++;
boolean success = createVMEmissionRecord(dataCenter, vm, pm);
if (success) {
successfulCalculations++;
} else {
failedCalculations++;
}
} }
} else { } else {
System.out.println(" Skipping VM " + vm.getVmName() + " - calcOn = " + vm.getCalcOn()); System.out.println(" Skipping VM " + vm.getVmName() + " (calcOn = true) - no power consumption data");
} }
} else {
System.out.println("⏭️ Skipping VM " + vm.getVmName() + " - calcOn = " + vm.getCalcOn());
} }
} }
} }
} }
System.out.println("🎯 VM Emission Calculation Summary:"); System.out.println("🎯 VM Emission Calculation Summary:");
System.out.println(" Total VMs found: " + totalVMs); System.out.println(" Total VMs found: " + totalVMs);
System.out.println(" VMs with calcOn = true: " + eligibleVMs); System.out.println(" VMs with calcOn = true: " + eligibleVMs);
@@ -587,7 +509,7 @@ public class MessageListener {
System.out.println(" Failed emission calculations: " + failedCalculations); System.out.println(" Failed emission calculations: " + failedCalculations);
} }
private boolean createVMEmissionRecord(DataCenter dataCenter, VM vm, Project project, PhysicalMachine pm) { private boolean createVMEmissionRecord(DataCenter dataCenter, VM vm, PhysicalMachine pm) {
try { try {
// Check if VM has an ID (is persisted) // Check if VM has an ID (is persisted)
if (vm.getId() == null) { if (vm.getId() == null) {
@@ -595,7 +517,7 @@ public class MessageListener {
return false; return false;
} }
MainDataTableCreateInput input = createVMMainDataTableInput(dataCenter, vm, project, pm); MainDataTableCreateInput input = createVMMainDataTableInput(dataCenter, vm, pm);
System.out.println("🔍 Creating emission record for VM: " + vm.getVmName() + " (Power: " + vm.getPower() + "W)"); System.out.println("🔍 Creating emission record for VM: " + vm.getVmName() + " (Power: " + vm.getPower() + "W)");
MainDataTable result = callMainDataTableMutation(input); MainDataTable result = callMainDataTableMutation(input);
@@ -619,7 +541,7 @@ public class MessageListener {
} }
} }
private boolean createVMEmissionRecordForSource(DataCenter dataCenter, VM vm, Project project, PhysicalMachine pm, String emissionSourceName, Integer percentage) { private boolean createVMEmissionRecordForSource(DataCenter dataCenter, VM vm, PhysicalMachine pm, String emissionSourceName, Integer percentage) {
try { try {
// Check if VM has an ID (is persisted) // Check if VM has an ID (is persisted)
if (vm.getId() == null) { if (vm.getId() == null) {
@@ -627,19 +549,56 @@ public class MessageListener {
return false; return false;
} }
// Find the emission source by name/tag // Find the emission source by name/tag from datacenter's configured emission sources
List<EmissionSource> emissionSources = emissionSourceRepo.findByTag(emissionSourceName); EmissionSource emissionSource = null;
if (emissionSources.isEmpty()) {
// First, try to find the emission source from datacenter's configured sources
if (dataCenter.getDataCenterEmissionSources() != null && !dataCenter.getDataCenterEmissionSources().isEmpty()) {
for (DataCenterEmissionSource dces : dataCenter.getDataCenterEmissionSources()) {
if (dces.getEmissionSource() != null &&
emissionSourceName.equalsIgnoreCase(dces.getEmissionSource().getTag())) {
emissionSource = dces.getEmissionSource();
System.out.println("✅ Found emission source '" + emissionSourceName +
"' in datacenter's configured sources (ID: " + emissionSource.getId() + ")");
break;
}
}
}
// If not found in datacenter's sources, fall back to subsector-specific search
if (emissionSource == null && dataCenter.getSubSector() != null) {
emissionSource = emissionSourceRepo.findByTagAndSubSectorIgnoreCase(emissionSourceName, dataCenter.getSubSector());
if (emissionSource != null) {
System.out.println("⚠️ Using subsector fallback for emission source '" + emissionSourceName +
"' (ID: " + emissionSource.getId() + ") - Consider configuring it for datacenter");
}
}
// Last resort: global search
if (emissionSource == null) {
List<EmissionSource> emissionSources = emissionSourceRepo.findByTag(emissionSourceName);
if (!emissionSources.isEmpty()) {
emissionSource = emissionSources.get(0);
System.out.println("⚠️ Using global fallback for emission source '" + emissionSourceName +
"' (ID: " + emissionSource.getId() + ") - This may cause incorrect calculations!");
}
}
if (emissionSource == null) {
System.err.println("❌ Could not find emission source: " + emissionSourceName); System.err.println("❌ Could not find emission source: " + emissionSourceName);
return false; return false;
} }
EmissionSource emissionSource = emissionSources.get(0);
// Calculate power consumption for this emission source (percentage of total VM power) // Calculate power consumption for this emission source (percentage of total VM power)
double sourceSpecificPower = vm.getPower() * (percentage / 100.0); double sourceSpecificPower = vm.getPower() * (percentage / 100.0);
MainDataTableCreateInput input = createVMMainDataTableInputForSource(dataCenter, vm, project, pm, emissionSource, sourceSpecificPower, percentage); MainDataTableCreateInput input = createVMMainDataTableInputForSource(dataCenter, vm, pm, emissionSource, sourceSpecificPower, percentage);
if (input == null) {
System.err.println("❌ Failed to create input for VM emission calculation - skipping");
return false;
}
System.out.println("🔍 Creating emission record for VM: " + vm.getVmName() + System.out.println("🔍 Creating emission record for VM: " + vm.getVmName() +
" - Source: " + emissionSourceName + " (" + percentage + "%) - Power: " + sourceSpecificPower + "W"); " - Source: " + emissionSourceName + " (" + percentage + "%) - Power: " + sourceSpecificPower + "W");
@@ -665,7 +624,7 @@ public class MessageListener {
} }
} }
private MainDataTableCreateInput createVMMainDataTableInput(DataCenter dataCenter, VM vm, Project project, PhysicalMachine pm) { private MainDataTableCreateInput createVMMainDataTableInput(DataCenter dataCenter, VM vm, PhysicalMachine pm) {
MainDataTableCreateInput input = new MainDataTableCreateInput(); MainDataTableCreateInput input = new MainDataTableCreateInput();
// Copy datacenter-level information (if available) // Copy datacenter-level information (if available)
@@ -692,8 +651,15 @@ public class MessageListener {
input.setSubSector(dataCenter.getSubSector().getId()); input.setSubSector(dataCenter.getSubSector().getId());
} }
if (dataCenter.getEmissionSource() != null) { // Handle multiple emission sources - use the default one for emission calculations
input.setEmissionSource(dataCenter.getEmissionSource().getId()); if (dataCenter.getDataCenterEmissionSources() != null && !dataCenter.getDataCenterEmissionSources().isEmpty()) {
// Find the default emission source or use the first one
DataCenterEmissionSource defaultEmissionSource = dataCenter.getDataCenterEmissionSources().stream()
.filter(DataCenterEmissionSource::getIsDefault)
.findFirst()
.orElse(dataCenter.getDataCenterEmissionSources().get(0));
input.setEmissionSource(defaultEmissionSource.getEmissionSource().getId());
} else { } else {
// Fallback to default emission source for electricity // Fallback to default emission source for electricity
try { try {
@@ -711,8 +677,16 @@ public class MessageListener {
input.setActivitySubUnit(dataCenter.getActivitySubUnit().getId()); input.setActivitySubUnit(dataCenter.getActivitySubUnit().getId());
} }
if (dataCenter.getConsuptionUnit() != null) { // Handle consumption unit from emission sources - use the default one for VM calculations
input.setConsuptionUnit(dataCenter.getConsuptionUnit().getId()); if (dataCenter.getDataCenterEmissionSources() != null && !dataCenter.getDataCenterEmissionSources().isEmpty()) {
DataCenterEmissionSource defaultEmissionSource = dataCenter.getDataCenterEmissionSources().stream()
.filter(DataCenterEmissionSource::getIsDefault)
.findFirst()
.orElse(dataCenter.getDataCenterEmissionSources().get(0));
if (defaultEmissionSource.getConsuptionUnit() != null) {
input.setConsuptionUnit(defaultEmissionSource.getConsuptionUnit().getId());
}
} }
// Default to Kapsam-3 if no emission scope is set // Default to Kapsam-3 if no emission scope is set
@@ -739,68 +713,142 @@ public class MessageListener {
System.out.println(" VM Name: " + vm.getVmName()); System.out.println(" VM Name: " + vm.getVmName());
System.out.println(" Power: " + vm.getPower() + "W"); System.out.println(" Power: " + vm.getPower() + "W");
System.out.println(" Physical Machine: " + pm.getName()); System.out.println(" Physical Machine: " + pm.getName());
System.out.println(" Project: " + project.getName());
System.out.println(" DataCenter Sector: " + (dataCenter.getSector() != null ? dataCenter.getSector().getTag() : "NOT SET")); System.out.println(" DataCenter Sector: " + (dataCenter.getSector() != null ? dataCenter.getSector().getTag() : "NOT SET"));
return input; return input;
} }
private MainDataTableCreateInput createVMMainDataTableInputForSource(DataCenter dataCenter, VM vm, Project project, PhysicalMachine pm, EmissionSource emissionSource, double sourceSpecificPower, Integer percentage) { private MainDataTableCreateInput createVMMainDataTableInputForSource(DataCenter dataCenter, VM vm, PhysicalMachine pm, EmissionSource emissionSource, double sourceSpecificPower, Integer percentage) {
MainDataTableCreateInput input = new MainDataTableCreateInput(); MainDataTableCreateInput input = new MainDataTableCreateInput();
// Copy datacenter-level information (if available) // Copy datacenter-level information (if available)
input.setYear("2025"); input.setYear("2025");
input.setMonth("07"); input.setMonth("07");
// Validate required fields
if (dataCenter == null) {
System.err.println("❌ DataCenter is null - cannot create emission record");
return null;
}
if (vm == null) {
System.err.println("❌ VM is null - cannot create emission record");
return null;
}
if (emissionSource == null) {
System.err.println("❌ EmissionSource is null - cannot create emission record");
return null;
}
// Note: These fields are no longer received in the message // Note: These fields are no longer received in the message
// They need to be set via DataCenter CRUD operations first // They need to be set via DataCenter CRUD operations first
if (dataCenter.getArea() != null && !dataCenter.getArea().getCities().isEmpty()) { if (dataCenter.getArea() != null && !dataCenter.getArea().getCities().isEmpty()) {
input.setCity(dataCenter.getArea().getCities().get(0).getId()); input.setCity(dataCenter.getArea().getCities().get(0).getId());
System.out.println("🔍 Setting City: " + dataCenter.getArea().getCities().get(0).getId());
} else {
System.out.println("⚠️ Warning: No city available for DataCenter");
} }
if (dataCenter.getArea() != null && !dataCenter.getArea().getDistricts().isEmpty()) { if (dataCenter.getArea() != null && !dataCenter.getArea().getDistricts().isEmpty()) {
input.setDistrict(dataCenter.getArea().getDistricts().get(0).getId()); input.setDistrict(dataCenter.getArea().getDistricts().get(0).getId());
System.out.println("🔍 Setting District: " + dataCenter.getArea().getDistricts().get(0).getId());
} else {
System.out.println("⚠️ Warning: No district available for DataCenter");
} }
if (dataCenter.getSector() != null) { if (dataCenter.getSector() != null) {
input.setSector(dataCenter.getSector().getId()); input.setSector(dataCenter.getSector().getId());
System.out.println("🔍 Setting Sector: " + dataCenter.getSector().getId() + " (" + dataCenter.getSector().getTag() + ")");
} else { } else {
System.out.println("⚠️ Warning: DataCenter has no sector set - emission calculation may fail"); System.err.println("❌ Error: DataCenter has no sector set - this is required for emission calculation");
return null;
} }
if (dataCenter.getSubSector() != null) { if (dataCenter.getSubSector() != null) {
input.setSubSector(dataCenter.getSubSector().getId()); input.setSubSector(dataCenter.getSubSector().getId());
System.out.println("🔍 Setting SubSector: " + dataCenter.getSubSector().getId());
} else {
System.out.println("⚠️ Warning: DataCenter has no subsector set");
} }
// Use the specific emission source for this calculation // Use the specific emission source for this calculation
input.setEmissionSource(emissionSource.getId()); input.setEmissionSource(emissionSource.getId());
System.out.println("🔍 Setting EmissionSource: " + emissionSource.getId() + " (" + emissionSource.getTag() + ")");
if (dataCenter.getActivitySubUnit() != null) { if (dataCenter.getActivitySubUnit() != null) {
input.setActivitySubUnit(dataCenter.getActivitySubUnit().getId()); input.setActivitySubUnit(dataCenter.getActivitySubUnit().getId());
System.out.println("🔍 Setting ActivitySubUnit: " + dataCenter.getActivitySubUnit().getId());
} else {
System.out.println("⚠️ Warning: DataCenter has no activity sub unit set");
} }
if (dataCenter.getConsuptionUnit() != null) { // Handle consumption unit from emission sources - use the emission source's unit
input.setConsuptionUnit(dataCenter.getConsuptionUnit().getId()); if (emissionSource != null) {
// Find the DataCenterEmissionSource that matches this emissionSource
System.out.println("🔍 Looking for consumption unit for emission source: " + emissionSource.getTag());
if (dataCenter.getDataCenterEmissionSources() == null || dataCenter.getDataCenterEmissionSources().isEmpty()) {
System.err.println("❌ Error: DataCenter has no emission sources configured - cannot find consumption unit");
return null;
}
boolean foundUnit = false;
for (DataCenterEmissionSource dces : dataCenter.getDataCenterEmissionSources()) {
if (dces.getEmissionSource() != null && dces.getEmissionSource().getId().equals(emissionSource.getId())) {
if (dces.getConsuptionUnit() != null) {
input.setConsuptionUnit(dces.getConsuptionUnit().getId());
System.out.println("🔍 Setting ConsumptionUnit: " + dces.getConsuptionUnit().getId() + " (" + dces.getConsuptionUnit().getTag() + ")");
foundUnit = true;
break;
} else {
System.err.println("❌ Error: DataCenterEmissionSource has no consumption unit set for emission source: " + emissionSource.getTag());
return null;
}
}
}
if (!foundUnit) {
System.err.println("❌ Error: Could not find matching DataCenterEmissionSource for emission source: " + emissionSource.getTag());
return null;
}
} }
// Default to Kapsam-3 if no emission scope is set // Default to Kapsam-3 if no emission scope is set
input.setScope(dataCenter.getEmissionScope() != null ? input.setScope(dataCenter.getEmissionScope() != null ?
dataCenter.getEmissionScope().getTag().equals("Kapsam-3") : true); dataCenter.getEmissionScope().getTag().equals("Kapsam-3") : true);
System.out.println("🔍 Setting Scope: " + (dataCenter.getEmissionScope() != null ?
dataCenter.getEmissionScope().getTag() : "Kapsam-3 (default)"));
try { try {
List<Organization> organizations = organizationRepo.findAll(); List<Organization> organizations = organizationRepo.findAll();
if (!organizations.isEmpty()) { if (!organizations.isEmpty()) {
input.setOrganization(organizations.get(0).getId()); input.setOrganization(organizations.get(0).getId());
System.out.println("🔍 Setting Organization: " + organizations.get(0).getId());
} else {
System.err.println("❌ Error: No organizations found in database - this is required");
return null;
} }
} catch (Exception e) { } catch (Exception e) {
System.err.println("❌ Error finding organization: " + e.getMessage()); System.err.println("❌ Error finding organization: " + e.getMessage());
return null;
} }
// Set VM-specific fields // Set VM-specific fields
input.setVmId(vm.getId()); input.setVmId(vm.getId());
System.out.println("🔍 Setting VM ID: " + vm.getId());
// Use the source-specific power consumption (percentage of total VM power) // Use the source-specific power consumption (percentage of total VM power)
input.setConsuptionAmount(String.valueOf(sourceSpecificPower)); // Format to 6 decimal places to avoid very long strings
String formattedPower = String.format("%.6f", sourceSpecificPower);
input.setConsuptionAmount(formattedPower);
System.out.println("🔍 Setting Consumption Amount: " + formattedPower + "W");
// Validate field lengths to prevent database errors
System.out.println("🔍 Field length validation:");
System.out.println(" Year: " + (input.getYear() != null ? input.getYear().length() : "null"));
System.out.println(" Month: " + (input.getMonth() != null ? input.getMonth().length() : "null"));
System.out.println(" ConsuptionAmount: " + (input.getConsuptionAmount() != null ? input.getConsuptionAmount().length() : "null"));
System.out.println("🔍 VM Emission Input for Source:"); System.out.println("🔍 VM Emission Input for Source:");
System.out.println(" VM ID: " + vm.getId()); System.out.println(" VM ID: " + vm.getId());
@@ -809,7 +857,6 @@ public class MessageListener {
System.out.println(" Percentage: " + percentage + "%"); System.out.println(" Percentage: " + percentage + "%");
System.out.println(" Source Power: " + sourceSpecificPower + "W"); System.out.println(" Source Power: " + sourceSpecificPower + "W");
System.out.println(" Physical Machine: " + pm.getName()); System.out.println(" Physical Machine: " + pm.getName());
System.out.println(" Project: " + project.getName());
System.out.println(" DataCenter Sector: " + (dataCenter.getSector() != null ? dataCenter.getSector().getTag() : "NOT SET")); System.out.println(" DataCenter Sector: " + (dataCenter.getSector() != null ? dataCenter.getSector().getTag() : "NOT SET"));
return input; return input;
@@ -828,6 +875,34 @@ public class MessageListener {
try { try {
System.out.println("🔄 Calling mainDataTableMutation.createMainDataTable..."); System.out.println("🔄 Calling mainDataTableMutation.createMainDataTable...");
// Validate input fields before making the call
if (input.getSector() == null) {
System.err.println("❌ Sector is null - cannot create emission record");
return null;
}
if (input.getEmissionSource() == null) {
System.err.println("❌ EmissionSource is null - cannot create emission record");
return null;
}
if (input.getConsuptionUnit() == null) {
System.err.println("❌ ConsumptionUnit is null - cannot create emission record");
return null;
}
if (input.getOrganization() == null) {
System.err.println("❌ Organization is null - cannot create emission record");
return null;
}
if (input.getVmId() == null) {
System.err.println("❌ VM ID is null - cannot create emission record");
return null;
}
System.out.println("🔍 Input validation passed - proceeding with mutation call");
// Call the mutation method - pass null environment since we've already patched the logging // Call the mutation method - pass null environment since we've already patched the logging
MainDataTable result = mainDataTableMutation.createMainDataTable(input, null); MainDataTable result = mainDataTableMutation.createMainDataTable(input, null);

View File

@@ -17,10 +17,16 @@ security.jwt.token.secret-key=secret
app.survey.base-url=http://localhost.com app.survey.base-url=http://localhost.com
spring.rabbitmq.host=188.132.198.145 # spring.rabbitmq.host=188.132.198.145
# spring.rabbitmq.port=5672
# spring.rabbitmq.username=testuser
# spring.rabbitmq.password=JGasF24561AZv2894De
#spring.rabbitmq.host=rabbitmq
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672 spring.rabbitmq.port=5672
spring.rabbitmq.username=testuser spring.rabbitmq.username=guest
spring.rabbitmq.password=JGasF24561AZv2894De spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/ spring.rabbitmq.virtual-host=/
spring.rabbitmq.connection-timeout=20000 spring.rabbitmq.connection-timeout=20000
spring.rabbitmq.template.retry.enabled=true spring.rabbitmq.template.retry.enabled=true
@@ -28,6 +34,3 @@ spring.rabbitmq.template.retry.max-attempts=3
spring.rabbitmq.template.retry.initial-interval=1000ms spring.rabbitmq.template.retry.initial-interval=1000ms
logging.level.org.springframework.amqp=DEBUG logging.level.org.springframework.amqp=DEBUG
spring.jpa.show-sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

View File

@@ -5,10 +5,13 @@ input DataCenterCreateInput {
sectorId: ID sectorId: ID
subSectorId: ID subSectorId: ID
activitySubUnitId: ID activitySubUnitId: ID
emissionSourceId: ID
consuptionUnitId: ID # Multiple emission sources support - each with exactly one unit
dataCenterEmissionSources: [DataCenterEmissionSourceInput!]
consuptionAmount: Float consuptionAmount: Float
areaId: ID areaId: ID
cityId: ID
number: Int number: Int
ayposURL: String ayposURL: String
address: String address: String
@@ -23,13 +26,23 @@ input DataCenterUpdateInput {
sectorId: ID sectorId: ID
subSectorId: ID subSectorId: ID
activitySubUnitId: ID activitySubUnitId: ID
emissionSourceId: ID
consuptionUnitId: ID # Multiple emission sources support - each with exactly one unit
dataCenterEmissionSources: [DataCenterEmissionSourceInput!]
consuptionAmount: Float consuptionAmount: Float
areaId: ID areaId: ID
cityId: ID
number: Int number: Int
ayposURL: String ayposURL: String
address: String address: String
latitude: Float latitude: Float
longitude: Float longitude: Float
} }
input DataCenterEmissionSourceInput {
emissionSourceId: ID!
consuptionUnitId: ID!
isDefault: Boolean
percentage: Float
}

View File

@@ -3,4 +3,5 @@ extend type Query{
dataCenters(criteria: DataCenterCriteria, sortBy: [SortBy!]): [DataCenter!] dataCenters(criteria: DataCenterCriteria, sortBy: [SortBy!]): [DataCenter!]
paginateDataCenters(pagination : Pagination!, criteria: DataCenterCriteria, sortBy:[SortBy!] ) : DataCenterPageable! paginateDataCenters(pagination : Pagination!, criteria: DataCenterCriteria, sortBy:[SortBy!] ) : DataCenterPageable!
getByNumber(number: Int!): DataCenter getByNumber(number: Int!): DataCenter
physicalMachines(datacenterId: ID!): [PhysicalMachine!]!
} }

View File

@@ -7,12 +7,15 @@ type DataCenter {
sector: Sector sector: Sector
subSector: SubSector subSector: SubSector
activitySubUnit: ActivitySubUnit activitySubUnit: ActivitySubUnit
emissionSource: EmissionSource
consuptionUnit: ConsuptionUnit # Multiple emission sources support - each with exactly one unit
dataCenterEmissionSources: [DataCenterEmissionSource]
consuptionAmount: Float consuptionAmount: Float
projects: [Project] physicalMachines: [PhysicalMachine]
area: Area area: Area
city: City
number: Int number: Int
ayposURL: String ayposURL: String
@@ -21,10 +24,12 @@ type DataCenter {
longitude: Float longitude: Float
} }
type Project { type DataCenterEmissionSource {
id: ID id: ID
name: String emissionSource: EmissionSource
physicalMachines: [PhysicalMachine] consuptionUnit: ConsuptionUnit
isDefault: Boolean
percentage: Float
} }
type PhysicalMachine { type PhysicalMachine {
@@ -32,11 +37,13 @@ type PhysicalMachine {
name: String name: String
ip: String ip: String
tag: String tag: String
cloudSystem: String
power: Float power: Float
vms: [Vm] vms: [VM]
dataCenter: DataCenter
} }
type Vm { type VM {
id: ID id: ID
state: String state: String
vmName: String vmName: String
@@ -47,8 +54,10 @@ type Vm {
host: String host: String
flavorName: String flavorName: String
tag: String tag: String
project: String
emissionSource: EmissionSourceMap emissionSource: EmissionSourceMap
config: Config config: Config
physicalMachine: PhysicalMachine
} }
scalar EmissionSourceMap scalar EmissionSourceMap

View File

@@ -2,5 +2,5 @@ extend type Query{
mainDataTable(id: ID!): MainDataTable! mainDataTable(id: ID!): MainDataTable!
mainDataTables(criteria: MainDataTableCriteria, sortBy: [SortBy!]): [MainDataTable!] mainDataTables(criteria: MainDataTableCriteria, sortBy: [SortBy!]): [MainDataTable!]
paginateMainDataTables(pagination : Pagination!, criteria: MainDataTableCriteria, sortBy:[SortBy!] ) : MainDataTablePageable! paginateMainDataTables(pagination : Pagination!, criteria: MainDataTableCriteria, sortBy:[SortBy!] ) : MainDataTablePageable!
vmEmissionSummary: [VMEmissionSummary!]! vmEmissionSummary(datacenterId: ID): [VMEmissionSummary!]!
} }

View File

@@ -26,11 +26,11 @@ type MainDataTable {
proteinAmount:Float proteinAmount:Float
burnOrOpenBurn:Boolean burnOrOpenBurn:Boolean
scopeCheck:Boolean scopeCheck:Boolean
vm: Vm vm: VM
} }
type Vm { type VM {
id: ID id: ID
state: String state: String
vmName: String vmName: String
@@ -41,6 +41,7 @@ type Vm {
host: String host: String
flavorName: String flavorName: String
tag: String tag: String
project: String
config: Config config: Config
} }
@@ -51,22 +52,22 @@ type Config {
disk: Int disk: Int
} }
type VMEmissionSummary { type VMEmissionSummary {
vmId: ID! vmId: ID!
vmName: String! vmName: String
vmPower: Float vmPower: Float
vmStatus: String vmStatus: String
totalEmission: Float! totalEmission: Float!
createdDate: LocalDateTime! createdDate: LocalDateTime!
physicalMachine: String physicalMachine: String
project: String cloudSystem: String
dataCenter: String dataCenter: String
# Individual emission values per record # Individual emission values per record
co2: Float! co2: Float!
ch4: Float! ch4: Float!
n2o: Float! n2o: Float!
reportGeneratedTime: LocalDateTime reportGeneratedTime: LocalDateTime
} }
type SolidWasteSupplement { type SolidWasteSupplement {
id: ID! id: ID!

View File

@@ -67,11 +67,7 @@
"Common": { "Common": {
"save": "Save", "save": "Save",
"cancel": "Cancel", "cancel": "Cancel"
"yes": "Yes",
"no": "No",
"areYouSure": "Are you sure?",
"cantRevert": "This action cannot be undone!"
}, },
"DataInput": { "DataInput": {

View File

@@ -1,315 +1,311 @@
{ {
"Actions": "Aksiyonlar", "Actions": "Aksiyonlar",
"Active": "Aktif", "Active": "Aktif",
"ByName": "İsme Göre", "ByName": "İsme Göre",
"CreatedTime": "Oluşturulma Zamanı", "CreatedTime": "Oluşturulma Zamanı",
"Description": " Açıklaması", "Description": " Açıklaması",
"Filter": "Filtrele", "Filter": "Filtrele",
"Management": "Yönetim", "Management": "Yönetim",
"Passive": "Pasif", "Passive": "Pasif",
"Show": "Göster", "Show": "Göster",
"Status": "Durum", "Status": "Durum",
"Time": "Zaman ", "Time": "Zaman ",
"Activities": { "Activities": {
"activity": "Aktivite ", "activity": "Aktivite ",
"activities": "Aktiviteler ", "activities": "Aktiviteler ",
"type": "Log Tipi", "type": "Log Tipi",
"message": "Log Mesajı" "message": "Log Mesajı"
}, },
"Areas": { "Areas": {
"addArea": "Alan Ekle", "addArea": "Alan Ekle",
"area": "Alan ", "area": "Alan ",
"areas": "Alanlar ", "areas": "Alanlar ",
"areaName": "Alan Adı ", "areaName": "Alan Adı ",
"city": "Şehir ", "city": "Şehir ",
"cities": "Şehirler ", "cities": "Şehirler ",
"cityName": "Şehir Adı ", "cityName": "Şehir Adı ",
"country": "Ülke ", "country": "Ülke ",
"countries": "Ülkeler ", "countries": "Ülkeler ",
"countryName": "Ülke Adı ", "countryName": "Ülke Adı ",
"countryCode": "Ülke Kodu ", "countryCode": "Ülke Kodu ",
"district": "İlçe ", "district": "İlçe ",
"districts": "İlçeler", "districts": "İlçeler",
"districtName": "İlçe Adı", "districtName": "İlçe Adı",
"neighborhood": "Mahalle ", "neighborhood": "Mahalle ",
"neighborhoods": "Mahalleler ", "neighborhoods": "Mahalleler ",
"neighborhoodName": "Mahalle Adı", "neighborhoodName": "Mahalle Adı",
"addNeighborhood": "Mahalle Ekle", "addNeighborhood": "Mahalle Ekle",
"latitude": "Enlem", "latitude": "Enlem",
"longitude": "Boylam" "longitude": "Boylam"
}, },
"Auth": { "Auth": {
"authorized": "Devam etmek için yetkilendirilmiş kullanıcı bilgilerinizi giriniz.", "authorized": "Devam etmek için yetkilendirilmiş kullanıcı bilgilerinizi giriniz.",
"didUForgotPassword": "Şifrenizi mi unuttunuz?", "didUForgotPassword": "Şifrenizi mi unuttunuz?",
"logout": ıkış Yap", "logout": ıkış Yap",
"logoutMessage": " Çıkış yaptınız. Yönlendiriliyorsunuz...", "logoutMessage": " Çıkış yaptınız. Yönlendiriliyorsunuz...",
"login": "Giriş Yap", "login": "Giriş Yap",
"loginMessage": " Giriş başarılı yönlendiriliyorsunuz...", "loginMessage": " Giriş başarılı yönlendiriliyorsunuz...",
"password": "Şifre ", "password": "Şifre ",
"welcome": "Hoşgeldiniz", "welcome": "Hoşgeldiniz",
"incorrectForm": "Kullanıcı bilgileri hatalıdır. Lütfen tekrar deneyiniz." "incorrectForm": "Kullanıcı bilgileri hatalıdır. Lütfen tekrar deneyiniz."
}, },
"Cruds": { "Cruds": {
"add": " Ekle", "add": " Ekle",
"cancel": " İptal", "cancel": " İptal",
"delete": "Sil", "delete": "Sil",
"edit": "Düzenle", "edit": "Düzenle",
"reactive": "Aktif Et", "reactive": "Aktif Et",
"save": "Kaydet", "save": "Kaydet",
"saving": "Kaydediliyor..", "saving": "Kaydediliyor..",
"update": "Güncelle" "update": "Güncelle"
}, },
"Common": { "Common": {
"save": "Kaydet", "save": "Kaydet",
"cancel": "İptal", "cancel": " İptal"
"yes": "Evet", },
"no": "Hayır",
"areYouSure": "Emin misiniz?", "DataInput": {
"cantRevert": "Bu işlem geri alınamaz!" "area": "Bölge ",
}, "report": "Rapor ",
"reports": "Raw Data",
"DataInput": { "data": "Veri ",
"area": "Bölge ", "datas": "Veriler ",
"report": "Rapor ", "dataInput": "Veri Girişi",
"reports": "Raw Data", "year": "Yıl",
"data": "Veri ", "month": "Ay",
"datas": "Veriler ", "consumptionAmount": "Tüketim Miktarı",
"dataInput": "Veri Girişi", "consumptionUnit": "Tüketim Birimi",
"year": "Yıl", "gpcReference": "GPC Referans",
"month": "Ay", "total": "Toplam ",
"consumptionAmount": "Tüketim Miktarı", "save": "Veriyi Kaydet",
"consumptionUnit": "Tüketim Birimi", "update": "Veriyi Güncelle",
"gpcReference": "GPC Referans", "showDeleted": "Silinen Raporları Göster",
"total": "Toplam ", "result": "Sonuç",
"save": "Veriyi Kaydet", "directToAllDatas": "Tüm Verileri Gör",
"update": "Veriyi Güncelle", "addNewData": "Yeni Veri Ekle",
"showDeleted": "Silinen Raporları Göster", "failUploadExcel": "Dosya yüklenirken hata oluştu!"
"result": "Sonuç", },
"directToAllDatas": "Tüm Verileri Gör",
"addNewData": "Yeni Veri Ekle", "Graphics": {
"failUploadExcel": "Dosya yüklenirken hata oluştu!" "graphics": "Raporlar",
}, "reports": "Raporlar"
},
"Graphics": {
"graphics": "Raporlar", "EmissionSources": {
"reports": "Raporlar" "dataSet": "Veri Seti",
}, "emissionSource": "Emisyon Kaynağı ",
"emissionSources": "Emisyon Kaynakları ",
"EmissionSources": { "emissionSourceName": "Emisyon Kaynağı Adı",
"dataSet": "Veri Seti", "addEmissionSource": "Emisyon Kaynağı Ekle",
"emissionSource": "Emisyon Kaynağı ", "existingEmissionName": "Bu isimde bir emisyon kaynağı mevcuttur!",
"emissionSources": "Emisyon Kaynakları ", "sector": "Veri Sektörü ",
"emissionSourceName": "Emisyon Kaynağı Adı", "sectors": "Veri Sektörleri ",
"addEmissionSource": "Emisyon Kaynağı Ekle", "subSector": "Sektör Alt Birimi ",
"existingEmissionName": "Bu isimde bir emisyon kaynağı mevcuttur!", "subSectors": "Sektör Alt Birimleri ",
"sector": "Veri Sektörü ", "subUnit": "Faaliyet Alt Birimi ",
"sectors": "Veri Sektörleri ", "subUnits": "Faaliyet Alt Birimleri ",
"subSector": "Sektör Alt Birimi ", "emissionScopes": "Emisyon Kapsamı ",
"subSectors": "Sektör Alt Birimleri ", "emissionFactors": "Emisyon Faktörleri ",
"subUnit": "Faaliyet Alt Birimi ", "showDeletedEmissionSource": "Silinen Emisyon Kaynaklarını Göster"
"subUnits": "Faaliyet Alt Birimleri ", },
"emissionScopes": "Emisyon Kapsamı ",
"emissionFactors": "Emisyon Faktörleri ", "Map": {
"showDeletedEmissionSource": "Silinen Emisyon Kaynaklarını Göster" "map": "Harita",
}, "goBack": "Geri dön",
"reference": "Referans",
"Map": { "title": "Harita"
"map": "Harita", },
"goBack": "Geri dön",
"reference": "Referans", "Months": {
"title": "Harita" "1": "Ocak",
}, "2": "Şubat",
"3": "Mart",
"Months": { "4": "Nisan",
"1": "Ocak", "5": "Mayıs",
"2": "Şubat", "6": "Haziran",
"3": "Mart", "7": "Temmuz",
"4": "Nisan", "8": "Ağustos",
"5": "Mayıs", "9": "Eylül",
"6": "Haziran", "10": "Ekim",
"7": "Temmuz", "11": "Kasım",
"8": "Ağustos", "12": "Aralık",
"9": "Eylül", "null": "Yıl Geneli",
"10": "Ekim", "0": "Yıl Geneli"
"11": "Kasım", },
"12": "Aralık",
"null": "Yıl Geneli", "Notifications": {
"0": "Yıl Geneli" "content": "İçerik ",
}, "notification": "Bildirim ",
"notifications": "Bildirimler ",
"Notifications": { "showAll": "Tüm Bildirimleri Göster",
"content": "İçerik ", "title": "Başlık ",
"notification": "Bildirim ", "notificationType": "Bildirim Tipi "
"notifications": "Bildirimler ", },
"showAll": "Tüm Bildirimleri Göster",
"title": "Başlık ", "Organizations": {
"notificationType": "Bildirim Tipi " "organization": "Organizasyon ",
}, "organizations": "Organizasyonlar",
"organizationName": "Organizasyon Adı",
"Organizations": { "parentOrganization": "Bağlı Olduğu Organizasyon",
"organization": "Organizasyon ", "childOrganization": "Alt Organizasyonu",
"organizations": "Organizasyonlar", "addOrganization": "Organizasyon Ekle",
"organizationName": "Organizasyon Adı", "existingName": "Bu isimde bir organizasyon mevcuttur!.",
"parentOrganization": "Bağlı Olduğu Organizasyon", "showDeletedOrganizations": "Silinen Organizasyonları Göster"
"childOrganization": "Alt Organizasyonu", },
"addOrganization": "Organizasyon Ekle",
"existingName": "Bu isimde bir organizasyon mevcuttur!.", "PasswordLabel": {
"showDeletedOrganizations": "Silinen Organizasyonları Göster" "passwordLabel": "Şifre",
}, "confirmPassword": "Şifre Tekrar",
"oldPassword": "Eski Şifre",
"PasswordLabel": { "newPassword": "Yeni Şifre",
"passwordLabel": "Şifre", "newConfirmPassword": "Yeni Şifre Tekrar",
"confirmPassword": "Şifre Tekrar", "verificationCode": "Doğrulama Kodu",
"oldPassword": "Eski Şifre", "cannotbeleftblank": " Boş Bırakılamaz ",
"newPassword": "Yeni Şifre", "passwordNotSame": "Şifreler aynı değil",
"newConfirmPassword": "Yeni Şifre Tekrar", "passwordValidation": "Şifre 6-20 karakter uzunluğunda, en az 1 sayı, 1 büyük harf ve 1 küçük harf içermelidir!",
"verificationCode": "Doğrulama Kodu",
"cannotbeleftblank": " Boş Bırakılamaz ", "forgotPassword": "Şifremi Unuttum",
"passwordNotSame": "Şifreler aynı değil", "enterEmail": "Geçerli bir email giriniz.",
"passwordValidation": "Şifre 6-20 karakter uzunluğunda, en az 1 sayı, 1 büyük harf ve 1 küçük harf içermelidir!", "send": "Gönder",
"redirectToReset": "Şifre sıfırlama ekranına yönlendiriliyorsunuz..",
"forgotPassword": "Şifremi Unuttum",
"enterEmail": "Geçerli bir email giriniz.", "resetPassword": "Şifre Sıfırlama",
"send": "Gönder", "resend": "Doğrulama Kodunu Tekrar Gönder",
"redirectToReset": "Şifre sıfırlama ekranına yönlendiriliyorsunuz..", "invalidVerificationCode": "Geçersiz doğrulama kodu!",
"redirectToLogin": "Giriş ekranına yönlendiriliyorsunuz.."
"resetPassword": "Şifre Sıfırlama", },
"resend": "Doğrulama Kodunu Tekrar Gönder",
"invalidVerificationCode": "Geçersiz doğrulama kodu!", "Roles": {
"redirectToLogin": "Giriş ekranına yönlendiriliyorsunuz.." "role": "Rol ",
}, "roles": "Roller",
"roleName": "Rol Adı",
"Roles": { "addRole": "Rol Ekle",
"role": "Rol ", "permissions": "Yetkiler",
"roles": "Roller", "existingRole": "Bu rol zaten mevcuttur."
"roleName": "Rol Adı", },
"addRole": "Rol Ekle",
"permissions": "Yetkiler", "Survey": {
"existingRole": "Bu rol zaten mevcuttur." "addAnswer": "Cevap Ekle",
}, "addSurvey": "Anket Ekle",
"addQuestion": "Soru Ekle",
"Survey": { "answer": "Cevap ",
"addAnswer": "Cevap Ekle", "answers": "Cevaplar",
"addSurvey": "Anket Ekle", "survey": "Anket",
"addQuestion": "Soru Ekle", "surveys": "Anketler ",
"answer": "Cevap ", "surveyName": "Anket Adı",
"answers": "Cevaplar", "question": "Soru ",
"survey": "Anket", "questions": "Sorular",
"surveys": "Anketler ", "tag": "Etiket",
"surveyName": "Anket Adı", "value": "Değer"
"question": "Soru ", },
"questions": "Sorular",
"tag": "Etiket", "Contact": {
"value": "Değer" "contact": "İletişim",
}, "contactInfo": "İletişim Bilgileri",
"contactEmail": "E-posta Adresi",
"Contact": { "contactPhoneNumber": "Telefon Numarası",
"contact": "İletişim", "contactAddress": "Adres"
"contactInfo": "İletişim Bilgileri", },
"contactEmail": "E-posta Adresi", "MailSettings": {
"contactPhoneNumber": "Telefon Numarası", "mailSettings": "E-posta Ayarları",
"contactAddress": "Adres" "editMailInfo": "E-posta Bilgilerini Düzenle",
}, "hostName": "Sunucu Adı",
"MailSettings": { "smtpPort": "SMTP Portu",
"mailSettings": "E-posta Ayarları", "emailAddress": "E-posta Adresi",
"editMailInfo": "E-posta Bilgilerini Düzenle", "emailPassword": "E-posta Şifresi",
"hostName": "Sunucu Adı", "leaveBlankNote": "(Mevcut şifreyi korumak için boş bırakın)",
"smtpPort": "SMTP Portu", "mainMail": "Ana e-posta yapılandırması olarak ayarla",
"emailAddress": "E-posta Adresi", "saveSettings": "Ayarları Kaydet",
"emailPassword": "E-posta Şifresi", "notConfigured": "E-posta yapılandırılmamış",
"leaveBlankNote": "(Mevcut şifreyi korumak için boş bırakın)", "noMailsRegistered": "Kayıtlı e-posta bulunamadı"
"mainMail": "Ana e-posta yapılandırması olarak ayarla", },
"saveSettings": "Ayarları Kaydet",
"notConfigured": "E-posta yapılandırılmamış", "Timer": {
"noMailsRegistered": "Kayıtlı e-posta bulunamadı" "continue": "Devam Et ",
}, "expire": "Oturum süreniz dolmak üzeredir.."
},
"Timer": {
"continue": "Devam Et ", "Users": {
"expire": "Oturum süreniz dolmak üzeredir.." "user": "Kullanıcı ",
}, "users": "Kullanıcılar ",
"userName": "Kullanıcı Adı ",
"Users": { "addUser": "Kullanıcı Ekle",
"user": "Kullanıcı ", "existingEmail": "Bu e-mail zaten mevcuttur.",
"users": "Kullanıcılar ", "existingPhoneNumber": "Bu telefon numarası zaten mevcuttur.",
"userName": "Kullanıcı Adı ", "showDeletedUsers": "Silinen Kullanıcıları Göster"
"addUser": "Kullanıcı Ekle", },
"existingEmail": "Bu e-mail zaten mevcuttur.",
"existingPhoneNumber": "Bu telefon numarası zaten mevcuttur.", "UserProfile": {
"showDeletedUsers": "Silinen Kullanıcıları Göster" "myProfile": "Profilim",
}, "firstName": "Ad",
"lastName": "Soyad",
"UserProfile": { "phoneNumber": "Telefon Numarası",
"myProfile": "Profilim", "avatar": "Profil Fotoğrafı",
"firstName": "Ad", "status": "Durum",
"lastName": "Soyad", "changePassword": "Şifre Değiştir",
"phoneNumber": "Telefon Numarası", "communicationPreferences": "İletişim Tercihleri",
"avatar": "Profil Fotoğrafı", "updateAvatar": "Profil Resmini Güncelle"
"status": "Durum", },
"changePassword": "Şifre Değiştir",
"communicationPreferences": "İletişim Tercihleri", "Warnings": {
"updateAvatar": "Profil Resmini Güncelle" "addedFail": " Eklenirken hata meydana geldi, lütfen tekrar deneyiniz.",
}, "addedSuccessfully": " Başarıyla Eklendi!",
"Warnings": { "updatedSuccessfully": " Başarıyla Güncellendi!",
"addedFail": " Eklenirken hata meydana geldi, lütfen tekrar deneyiniz.", "updatedFail": " Güncellenirken hata meydana geldi, lütfen tekrar deneyiniz.",
"addedSuccessfully": " Başarıyla Eklendi!",
"deletedSuccessfully": " Başarıyla Silindi!",
"updatedSuccessfully": " Başarıyla Güncellendi!", "deletedFail": " Silinirken hata meydana geldi, lütfen tekrar deneyiniz.",
"updatedFail": " Güncellenirken hata meydana geldi, lütfen tekrar deneyiniz.",
"genericUpdateFailed": "Güncelleme başarısız oldu. Lütfen tekrar deneyiniz.",
"deletedSuccessfully": " Başarıyla Silindi!", "notFound": "Bulunamadı",
"deletedFail": " Silinirken hata meydana geldi, lütfen tekrar deneyiniz.", "notUndone": "Bu işlem geri alınamaz!",
"required": "Tüm Alanlar Zorunludur!",
"genericUpdateFailed": "Güncelleme başarısız oldu. Lütfen tekrar deneyiniz.", "sureForDelete": " Silmek İstediğinize Emin Misiniz?",
"notFound": "Bulunamadı", "uniqueName": " Benzersiz bir isim veriniz! "
"notUndone": "Bu işlem geri alınamaz!", },
"required": "Tüm Alanlar Zorunludur!",
"sureForDelete": " Silmek İstediğinize Emin Misiniz?", "UserActivities": {
"uniqueName": " Benzersiz bir isim veriniz! " "title": "Kullanıcı Aktiviteleri"
}, },
"SystemActivities": {
"UserActivities": { "title": "Sistem Aktiviteleri"
"title": "Kullanıcı Aktiviteleri" },
},
"SystemActivities": { "DataCenter": {
"title": "Sistem Aktiviteleri" "title": "Veri Merkezleri",
}, "create": "Veri Merkezi Ekle",
"name": "İsim",
"DataCenter": { "namePlaceholder": "Veri merkezi ismini girin",
"title": "Veri Merkezleri", "externalId": "Harici ID",
"create": "Veri Merkezi Ekle", "externalIdPlaceholder": "Harici ID girin",
"name": "İsim", "number": "Numara",
"namePlaceholder": "Veri merkezi ismini girin", "numberPlaceholder": "Numara girin",
"externalId": "Harici ID", "url": "URL",
"externalIdPlaceholder": "Harici ID girin", "urlPlaceholder": "URL girin",
"number": "Numara", "createSuccess": "Veri merkezi başarıyla oluşturuldu",
"numberPlaceholder": "Numara girin", "deleteSuccess": "Veri merkezi başarıyla silindi",
"url": "URL", "searchPlaceholder": "Veri merkezlerinde ara..."
"urlPlaceholder": "URL girin", },
"createSuccess": "Veri merkezi başarıyla oluşturuldu",
"deleteSuccess": "Veri merkezi başarıyla silindi", "DataCenters": {
"searchPlaceholder": "Veri merkezlerinde ara..." "title": "Veri Merkezleri",
}, "create": "Veri Merkezi Ekle",
"name": "İsim",
"DataCenters": { "namePlaceholder": "Veri merkezi ismini girin",
"title": "Veri Merkezleri", "externalId": "Harici ID",
"create": "Veri Merkezi Ekle", "externalIdPlaceholder": "Harici ID girin",
"name": "İsim", "number": "Numara",
"namePlaceholder": "Veri merkezi ismini girin", "numberPlaceholder": "Numara girin",
"externalId": "Harici ID", "url": "URL",
"externalIdPlaceholder": "Harici ID girin", "urlPlaceholder": "URL girin",
"number": "Numara", "createSuccess": "Veri merkezi başarıyla oluşturuldu",
"numberPlaceholder": "Numara girin", "deleteSuccess": "Veri merkezi başarıyla silindi",
"url": "URL", "searchPlaceholder": "Veri merkezlerinde ara..."
"urlPlaceholder": "URL girin", }
"createSuccess": "Veri merkezi başarıyla oluşturuldu", }
"deleteSuccess": "Veri merkezi başarıyla silindi",
"searchPlaceholder": "Veri merkezlerinde ara..."
}
}

View File

@@ -49,9 +49,9 @@ export default [
permissionCheck("paginate_roles_get")) && [ permissionCheck("paginate_roles_get")) && [
{ {
id: "Organizations", id: "Organizations",
title: "Data Center Management", title: "DataCenters.title",
icon: <Home size={20} />, icon: <Home size={20} />,
navLink: "/veri-merkezi-yonetimi", navLink: "/organizasyonlar",
display: (permissionCheck("paginate_datacenters_get") || display: (permissionCheck("paginate_datacenters_get") ||
permissionCheck("data_center_create") || permissionCheck("data_center_create") ||
permissionCheck("data_center_update") || permissionCheck("data_center_update") ||
@@ -142,63 +142,9 @@ export default [
}, },
{ {
id: "DataCenter", id: "DataCenter",
title: "Data Center Overview", title: "Data Centers",
icon: <Zap size={20} />, icon: <Zap size={20} />,
navLink: "/veri-merkezi-genel", navLink: "/verimerkezi",
},
{
id: "Areas",
title: "Areas.areas",
icon: <Map size={20} />,
display:
permissionCheck("paginate_areas_get") ||
permissionCheck("paginate_countries_get") ||
permissionCheck("paginate_cities_get") ||
permissionCheck("paginate_districts_get") ||
permissionCheck("paginate_neighborhoods_get")
? ""
: "none",
children: (permissionCheck("paginate_areas_get") ||
permissionCheck("paginate_countries_get") ||
permissionCheck("paginate_cities_get") ||
permissionCheck("paginate_districts_get") ||
permissionCheck("paginate_neighborhoods_get")) && [
{
id: "AreasManagement",
title: "Areas.areas",
icon: <ArrowRight size={20} />,
navLink: "/alanlar",
display: permissionCheck("paginate_areas_get") ? "" : "none",
},
{
id: "Countries",
title: "Areas.countries",
icon: <ArrowRight size={20} />,
navLink: "/ulkeler",
display: permissionCheck("paginate_countries_get") ? "" : "none",
},
{
id: "Cities",
title: "Areas.cities",
icon: <ArrowRight size={20} />,
navLink: "/iller",
display: permissionCheck("paginate_cities_get") ? "" : "none",
},
{
id: "Districts",
title: "Areas.districts",
icon: <ArrowRight size={20} />,
navLink: "/ilceler",
display: permissionCheck("paginate_districts_get") ? "" : "none",
},
{
id: "Neighborhoods",
title: "Areas.neighborhoods",
icon: <ArrowRight size={20} />,
navLink: "/mahalleler",
display: permissionCheck("paginate_neighborhoods_get") ? "" : "none",
},
],
}, },
{ {
id: "Survey", id: "Survey",

View File

@@ -49,9 +49,9 @@ export default [
permissionCheck("paginate_roles_get")) && [ permissionCheck("paginate_roles_get")) && [
{ {
id: "DataCenters", id: "DataCenters",
title: "Data Center Management", title: "DataCenters.title",
icon: <Zap size={20} />, icon: <Zap size={20} />,
navLink: "/veri-merkezi-yonetimi", navLink: "/organizasyonlar",
display: (permissionCheck("paginate_datacenters_get") || display: (permissionCheck("paginate_datacenters_get") ||
permissionCheck("data_center_create") || permissionCheck("data_center_create") ||
permissionCheck("data_center_update") || permissionCheck("data_center_update") ||
@@ -142,63 +142,9 @@ export default [
}, },
{ {
id: "DataCenter", id: "DataCenter",
title: "Data Center Overview", title: "DataCenters",
icon: <Zap size={20} />, icon: <Zap size={20} />,
navLink: "/veri-merkezi-genel", navLink: "/verimerkezi",
},
{
id: "Areas",
title: "Areas.areas",
icon: <Map size={20} />,
display:
permissionCheck("paginate_areas_get") ||
permissionCheck("paginate_countries_get") ||
permissionCheck("paginate_cities_get") ||
permissionCheck("paginate_districts_get") ||
permissionCheck("paginate_neighborhoods_get")
? ""
: "none",
children: (permissionCheck("paginate_areas_get") ||
permissionCheck("paginate_countries_get") ||
permissionCheck("paginate_cities_get") ||
permissionCheck("paginate_districts_get") ||
permissionCheck("paginate_neighborhoods_get")) && [
{
id: "AreasManagement",
title: "Areas.areas",
icon: <ArrowRight size={20} />,
navLink: "/alanlar",
display: permissionCheck("paginate_areas_get") ? "" : "none",
},
{
id: "Countries",
title: "Areas.countries",
icon: <ArrowRight size={20} />,
navLink: "/ulkeler",
display: permissionCheck("paginate_countries_get") ? "" : "none",
},
{
id: "Cities",
title: "Areas.cities",
icon: <ArrowRight size={20} />,
navLink: "/iller",
display: permissionCheck("paginate_cities_get") ? "" : "none",
},
{
id: "Districts",
title: "Areas.districts",
icon: <ArrowRight size={20} />,
navLink: "/ilceler",
display: permissionCheck("paginate_districts_get") ? "" : "none",
},
{
id: "Neighborhoods",
title: "Areas.neighborhoods",
icon: <ArrowRight size={20} />,
navLink: "/mahalleler",
display: permissionCheck("paginate_neighborhoods_get") ? "" : "none",
},
],
}, },
{ {
id: "Survey", id: "Survey",

View File

@@ -12,15 +12,6 @@ export const getAreas = () => {
id id
tag tag
isDeleted isDeleted
cities {
id
name
coordinates
country {
id
name
}
}
} }
} }
`, `,

View File

@@ -34,41 +34,10 @@ export const getDataCenters = () => {
latitude latitude
longitude longitude
area { area {
id
tag
cities {
id
name
}
districts {
id
name
}
}
emissionScope {
id
tag
description
}
sector {
id
tag
}
subSector {
id
tag
}
emissionSource {
id
tag
}
consuptionUnit {
id
description
}
activitySubUnit {
id
tag tag
name
cityId
districtId
} }
projects { projects {
id id
@@ -76,16 +45,12 @@ export const getDataCenters = () => {
physicalMachines { physicalMachines {
id id
name name
vms { vms {
active {
id id
vmName status
state name
power power
calcOn
hostingPm
host
flavorName
tag
config { config {
id id
cpu cpu
@@ -93,6 +58,7 @@ export const getDataCenters = () => {
disk disk
} }
} }
}
} }
} }
} }
@@ -189,41 +155,10 @@ export const createDataCenter = (dataCenterData) => {
latitude latitude
longitude longitude
area { area {
id
tag
cities {
id
name
}
districts {
id
name
}
}
emissionScope {
id
tag
description
}
sector {
id
tag
}
subSector {
id
tag
}
emissionSource {
id
tag
}
consuptionUnit {
id
description
}
activitySubUnit {
id
tag tag
name
cityId
districtId
} }
} }
} }
@@ -234,16 +169,11 @@ export const createDataCenter = (dataCenterData) => {
externalId: parseInt(dataCenterData.externalId), externalId: parseInt(dataCenterData.externalId),
ayposURL: dataCenterData.ayposURL || "", ayposURL: dataCenterData.ayposURL || "",
number: parseInt(dataCenterData.number) || 1, number: parseInt(dataCenterData.number) || 1,
areaId: dataCenterData.areaId || null, areaId: dataCenterData.areaId,
address: dataCenterData.address || "", address: dataCenterData.address || "",
latitude: dataCenterData.latitude ? parseFloat(dataCenterData.latitude) : null, latitude: dataCenterData.latitude ? parseFloat(dataCenterData.latitude) : null,
longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null, longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null,
emissionScopeId: dataCenterData.emissionScopeId || null, city: dataCenterData.city
sectorId: dataCenterData.sectorId || null,
subSectorId: dataCenterData.subSectorId || null,
emissionSourceId: dataCenterData.emissionSourceId || null,
consuptionUnitId: dataCenterData.consuptionUnitId || null,
activitySubUnitId: dataCenterData.activitySubUnitId || null
} }
} }
}, },
@@ -310,41 +240,10 @@ export const updateDataCenter = (id, dataCenterData) => {
latitude latitude
longitude longitude
area { area {
id
tag
cities {
id
name
}
districts {
id
name
}
}
emissionScope {
id
tag
description
}
sector {
id
tag
}
subSector {
id
tag
}
emissionSource {
id
tag
}
consuptionUnit {
id
description
}
activitySubUnit {
id
tag tag
name
cityId
districtId
} }
} }
} }
@@ -356,16 +255,11 @@ export const updateDataCenter = (id, dataCenterData) => {
externalId: parseInt(dataCenterData.externalId), externalId: parseInt(dataCenterData.externalId),
ayposURL: dataCenterData.ayposURL || "", ayposURL: dataCenterData.ayposURL || "",
number: parseInt(dataCenterData.number) || 1, number: parseInt(dataCenterData.number) || 1,
areaId: dataCenterData.areaId || null, areaId: dataCenterData.areaId,
address: dataCenterData.address || "", address: dataCenterData.address || "",
latitude: dataCenterData.latitude ? parseFloat(dataCenterData.latitude) : null, latitude: dataCenterData.latitude ? parseFloat(dataCenterData.latitude) : null,
longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null, longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null,
emissionScopeId: dataCenterData.emissionScopeId || null, city: dataCenterData.city
sectorId: dataCenterData.sectorId || null,
subSectorId: dataCenterData.subSectorId || null,
emissionSourceId: dataCenterData.emissionSourceId || null,
consuptionUnitId: dataCenterData.consuptionUnitId || null,
activitySubUnitId: dataCenterData.activitySubUnitId || null
} }
} }
}, },
@@ -448,56 +342,6 @@ export const deleteDataCenter = (id) => {
}; };
}; };
export const getEmissionScopes = () => {
return async (dispatch) => {
dispatch({
type: "GET_EMISSION_SCOPES_LOADING",
});
try {
const response = await ApplicationService.http().post(
"/graphql",
{
query: `
query GetEmissionScopes {
emissionScopes {
id
tag
description
}
}
`
},
{
headers: {
Authorization: "Bearer " + localStorage.getItem("accessToken"),
},
}
);
if (response.data?.errors) {
throw new Error(response.data.errors[0].message);
}
dispatch({
type: "GET_EMISSION_SCOPES_SUCCESS",
payload: response.data.data.emissionScopes
});
return response.data.data.emissionScopes;
} catch (error) {
console.error("Error fetching emission scopes:", error);
dispatch({
type: "GET_EMISSION_SCOPES_ERROR",
payload: {
error: error.message || "Failed to fetch emission scopes",
},
});
throw error;
}
};
};
export const getDataCenterVMs = (dataCenterId) => { export const getDataCenterVMs = (dataCenterId) => {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
// Don't make the request if dataCenterId is undefined, null, or empty // Don't make the request if dataCenterId is undefined, null, or empty

View File

@@ -125,12 +125,11 @@ export const getMainDataTablesWithPaginate = (data) => {
{ {
paginateMainDataTables( paginateMainDataTables(
pagination: { page: 0, rowsPerPage: 100 } pagination: { page: 0, rowsPerPage: 100 }
criteria: { deleted: false, hasVm: true } criteria: { deleted: false }
sortBy: [{ field: "createdDate", direction: DESC }] sortBy: [{ field: "createdDate", direction: DESC }]
) { ) {
content { content {
id id
year
sector { sector {
id id
tag tag
@@ -139,40 +138,11 @@ export const getMainDataTablesWithPaginate = (data) => {
id id
tag tag
} }
activitySubUnit {
id
tag
}
emissionSource {
id
tag
}
emissionScope {
id
tag
}
co2 co2
ch4 ch4
n2o n2o
totalEmission totalEmission
createdDate createdDate
vm {
id
vmName
state
power
calcOn
hostingPm
host
flavorName
tag
config {
id
cpu
ram
disk
}
}
} }
pageInfo { pageInfo {
totalElements totalElements

View File

@@ -1,33 +0,0 @@
const initialState = {
emissionScopes: [],
loading: false,
error: null,
};
const emissionScopeReducer = (state = initialState, action) => {
switch (action.type) {
case "GET_EMISSION_SCOPES_LOADING":
return {
...state,
loading: true,
error: null,
};
case "GET_EMISSION_SCOPES_SUCCESS":
return {
...state,
loading: false,
emissionScopes: action.payload,
error: null,
};
case "GET_EMISSION_SCOPES_ERROR":
return {
...state,
loading: false,
error: action.payload.error,
};
default:
return state;
}
};
export default emissionScopeReducer;

View File

@@ -27,7 +27,6 @@ import surveys from "./surveys";
import uploads from "./upload"; import uploads from "./upload";
import mailSettings from "./mailSettings"; import mailSettings from "./mailSettings";
import dataCenter from "./dataCenter"; import dataCenter from "./dataCenter";
import emissionScope from "./emissionScope";
const rootReducer = combineReducers({ const rootReducer = combineReducers({
accessToken, accessToken,
@@ -58,7 +57,6 @@ const rootReducer = combineReducers({
uploads, uploads,
mailSettings, mailSettings,
dataCenter, dataCenter,
emissionScope,
}); });
export default rootReducer; export default rootReducer;

View File

@@ -25,7 +25,7 @@ const Routes = [
display: permissionCheck("paginate_users_get"), display: permissionCheck("paginate_users_get"),
}, },
{ {
path: "/veri-merkezi-yonetimi", path: "/organizasyonlar",
component: lazy(() => import("../../views/DataCenterManagement")), component: lazy(() => import("../../views/DataCenterManagement")),
display: permissionCheck("paginate_datacenters_get") || display: permissionCheck("paginate_datacenters_get") ||
permissionCheck("data_center_create") || permissionCheck("data_center_create") ||
@@ -74,7 +74,7 @@ const Routes = [
display: permissionCheck("activity_sub_units_get"), display: permissionCheck("activity_sub_units_get"),
}, },
{ {
path: "/veri-merkezi-genel", path: "/verimerkezi",
component: lazy(() => import("../../views/DataCenter")), component: lazy(() => import("../../views/DataCenter")),
}, },
{ {

View File

@@ -41,23 +41,14 @@ const DataCenter = () => {
// Projects // Projects
{ {
name: "Projects", name: "Projects",
selector: (row) => (row.projects || []).length, selector: (row) =>
sortable: true, (row.projects || []).map((p) => p.name).join(", "),
sortable: false,
minWidth: "200px", minWidth: "200px",
cell: (row) => ( cell: (row) => (
<div> <span>
{(row.projects || []).length > 0 ? ( {(row.projects || []).map((p) => p.name).join(", ") || "-"}
<div className="d-flex flex-column"> </span>
{row.projects.map((project, index) => (
<div key={project.id} className={`badge badge-light-primary ${index > 0 ? 'mt-1' : ''}`}>
{project.name}
</div>
))}
</div>
) : (
<span className="text-muted">-</span>
)}
</div>
), ),
}, },
// Physical Machines // Physical Machines
@@ -77,41 +68,26 @@ const DataCenter = () => {
}, },
}, },
{ {
name: "Virtual Machines", name: "Total Active VMs",
selector: (row) => { selector: (row) => {
const pms = getAllPhysicalMachines(row); const pms = getAllPhysicalMachines(row);
const vms = pms.reduce((acc, pm) => { return pms.reduce(
if (!pm.vms) return acc; (total, pm) => total + (pm.vms?.active?.length || 0),
return { 0
active: acc.active + pm.vms.filter(vm => vm.state?.toLowerCase() === "active").length, );
total: acc.total + pm.vms.length
};
}, { active: 0, total: 0 });
return vms.total;
}, },
sortable: true, sortable: true,
minWidth: "200px", minWidth: "150px",
cell: (row) => { cell: (row) => {
const pms = getAllPhysicalMachines(row); const pms = getAllPhysicalMachines(row);
const vms = pms.reduce((acc, pm) => { const totalVMs = pms.reduce(
if (!pm.vms) return acc; (total, pm) => total + (pm.vms?.active?.length || 0),
return { 0
active: acc.active + pm.vms.filter(vm => vm.state?.toLowerCase() === "active").length, );
total: acc.total + pm.vms.length
};
}, { active: 0, total: 0 });
return ( return (
<div className="d-flex align-items-center"> <div className="d-flex align-items-center">
<Monitor size={16} className="mr-2" /> <Monitor size={16} className="mr-1" />
<div> <span>{totalVMs}</span>
<div className="font-weight-bold">{vms.total} Total</div>
<div className="small">
<span className="text-success">{vms.active} Active</span>
<span className="text-muted mx-1"></span>
<span className="text-warning">{vms.total - vms.active} Inactive</span>
</div>
</div>
</div> </div>
); );
}, },
@@ -162,78 +138,76 @@ const DataCenter = () => {
<div key={pm.id} className="mb-3 border rounded p-3"> <div key={pm.id} className="mb-3 border rounded p-3">
<h6 className="text-primary">{pm.name}</h6> <h6 className="text-primary">{pm.name}</h6>
{/* All VMs */} {/* Active VMs */}
<div className="mb-2 d-flex justify-content-between align-items-center"> <p className="mb-2">
<h6 className="mb-0"> <strong>Active VMs ({pm.vms?.active?.length || 0}):</strong>
<Monitor size={16} className="mr-1" /> </p>
Virtual Machines ({pm.vms?.length || 0}) {pm.vms?.active?.length > 0 ? (
</h6> <div className="ml-3">
</div> {pm.vms.active.map((vm) => (
{pm.vms?.length > 0 ? ( <div
<div className="table-responsive mt-2"> key={vm.id}
<table className="table table-bordered table-hover"> className="mb-2 p-2 border-left border-success"
<thead className="thead-light"> >
<tr> <div className="row">
<th>Name</th> <div className="col-md-3">
<th>Status</th> <strong>Name:</strong> {vm.name}
<th>Power (W)</th> </div>
<th>Configuration</th> <div className="col-md-2">
<th>Host</th> <strong>Status:</strong>
</tr> <span className="badge badge-success ml-1">
</thead> {vm.status}
<tbody> </span>
{pm.vms.map((vm) => { </div>
const isActive = vm.state && ["ACTIVE", "active"].includes(vm.state); <div className="col-md-2">
return ( <strong>Power:</strong> {vm.power}
<tr key={vm.id}> </div>
<td> <div className="col-md-5">
<span className="font-weight-bold">{vm.vmName || vm.vm_name}</span> <strong>Config:</strong> CPU: {vm.config?.cpu}, RAM:{" "}
</td> {vm.config?.ram}, Disk: {vm.config?.disk}
<td> </div>
<div className={`d-inline-block px-2 py-1 rounded-pill ${isActive ? 'bg-light-success text-success' : 'bg-light-warning text-warning'}`}> </div>
{vm.state} </div>
</div> ))}
</td>
<td>
{vm.power ? (
<span>{vm.power.toFixed(2)}</span>
) : (
<span className="text-muted">-</span>
)}
</td>
<td>
<div className="d-flex align-items-center">
<div className="mr-3">
<small className="text-muted d-block">CPU</small>
<span>{(vm.config?.cpu || (vm.confg && vm.confg[1])) || '-'}</span>
</div>
<div className="mr-3">
<small className="text-muted d-block">RAM</small>
<span>{(vm.config?.ram || (vm.confg && vm.confg[2])) || '-'} GB</span>
</div>
<div>
<small className="text-muted d-block">Disk</small>
<span>{(vm.config?.disk || (vm.confg && vm.confg[3])) || '-'} GB</span>
</div>
</div>
</td>
<td>
<div className="d-flex align-items-center">
<Server size={14} className="mr-1" />
<span>{vm.host || vm.hostingPm || (vm.confg && vm.confg[4]) || '-'}</span>
</div>
</td>
</tr>
);
})}
</tbody>
</table>
</div> </div>
) : ( ) : (
<div className="text-center p-3 bg-light-secondary rounded"> <p className="text-muted ml-3">No active VMs</p>
<Monitor size={24} className="text-muted mb-1" /> )}
<p className="text-muted mb-0">No virtual machines found</p>
{/* Inactive VMs */}
<p className="mb-2 mt-3">
<strong>Inactive VMs ({pm.vms?.inactive?.length || 0}):</strong>
</p>
{pm.vms?.inactive?.length > 0 ? (
<div className="ml-3">
{pm.vms.inactive.map((vm) => (
<div
key={vm.id}
className="mb-2 p-2 border-left border-warning"
>
<div className="row">
<div className="col-md-3">
<strong>Name:</strong> {vm.name}
</div>
<div className="col-md-2">
<strong>Status:</strong>
<span className="badge badge-warning ml-1">
{vm.status}
</span>
</div>
<div className="col-md-2">
<strong>Power:</strong> {vm.power}
</div>
<div className="col-md-5">
<strong>Config:</strong> CPU: {vm.config?.cpu}, RAM:{" "}
{vm.config?.ram}, Disk: {vm.config?.disk}
</div>
</div>
</div>
))}
</div> </div>
) : (
<p className="text-muted ml-3">No inactive VMs</p>
)} )}
</div> </div>
))} ))}

View File

@@ -28,8 +28,7 @@ import { Edit } from "@mui/icons-material";
import { useSnackbar } from "notistack"; import { useSnackbar } from "notistack";
import { default as SweetAlert } from "sweetalert2"; import { default as SweetAlert } from "sweetalert2";
import withReactContent from "sweetalert2-react-content"; import withReactContent from "sweetalert2-react-content";
import { getDataCenters, createDataCenter, updateDataCenter, deleteDataCenter, getEmissionScopes } from "../redux/actions/dataCenter"; import { getDataCenters, createDataCenter, updateDataCenter, deleteDataCenter } from "../redux/actions/dataCenter";
import { getAreas, getAreasWithCriteria } from "../redux/actions/areas";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { getSectors, getSectorById, getSubSectorById, getConsuptionUnits } from "../redux/actions/datas"; import { getSectors, getSectorById, getSubSectorById, getConsuptionUnits } from "../redux/actions/datas";
import { getAllEmissionSources } from "../redux/actions/emissionSources"; import { getAllEmissionSources } from "../redux/actions/emissionSources";
@@ -106,8 +105,6 @@ const DataCenterManagement = () => {
externalId: "", externalId: "",
number: "", number: "",
address: "", address: "",
areaId: null,
cityId: null,
latitude: null, latitude: null,
longitude: null, longitude: null,
ayposURL: "", ayposURL: "",
@@ -122,22 +119,15 @@ const DataCenterManagement = () => {
const [mapPosition, setMapPosition] = useState(null); const [mapPosition, setMapPosition] = useState(null);
const dataCenterStore = useSelector((state) => { const dataCenterStore = useSelector((state) => state.dataCenter);
console.log('DataCenter Store:', state.dataCenter);
return state.dataCenter;
});
const emissionScopeStore = useSelector((state) => state.emissionScope);
const datasStore = useSelector((state) => state.datas); const datasStore = useSelector((state) => state.datas);
const emissionSourceStore = useSelector((state) => state.emissionSources); const emissionSourceStore = useSelector((state) => state.emissionSources);
const areasStore = useSelector((state) => state.areas);
const [sectorsOptions, setSectorsOptions] = useState([]); const [sectorsOptions, setSectorsOptions] = useState([]);
const [subSectorsOptions, setSubSectorsOptions] = useState([]); const [subSectorsOptions, setSubSectorsOptions] = useState([]);
const [emissionSourcesOptions, setEmissionSourcesOptions] = useState([]); const [emissionSourcesOptions, setEmissionSourcesOptions] = useState([]);
const [consuptionUnitsOptions, setConsuptionUnitsOptions] = useState([]); const [consuptionUnitsOptions, setConsuptionUnitsOptions] = useState([]);
const [activitySubUnitsOptions, setActivitySubUnitsOptions] = useState([]); const [activitySubUnitsOptions, setActivitySubUnitsOptions] = useState([]);
const [emissionScopesOptions, setEmissionScopesOptions] = useState([]); const [emissionScopesOptions, setEmissionScopesOptions] = useState([]);
const [areasOptions, setAreasOptions] = useState([]);
const [citiesOptions, setCitiesOptions] = useState([]);
// Add state for selected sector and sub sector like in data input // Add state for selected sector and sub sector like in data input
const [selectedSector, setSelectedSector] = useState(null); const [selectedSector, setSelectedSector] = useState(null);
@@ -182,9 +172,8 @@ const DataCenterManagement = () => {
}, },
{ {
name: t("Actions"), name: t("Actions"),
allowOverflow: true, allowOverflow: false,
width: "150px", maxWidth: "150px",
center: true,
cell: (row) => { cell: (row) => {
return ( return (
<div className="d-flex"> <div className="d-flex">
@@ -193,7 +182,7 @@ const DataCenterManagement = () => {
<MoreVertical size={15} /> <MoreVertical size={15} />
</DropdownToggle> </DropdownToggle>
<DropdownMenu container={"body"} end> <DropdownMenu container={"body"} end>
{permissionCheck("data_center_update") && ( {permissionCheck("datacenter_update") && (
<DropdownItem <DropdownItem
tag="a" tag="a"
className="w-100" className="w-100"
@@ -203,7 +192,7 @@ const DataCenterManagement = () => {
<span className="align-middle ml-50">{t("Cruds.edit")}</span> <span className="align-middle ml-50">{t("Cruds.edit")}</span>
</DropdownItem> </DropdownItem>
)} )}
{permissionCheck("data_center_delete") && ( {permissionCheck("datacenter_delete") && (
<DropdownItem <DropdownItem
tag="a" tag="a"
className="w-100" className="w-100"
@@ -226,8 +215,6 @@ const DataCenterManagement = () => {
useEffect(() => { useEffect(() => {
dispatch(getDataCenters()); dispatch(getDataCenters());
dispatch(getSectors()); dispatch(getSectors());
dispatch(getAreas());
dispatch(getEmissionScopes());
}, [dispatch]); }, [dispatch]);
useEffect(() => { useEffect(() => {
@@ -308,69 +295,35 @@ const DataCenterManagement = () => {
}, [datasStore?.consuptionUnits]); }, [datasStore?.consuptionUnits]);
useEffect(() => { useEffect(() => {
if (emissionScopeStore?.emissionScopes) { setEmissionScopesOptions([
setEmissionScopesOptions( {
emissionScopeStore.emissionScopes.map((scope) => ({ label: "Şehir İçi",
value: scope.id, value: false,
label: scope.tag, },
})) {
); label: "Şehir Dışı",
} value: true,
}, [emissionScopeStore?.emissionScopes]); },
]);
// Set areas options when areas data is loaded }, []);
useEffect(() => {
if (areasStore?.areas) {
setAreasOptions(
areasStore.areas.map((area) => ({
value: area.id,
label: area.tag,
}))
);
}
}, [areasStore?.areas]);
// Set cities options when selected area changes
useEffect(() => {
if (selectedDataCenter.areaId && areasStore?.areas) {
const selectedArea = areasStore.areas.find(
(area) => area.id === selectedDataCenter.areaId
);
if (selectedArea?.cities) {
setCitiesOptions(
selectedArea.cities.map((city) => ({
value: city.id,
label: city.name,
}))
);
} else {
setCitiesOptions([]);
}
} else {
setCitiesOptions([]);
}
}, [selectedDataCenter.areaId, areasStore?.areas]);
const handleEditDataCenter = (row) => { const handleEditDataCenter = (row) => {
console.log('Editing data center:', row);
setEditingDataCenter(row); setEditingDataCenter(row);
setSelectedDataCenter({ setSelectedDataCenter({
name: row.dataCenter, name: row.dataCenter,
externalId: row.externalId?.toString(), externalId: row.externalId,
number: row.number?.toString(), number: row.number,
address: row.address || "", address: row.address,
areaId: row.area?.id || null,
cityId: null,
latitude: row.latitude, latitude: row.latitude,
longitude: row.longitude, longitude: row.longitude,
ayposURL: row.ayposURL || "", ayposURL: row.ayposURL,
city: row.city || "", city: row.city,
emissionScopeId: row.emissionScope?.id || null, emissionScopeId: row.emissionScope?.id,
sectorId: row.sector?.id || null, sectorId: row.sector?.id,
subSectorId: row.subSector?.id || null, subSectorId: row.subSector?.id,
emissionSourceId: row.emissionSource?.id || null, emissionSourceId: row.emissionSource?.id,
consuptionUnitId: row.consuptionUnit?.id || null, consuptionUnitId: row.consuptionUnit?.id,
activitySubUnitId: row.activitySubUnit?.id || null activitySubUnitId: row.activitySubUnit?.id
}); });
// Set the selected sector and sub sector for cascading dropdowns // Set the selected sector and sub sector for cascading dropdowns
@@ -411,101 +364,18 @@ const DataCenterManagement = () => {
} }
}; };
const validateForm = () => {
const errors = [];
// Required fields validation
if (!selectedDataCenter.name?.trim()) {
errors.push(t("DataCenter.nameRequired"));
}
if (!selectedDataCenter.externalId?.trim()) {
errors.push(t("DataCenter.externalIdRequired"));
}
if (!selectedDataCenter.sectorId) {
errors.push(t("DataCenter.sectorRequired"));
}
// Number validations
try {
if (selectedDataCenter.externalId) {
const externalId = parseInt(selectedDataCenter.externalId);
if (isNaN(externalId) || externalId < 0) {
errors.push(t("DataCenter.externalIdMustBePositiveNumber"));
}
}
if (selectedDataCenter.number) {
const number = parseInt(selectedDataCenter.number);
if (isNaN(number) || number < 1) {
errors.push(t("DataCenter.numberMustBePositive"));
}
}
} catch (e) {
errors.push(t("DataCenter.invalidNumberFormat"));
}
// Coordinate validations
if (selectedDataCenter.latitude || selectedDataCenter.longitude) {
try {
const lat = parseFloat(selectedDataCenter.latitude);
const lng = parseFloat(selectedDataCenter.longitude);
if (isNaN(lat) || lat < -90 || lat > 90) {
errors.push(t("DataCenter.invalidLatitude"));
}
if (isNaN(lng) || lng < -180 || lng > 180) {
errors.push(t("DataCenter.invalidLongitude"));
}
} catch (e) {
errors.push(t("DataCenter.invalidCoordinates"));
}
}
// URL validation
if (selectedDataCenter.ayposURL?.trim()) {
try {
new URL(selectedDataCenter.ayposURL);
} catch (e) {
errors.push(t("DataCenter.invalidURL"));
}
}
// Relationship validations
if (selectedDataCenter.subSectorId && !selectedDataCenter.sectorId) {
errors.push(t("DataCenter.sectorRequired"));
}
if (selectedDataCenter.emissionSourceId && !selectedDataCenter.subSectorId) {
errors.push(t("DataCenter.subSectorRequired"));
}
if (selectedDataCenter.consuptionUnitId && !selectedDataCenter.emissionSourceId) {
errors.push(t("DataCenter.emissionSourceRequired"));
}
if (selectedDataCenter.activitySubUnitId && !selectedDataCenter.subSectorId) {
errors.push(t("DataCenter.subSectorRequiredForActivity"));
}
return errors;
};
const handleSubmit = async () => { const handleSubmit = async () => {
const validationErrors = validateForm(); if (!selectedDataCenter.name || !selectedDataCenter.externalId) {
if (validationErrors.length > 0) { enqueueSnackbar(t("Common.fillRequiredFields"), { variant: "error" });
validationErrors.forEach(error => {
enqueueSnackbar(error, { variant: "error" });
});
return; return;
} }
try { try {
// Format data according to GraphQL input type // Ensure number is set for new data centers
const dataToSubmit = { const dataToSubmit = {
dataCenter: selectedDataCenter.name, ...selectedDataCenter,
externalId: parseInt(selectedDataCenter.externalId), number: selectedDataCenter.number || 1, // Default to 1 if not set
number: parseInt(selectedDataCenter.number || "1"), city: selectedDataCenter.city, // Add city to the payload
address: selectedDataCenter.address,
areaId: selectedDataCenter.areaId,
latitude: selectedDataCenter.latitude ? parseFloat(selectedDataCenter.latitude) : null,
longitude: selectedDataCenter.longitude ? parseFloat(selectedDataCenter.longitude) : null,
ayposURL: selectedDataCenter.ayposURL,
emissionScopeId: selectedDataCenter.emissionScopeId, emissionScopeId: selectedDataCenter.emissionScopeId,
sectorId: selectedDataCenter.sectorId, sectorId: selectedDataCenter.sectorId,
subSectorId: selectedDataCenter.subSectorId, subSectorId: selectedDataCenter.subSectorId,
@@ -523,27 +393,14 @@ const DataCenterManagement = () => {
await dispatch(createDataCenter(dataToSubmit)); await dispatch(createDataCenter(dataToSubmit));
enqueueSnackbar(t("DataCenter.createSuccess"), { variant: "success" }); enqueueSnackbar(t("DataCenter.createSuccess"), { variant: "success" });
} }
// Refresh the data centers list
await dispatch(getDataCenters());
handleCloseModal(); handleCloseModal();
} catch (error) { } catch (error) {
console.error("Submit error:", error); console.error("Submit error:", error);
enqueueSnackbar(
// Handle specific error cases error?.message || t("DataCenter.submitError"),
if (error.message?.includes("duplicate")) { { variant: "error" }
enqueueSnackbar(t("DataCenter.duplicateExternalId"), { variant: "error" }); );
} else if (error.message?.includes("permission")) {
enqueueSnackbar(t("Common.noPermission"), { variant: "error" });
} else if (error.message?.includes("not found")) {
enqueueSnackbar(t("DataCenter.resourceNotFound"), { variant: "error" });
} else {
enqueueSnackbar(
error?.message || t("DataCenter.submitError"),
{ variant: "error" }
);
}
} }
}; };
@@ -742,49 +599,19 @@ const DataCenterManagement = () => {
</Col> </Col>
<Col sm="6"> <Col sm="6">
<FormGroup> <FormGroup>
<Label for="area">Area</Label> <Label for="city">{t("DataCenter.city")}</Label>
<Select <Input
id="area" type="text"
name="area"
placeholder="Select area"
options={areasOptions}
value={areasOptions?.find(
(option) => option.value === selectedDataCenter.areaId
)}
onChange={(option) => {
setSelectedDataCenter({
...selectedDataCenter,
areaId: option?.value,
cityId: null,
city: "",
});
}}
isClearable
filterOption={customFilterForSelect}
/>
</FormGroup>
</Col>
<Col sm="6">
<FormGroup>
<Label for="city">City</Label>
<Select
id="city"
name="city" name="city"
placeholder="Select city" id="city"
options={citiesOptions} placeholder={t("DataCenter.city")}
value={citiesOptions?.find( value={selectedDataCenter.city}
(option) => option.value === selectedDataCenter.cityId onChange={(e) =>
)}
onChange={(option) => {
setSelectedDataCenter({ setSelectedDataCenter({
...selectedDataCenter, ...selectedDataCenter,
cityId: option?.value, city: e.target.value,
city: option?.label || "", })
}); }
}}
isClearable
filterOption={customFilterForSelect}
isDisabled={!selectedDataCenter.areaId}
/> />
</FormGroup> </FormGroup>
</Col> </Col>
@@ -843,7 +670,7 @@ const DataCenterManagement = () => {
</Col> </Col>
<Col sm="6"> <Col sm="6">
<FormGroup> <FormGroup>
<Label for="sector">Sector <span className="text-danger">*</span></Label> <Label for="sector">Sector</Label>
<Select <Select
id="sector" id="sector"
name="sector" name="sector"
@@ -1079,9 +906,7 @@ const DataCenterManagement = () => {
sortIcon={<ChevronDown size={10} />} sortIcon={<ChevronDown size={10} />}
paginationDefaultPage={currentPage} paginationDefaultPage={currentPage}
paginationComponent={CustomPagination} paginationComponent={CustomPagination}
data={dataCenterStore?.dataCenters || []} data={dataCenterStore.dataCenters}
progressPending={dataCenterStore?.loading}
progressComponent={<div className="text-center p-3">Loading...</div>}
noDataComponent={ noDataComponent={
<div className="p-2 text-center"> <div className="p-2 text-center">
{t("Common.noDataAvailable")} {t("Common.noDataAvailable")}

View File

@@ -13,18 +13,13 @@ function MainDataTables() {
const [error, setError] = useState(null); const [error, setError] = useState(null);
useEffect(() => { useEffect(() => {
const fetchData = async () => { try {
try { // Fetch VM emission data
setLoading(true); dispatch(getVMEmissionSummary());
await dispatch(getVMEmissionSummary()); } catch (err) {
} catch (err) { console.error('Error in MainDataTables:', err);
console.error('Error in MainDataTables:', err); setError(err.message);
setError(err.message); }
} finally {
setLoading(false);
}
};
fetchData();
}, [dispatch]); }, [dispatch]);
// Debug log for store data // Debug log for store data
@@ -32,21 +27,71 @@ function MainDataTables() {
console.log('Current store data:', mainDataTablesStore); console.log('Current store data:', mainDataTablesStore);
}, [mainDataTablesStore]); }, [mainDataTablesStore]);
const [loading, setLoading] = useState(true);
const columns = [ const columns = [
{ header: t("VM ID"), accessorKey: "vmId", Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span> }, {
{ header: t("VM Name"), accessorKey: "vmName", Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span> }, header: "VM ID",
{ header: t("VM Power"), accessorKey: "vmPower", Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span> }, accessorKey: "vmId",
{ header: t("VM Status"), accessorKey: "vmStatus", Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span> }, Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
{ header: t("Total Emission"), accessorKey: "totalEmission", Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span> }, },
{ header: t("Created Date"), accessorKey: "createdDate", Cell: ({ cell }) => (<span>{cell.getValue() ? new Date(cell.getValue()).toLocaleString() : "-"}</span>), sortable: true }, {
{ header: t("Physical Machine"), accessorKey: "physicalMachine", Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span> }, header: "Data Center",
{ header: t("Project"), accessorKey: "project", Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span> }, accessorKey: "dataCenter",
{ header: t("Data Center"), accessorKey: "dataCenter", Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span> }, Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
{ header: "CO2", accessorKey: "co2", Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span> }, },
{ header: "CH4", accessorKey: "ch4", Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span> }, {
{ header: "N2O", accessorKey: "n2o", Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span> }, header: "Project",
accessorKey: "project",
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: "Physical Machine",
accessorKey: "physicalMachine",
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: "Virtual Machine",
accessorKey: "vmName",
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: "VM Power (W)",
accessorKey: "vmPower",
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: "VM Status",
accessorKey: "vmStatus",
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: "Total Emissions",
accessorKey: "totalEmission",
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: "CO2",
accessorKey: "co2",
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: "CH4",
accessorKey: "ch4",
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: "N2O",
accessorKey: "n2o",
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: "Created Date",
accessorKey: "createdDate",
Cell: ({ cell }) => (
<span>
{cell.getValue() ? new Date(cell.getValue()).toLocaleString() : "-"}
</span>
),
},
]; ];
const tableData = mainDataTablesStore?.vmEmissionSummary || []; const tableData = mainDataTablesStore?.vmEmissionSummary || [];
@@ -64,7 +109,7 @@ function MainDataTables() {
<div style={{ marginTop: "2%" }}> <div style={{ marginTop: "2%" }}>
<Card> <Card>
<CardHeader className="border-bottom"> <CardHeader className="border-bottom">
<CardTitle tag="h4">{t("Raw Data")}</CardTitle> <CardTitle tag="h4">{t("Carbon Emission Data")}</CardTitle>
</CardHeader> </CardHeader>
<MaterialReactTable <MaterialReactTable
columns={columns} columns={columns}
@@ -87,14 +132,12 @@ function MainDataTables() {
pageIndex: 0 pageIndex: 0
}, },
sorting: [ sorting: [
{ id: 'createdDate', desc: true } { id: 'dataCenter', desc: false }
], ],
density: 'compact' density: 'compact'
}} }}
state={{ state={{
isLoading: loading, isLoading: !mainDataTablesStore?.vmEmissionSummary
showProgressBars: true,
showSkeletons: true,
}} }}
/> />
</Card> </Card>