multiple source calculation

This commit is contained in:
Ali Sadeghi
2025-08-04 18:26:36 +03:30
parent 09933c8bbf
commit 831eab906b
7 changed files with 812 additions and 496 deletions

View File

@@ -1,95 +1,7 @@
{ {
"158f073fbd554d4a9c32309ea7d1865e":{ "id":111,
"main_optimization_space":{ "data_center":"new lab blc",
"vms":{ "projects":{
"10.150.1.131":{
"vm_name":"BLC-AYPOS-Development-20",
"power":0,
"state":"inactive",
"hosting_pm":"10.150.1.33",
"host":"compute2",
"flavor_name":"aypos.test.flavour.10",
"tag":"None",
"confg":[
"BLC-AYPOS-Development-20",
2,
1,
8,
"compute2"
]
},
"10.150.1.186":{
"vm_name":"BLC-AYPOS-Development-21",
"power":0,
"state":"inactive",
"hosting_pm":"10.150.1.33",
"host":"compute2",
"flavor_name":"aypos.test.flavour.10",
"tag":"None",
"confg":[
"BLC-AYPOS-Development-21",
2,
1,
8,
"compute2"
]
}
},
"pms":{
"10.150.1.33":{
"tag":"None",
"name":"compute2",
"power":177.83822950819666,
"confg":[
"compute2",
3,
94,
59,
114
]
},
"10.150.1.34":{
"tag":"None",
"name":"compute3",
"power":21.3385737704918,
"confg":[
"compute3",
24,
115,
151,
114
]
},
"10.150.1.35":{
"tag":"None",
"name":"compute4",
"power":152.66185245901653,
"confg":[
"compute4",
-13,
28,
103,
114
]
},
"10.150.1.32":{
"tag":"None",
"name":"compute1",
"power":36.34004918032787,
"confg":[
"compute1",
10,
97,
211,
114
]
}
}
},
"sub_optimization_space":{
}
},
"48966d34ff274def88db7f7b6d9f5cdc":{ "48966d34ff274def88db7f7b6d9f5cdc":{
"main_optimization_space":{ "main_optimization_space":{
"vms":{ "vms":{
@@ -100,7 +12,14 @@
"hosting_pm":"10.150.1.35", "hosting_pm":"10.150.1.35",
"host":"compute4", "host":"compute4",
"flavor_name":"m1.medium", "flavor_name":"m1.medium",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"Bgreen", "Bgreen",
2, 2,
@@ -116,7 +35,14 @@
"hosting_pm":"10.150.1.34", "hosting_pm":"10.150.1.34",
"host":"compute3", "host":"compute3",
"flavor_name":"aypos.test.flavour.8", "flavor_name":"aypos.test.flavour.8",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"BLC-AYPOS-Development-1", "BLC-AYPOS-Development-1",
3, 3,
@@ -132,7 +58,14 @@
"hosting_pm":"10.150.1.33", "hosting_pm":"10.150.1.33",
"host":"compute2", "host":"compute2",
"flavor_name":"m1.small", "flavor_name":"m1.small",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"nginx-proxyV2", "nginx-proxyV2",
1, 1,
@@ -143,18 +76,25 @@
}, },
"10.150.1.114":{ "10.150.1.114":{
"vm_name":"BLC-AYPOS-Development-5", "vm_name":"BLC-AYPOS-Development-5",
"power":8.541673488756713, "power":0,
"state":"active", "state":"inactive",
"hosting_pm":"10.150.1.35", "hosting_pm":"10.150.1.33",
"host":"compute4", "host":"compute2",
"flavor_name":"aypos.test.flavour.19", "flavor_name":"aypos.test.flavour.19",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"BLC-AYPOS-Development-5", "BLC-AYPOS-Development-5",
2, 2,
3, 3,
8, 8,
"compute4" "compute2"
] ]
}, },
"10.150.1.123":{ "10.150.1.123":{
@@ -164,7 +104,14 @@
"hosting_pm":"10.150.1.35", "hosting_pm":"10.150.1.35",
"host":"compute4", "host":"compute4",
"flavor_name":"ForJAVA", "flavor_name":"ForJAVA",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"SGE", "SGE",
8, 8,
@@ -180,7 +127,14 @@
"hosting_pm":"10.150.1.35", "hosting_pm":"10.150.1.35",
"host":"compute4", "host":"compute4",
"flavor_name":"m1.public", "flavor_name":"m1.public",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"aybuke", "aybuke",
8, 8,
@@ -196,7 +150,14 @@
"hosting_pm":"10.150.1.34", "hosting_pm":"10.150.1.34",
"host":"compute3", "host":"compute3",
"flavor_name":"aypos.test.flavour.15", "flavor_name":"aypos.test.flavour.15",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"BLC-AYPOS-Development-2", "BLC-AYPOS-Development-2",
2, 2,
@@ -207,28 +168,42 @@
}, },
"10.150.1.141":{ "10.150.1.141":{
"vm_name":"BLC-AYPOS-Development-0", "vm_name":"BLC-AYPOS-Development-0",
"power":10.146380530416682, "power":12.178434411667777,
"state":"active", "state":"active",
"hosting_pm":"10.150.1.33", "hosting_pm":"10.150.1.35",
"host":"compute2", "host":"compute4",
"flavor_name":"aypos.test.flavour.11", "flavor_name":"aypos.test.flavour.11",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"BLC-AYPOS-Development-0", "BLC-AYPOS-Development-0",
3, 3,
3, 3,
8, 8,
"compute2" "compute4"
] ]
}, },
"10.150.1.145":{ "10.150.1.145":{
"vm_name":"BLC-AYPOS-Development-9", "vm_name":"BLC-AYPOS-Development-9",
"power":12.464360819208926, "power":14.950904196341009,
"state":"active", "state":"active",
"hosting_pm":"10.150.1.33", "hosting_pm":"10.150.1.33",
"host":"compute2", "host":"compute2",
"flavor_name":"aypos.test.flavour.0", "flavor_name":"aypos.test.flavour.0",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"BLC-AYPOS-Development-9", "BLC-AYPOS-Development-9",
2, 2,
@@ -244,7 +219,14 @@
"hosting_pm":"10.150.1.32", "hosting_pm":"10.150.1.32",
"host":"compute1", "host":"compute1",
"flavor_name":"m1.xlarge", "flavor_name":"m1.xlarge",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"blc-cloud", "blc-cloud",
8, 8,
@@ -260,7 +242,14 @@
"hosting_pm":"10.150.1.35", "hosting_pm":"10.150.1.35",
"host":"compute4", "host":"compute4",
"flavor_name":"m1.vrealize", "flavor_name":"m1.vrealize",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"Aypos-Ulak", "Aypos-Ulak",
8, 8,
@@ -276,7 +265,14 @@
"hosting_pm":"10.150.1.33", "hosting_pm":"10.150.1.33",
"host":"compute2", "host":"compute2",
"flavor_name":"ayposYedek", "flavor_name":"ayposYedek",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"prometheus_serverV3", "prometheus_serverV3",
2, 2,
@@ -292,7 +288,14 @@
"hosting_pm":"10.150.1.35", "hosting_pm":"10.150.1.35",
"host":"compute4", "host":"compute4",
"flavor_name":"m1.devstack", "flavor_name":"m1.devstack",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"blc-meet", "blc-meet",
4, 4,
@@ -308,7 +311,14 @@
"hosting_pm":"10.150.1.32", "hosting_pm":"10.150.1.32",
"host":"compute1", "host":"compute1",
"flavor_name":"m1.large", "flavor_name":"m1.large",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"blc-office", "blc-office",
4, 4,
@@ -324,7 +334,14 @@
"hosting_pm":"10.150.1.35", "hosting_pm":"10.150.1.35",
"host":"compute4", "host":"compute4",
"flavor_name":"mail-server", "flavor_name":"mail-server",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"mail-server", "mail-server",
4, 4,
@@ -335,49 +352,65 @@
}, },
"10.150.1.175":{ "10.150.1.175":{
"vm_name":"BLC-AYPOS-Development-7", "vm_name":"BLC-AYPOS-Development-7",
"power":16.084780100161176, "power":19.256314103409117,
"emissionsource":{
"dizel":30,
"coal":40,
"solar energy":30
},
"state":"active", "state":"active",
"hosting_pm":"10.150.1.33", "hosting_pm":"10.150.1.35",
"host":"compute2", "host":"compute4",
"flavor_name":"aypos.test.flavour.19", "flavor_name":"aypos.test.flavour.19",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"BLC-AYPOS-Development-7", "BLC-AYPOS-Development-7",
2, 2,
3, 3,
8, 8,
"compute2" "compute4"
] ]
}, },
"10.150.1.180":{ "10.150.1.180":{
"vm_name":"BLC-AYPOS-Development-8", "vm_name":"BLC-AYPOS-Development-8",
"power":22.454381667855632, "power":26.738567147437937,
"state":"active", "state":"active",
"hosting_pm":"10.150.1.33", "hosting_pm":"10.150.1.35",
"host":"compute2", "host":"compute4",
"flavor_name":"aypos.test.flavour.6", "flavor_name":"aypos.test.flavour.6",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"BLC-AYPOS-Development-8", "BLC-AYPOS-Development-8",
1, 1,
2, 2,
8, 8,
"compute2" "compute4"
] ]
}, },
"10.150.1.190":{ "10.150.1.190":{
"vm_name":"BLC-AYPOS-Development-6", "vm_name":"BLC-AYPOS-Development-6",
"power":36.17691364518403, "power":42.36942549990342,
"state":"active", "state":"active",
"hosting_pm":"10.150.1.33", "hosting_pm":"10.150.1.33",
"host":"compute2", "host":"compute2",
"flavor_name":"aypos.test.flavour.16", "flavor_name":"aypos.test.flavour.16",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"BLC-AYPOS-Development-6", "BLC-AYPOS-Development-6",
2, 2,
@@ -393,7 +426,14 @@
"hosting_pm":"10.150.1.34", "hosting_pm":"10.150.1.34",
"host":"compute3", "host":"compute3",
"flavor_name":"aypos.test.flavour.4", "flavor_name":"aypos.test.flavour.4",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"BLC-AYPOS-Development-4", "BLC-AYPOS-Development-4",
2, 2,
@@ -409,7 +449,14 @@
"hosting_pm":"10.150.1.33", "hosting_pm":"10.150.1.33",
"host":"compute2", "host":"compute2",
"flavor_name":"m1.large", "flavor_name":"m1.large",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"gitea-server", "gitea-server",
4, 4,
@@ -425,7 +472,14 @@
"hosting_pm":"10.150.1.35", "hosting_pm":"10.150.1.35",
"host":"compute4", "host":"compute4",
"flavor_name":"m1.vrealize", "flavor_name":"m1.vrealize",
"tag":"None", "emissionsource":{
"Dizel":10,
"Ham petrol":5,
"Orimulsion":15,
"Motor benzini":30,
"Jet benzini":40
},
"tag":"main_optimization_space",
"confg":[ "confg":[
"ollama", "ollama",
8, 8,
@@ -437,21 +491,21 @@
}, },
"pms":{ "pms":{
"10.150.1.33":{ "10.150.1.33":{
"tag":"None", "tag":"main_optimization_space",
"name":"compute2", "name":"compute2",
"power":177.83822950819666, "power":159.86075409836062,
"confg":[ "confg":[
"compute2", "compute2",
3, 11,
94, 101,
59, 91,
114 114
] ]
}, },
"10.150.1.34":{ "10.150.1.34":{
"tag":"None", "tag":"main_optimization_space",
"name":"compute3", "name":"compute3",
"power":21.3385737704918, "power":21.31772131147542,
"confg":[ "confg":[
"compute3", "compute3",
24, 24,
@@ -461,21 +515,21 @@
] ]
}, },
"10.150.1.35":{ "10.150.1.35":{
"tag":"None", "tag":"main_optimization_space",
"name":"compute4", "name":"compute4",
"power":152.66185245901653, "power":189.92359016393448,
"confg":[ "confg":[
"compute4", "compute4",
-13, -17,
28, 23,
103, 87,
114 114
] ]
}, },
"10.150.1.32":{ "10.150.1.32":{
"tag":"None", "tag":"main_optimization_space",
"name":"compute1", "name":"compute1",
"power":36.34004918032787, "power":36.45219672131149,
"confg":[ "confg":[
"compute1", "compute1",
10, 10,
@@ -491,3 +545,4 @@
} }
} }
} }
}

View File

@@ -2,8 +2,13 @@ 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.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sgs.lib.dao.domain.BaseDomain; import com.sgs.lib.dao.domain.BaseDomain;
import java.util.Map;
import java.util.HashMap;
import javax.persistence.*; import javax.persistence.*;
@Entity @Entity
@@ -18,9 +23,11 @@ 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 emissionSourceData; // JSON string to store emission source map
private Config config; private Config config;
private PhysicalMachine physicalMachine; private PhysicalMachine physicalMachine;
@Column(name = "state") @Column(name = "state")
public String getState() { public String getState() {
return state; return state;
@@ -102,6 +109,15 @@ public class VM extends BaseDomain {
this.ip = ip; this.ip = ip;
} }
@Column(name = "emission_source_data", columnDefinition = "text")
public String getEmissionSourceData() {
return emissionSourceData;
}
public void setEmissionSourceData(String emissionSourceData) {
this.emissionSourceData = emissionSourceData;
}
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "vm") @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "vm")
@JsonManagedReference @JsonManagedReference
public Config getConfig() { public Config getConfig() {
@@ -123,4 +139,33 @@ public class VM extends BaseDomain {
this.physicalMachine = physicalMachine; this.physicalMachine = physicalMachine;
} }
// Helper methods for emission source map
@Transient
public Map<String, Integer> getEmissionSource() {
if (emissionSourceData == null || emissionSourceData.trim().isEmpty()) {
return new HashMap<>();
}
try {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(emissionSourceData, new TypeReference<Map<String, Integer>>() {});
} catch (Exception e) {
System.err.println("Error parsing emission source data: " + e.getMessage());
return new HashMap<>();
}
}
public void setEmissionSource(Map<String, Integer> emissionSource) {
if (emissionSource == null) {
this.emissionSourceData = null;
return;
}
try {
ObjectMapper mapper = new ObjectMapper();
this.emissionSourceData = mapper.writeValueAsString(emissionSource);
} catch (Exception e) {
System.err.println("Error serializing emission source data: " + e.getMessage());
this.emissionSourceData = null;
}
}
} }

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 VMDto { public class VMDto {
@JsonProperty("vm_name") @JsonProperty("vm_name")
@@ -28,6 +29,9 @@ public class VMDto {
@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("emissionsource")
private Map<String, Integer> emissionSource;
private String ip; // IP address from the message key private String ip; // IP address from the message key
private boolean calcOn = false; // Derived from state: active = true, inactive = false private boolean calcOn = false; // Derived from state: active = true, inactive = false
@@ -113,6 +117,14 @@ public class VMDto {
this.calcOn = calcOn; this.calcOn = calcOn;
} }
public Map<String, Integer> getEmissionSource() {
return emissionSource;
}
public void setEmissionSource(Map<String, Integer> emissionSource) {
this.emissionSource = emissionSource;
}
// Helper method to get config as ConfigDto // Helper method to get config as ConfigDto
public ConfigDto getConfig() { public ConfigDto getConfig() {
if (confg != null && confg.size() >= 5) { if (confg != null && confg.size() >= 5) {

View File

@@ -92,7 +92,14 @@ public class MessageListener {
DataCenter entity = toDataCenterEntity(dto); DataCenter entity = toDataCenterEntity(dto);
DataCenter dataCenter = createDataCenter(entity); DataCenter dataCenter = createDataCenter(entity);
processEmissionCalculations(dataCenter);
// Save message processing success log
systemLogger.createSystemLog(LogType.INFO,
"VM data processed successfully for DataCenter ID: " + dataCenter.getExternalId());
// Process emission calculations in a separate transaction to avoid rollback issues
// This will be done asynchronously after the VM data is committed
processEmissionCalculationsAsync(dataCenter);
// 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);
@@ -117,7 +124,11 @@ public class MessageListener {
//System.out.println("✅ Saved DataCenter:\n" + objectMapper.writeValueAsString(dataCenter)); //System.out.println("✅ Saved DataCenter:\n" + objectMapper.writeValueAsString(dataCenter));
} catch (Exception e) { } catch (Exception e) {
System.err.println("Mesaj işlenirken hata oluştu: " + e.getMessage()); System.err.println("Mesaj işlenirken hata oluştu: " + e.getMessage());
e.printStackTrace();
systemLogger.createSystemLog(LogType.ERROR,
"Error processing VM message: " + e.getMessage());
// Don't rethrow the exception to prevent transaction rollback
} }
} }
@@ -153,8 +164,14 @@ public class MessageListener {
// Handle config from confg array // Handle config from confg array
entity.setConfig(toConfigEntity(dto.getConfig())); entity.setConfig(toConfigEntity(dto.getConfig()));
// Handle emission source map
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());
if (dto.getEmissionSource() != null && !dto.getEmissionSource().isEmpty()) {
System.out.println(" Emission Sources: " + dto.getEmissionSource());
}
return entity; return entity;
} }
@@ -401,6 +418,7 @@ public class MessageListener {
vm.setHost(newVm.getHost()); vm.setHost(newVm.getHost());
vm.setFlavorName(newVm.getFlavorName()); vm.setFlavorName(newVm.getFlavorName());
vm.setTag(newVm.getTag()); vm.setTag(newVm.getTag());
vm.setEmissionSource(newVm.getEmissionSource());
System.out.println("✅ Updated existing VM: " + vm.getVmName() + " (IP: " + vm.getIp() + ") - calcOn = " + vm.getCalcOn()); System.out.println("✅ Updated existing VM: " + vm.getVmName() + " (IP: " + vm.getIp() + ") - calcOn = " + vm.getCalcOn());
} else { } else {
@@ -450,6 +468,32 @@ public class MessageListener {
} }
/**
* Process emission calculations asynchronously to avoid transaction conflicts
*/
public void processEmissionCalculationsAsync(DataCenter dataCenter) {
// Run emission calculations in a separate thread to avoid transaction issues
new Thread(() -> {
try {
// Wait a bit to ensure the transaction is committed and VMs have IDs
Thread.sleep(2000);
// Refresh the DataCenter to get the latest state with VM IDs
Optional<DataCenter> refreshedDcOpt = dataCenterRepo.findByExternalId(dataCenter.getExternalId());
if (refreshedDcOpt.isPresent()) {
DataCenter refreshedDc = refreshedDcOpt.get();
System.out.println("🔄 Processing emission calculations asynchronously for DataCenter: " + refreshedDc.getDataCenter());
processEmissionCalculations(refreshedDc);
} else {
System.err.println("❌ Could not find DataCenter for emission calculations: " + dataCenter.getExternalId());
}
} catch (Exception e) {
System.err.println("❌ Error in async emission calculations: " + e.getMessage());
e.printStackTrace();
}
}).start();
}
public void processEmissionCalculations(DataCenter dataCenter) { public void processEmissionCalculations(DataCenter dataCenter) {
System.out.println("🔍 Starting VM-level emission calculations for DataCenter ID: " + dataCenter.getId() + System.out.println("🔍 Starting VM-level emission calculations for DataCenter ID: " + dataCenter.getId() +
" (Name: " + dataCenter.getDataCenter() + ")"); " (Name: " + dataCenter.getDataCenter() + ")");
@@ -476,7 +520,10 @@ public class MessageListener {
" (Name: " + dataCenter.getDataCenter() + ")"); " (Name: " + dataCenter.getDataCenter() + ")");
int totalVMs = 0; int totalVMs = 0;
int eligibleVMs = 0; int eligibleVMs = 0;
int processedVMs = 0;
int successfulCalculations = 0; int successfulCalculations = 0;
int failedCalculations = 0;
int totalEmissionSources = 0;
for (Project project : dataCenter.getProjects()) { for (Project project : dataCenter.getProjects()) {
for (PhysicalMachine pm : project.getPhysicalMachines()) { for (PhysicalMachine pm : project.getPhysicalMachines()) {
@@ -488,8 +535,37 @@ public class MessageListener {
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++;
// Check if VM has emission sources
Map<String, Integer> emissionSources = vm.getEmissionSource();
if (emissionSources != null && !emissionSources.isEmpty()) {
// Create separate emission record for each emission source
System.out.println("🔍 VM has " + emissionSources.size() + " emission sources");
totalEmissionSources += emissionSources.size();
for (Map.Entry<String, Integer> sourceEntry : emissionSources.entrySet()) {
String sourceName = sourceEntry.getKey();
Integer percentage = sourceEntry.getValue();
System.out.println(" - " + 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); boolean success = createVMEmissionRecord(dataCenter, vm, project, pm);
if (success) successfulCalculations++; if (success) {
successfulCalculations++;
} else {
failedCalculations++;
}
}
} else { } else {
System.out.println("⚠️ Skipping VM " + vm.getVmName() + " (calcOn = true) - no power consumption data"); System.out.println("⚠️ Skipping VM " + vm.getVmName() + " (calcOn = true) - no power consumption data");
} }
@@ -504,13 +580,21 @@ public class MessageListener {
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);
System.out.println(" VMs processed for emissions: " + processedVMs);
System.out.println(" VMs skipped (calcOn = false or null): " + (totalVMs - eligibleVMs)); System.out.println(" VMs skipped (calcOn = false or null): " + (totalVMs - eligibleVMs));
System.out.println(" Total emission source calculations: " + totalEmissionSources);
System.out.println(" Successful emission calculations: " + successfulCalculations); System.out.println(" Successful emission calculations: " + successfulCalculations);
System.out.println(" Failed calculations: " + (eligibleVMs - successfulCalculations)); 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, Project project, PhysicalMachine pm) {
try { try {
// Check if VM has an ID (is persisted)
if (vm.getId() == null) {
System.err.println("❌ VM " + vm.getVmName() + " has no ID - cannot create emission record");
return false;
}
MainDataTableCreateInput input = createVMMainDataTableInput(dataCenter, vm, project, pm); MainDataTableCreateInput input = createVMMainDataTableInput(dataCenter, vm, project, 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)");
@@ -535,6 +619,52 @@ public class MessageListener {
} }
} }
private boolean createVMEmissionRecordForSource(DataCenter dataCenter, VM vm, Project project, PhysicalMachine pm, String emissionSourceName, Integer percentage) {
try {
// Check if VM has an ID (is persisted)
if (vm.getId() == null) {
System.err.println("❌ VM " + vm.getVmName() + " has no ID - cannot create emission record for source " + emissionSourceName);
return false;
}
// Find the emission source by name/tag
List<EmissionSource> emissionSources = emissionSourceRepo.findByTag(emissionSourceName);
if (emissionSources.isEmpty()) {
System.err.println("❌ Could not find emission source: " + emissionSourceName);
return false;
}
EmissionSource emissionSource = emissionSources.get(0);
// Calculate power consumption for this emission source (percentage of total VM power)
double sourceSpecificPower = vm.getPower() * (percentage / 100.0);
MainDataTableCreateInput input = createVMMainDataTableInputForSource(dataCenter, vm, project, pm, emissionSource, sourceSpecificPower, percentage);
System.out.println("🔍 Creating emission record for VM: " + vm.getVmName() +
" - Source: " + emissionSourceName + " (" + percentage + "%) - Power: " + sourceSpecificPower + "W");
MainDataTable result = callMainDataTableMutation(input);
if (result != null) {
System.out.println("✅ VM Emission calculation completed for source " + emissionSourceName + ":");
System.out.println(" - VM: " + vm.getVmName());
System.out.println(" - Emission Source: " + emissionSourceName + " (" + percentage + "%)");
System.out.println(" - Power: " + sourceSpecificPower + "W");
System.out.println(" - CO2: " + result.getCo2());
System.out.println(" - Total Emission: " + result.getTotalEmission());
System.out.println(" - Record ID: " + result.getId());
return true;
} else {
System.err.println("❌ Failed to create emission record for VM: " + vm.getVmName() + " - Source: " + emissionSourceName);
return false;
}
} catch (Exception e) {
System.err.println("❌ Error calculating emissions for VM " + vm.getVmName() + " - Source: " + emissionSourceName + ": " + e.getMessage());
return false;
}
}
private MainDataTableCreateInput createVMMainDataTableInput(DataCenter dataCenter, VM vm, Project project, PhysicalMachine pm) { private MainDataTableCreateInput createVMMainDataTableInput(DataCenter dataCenter, VM vm, Project project, PhysicalMachine pm) {
MainDataTableCreateInput input = new MainDataTableCreateInput(); MainDataTableCreateInput input = new MainDataTableCreateInput();
@@ -615,6 +745,76 @@ public class MessageListener {
return input; return input;
} }
private MainDataTableCreateInput createVMMainDataTableInputForSource(DataCenter dataCenter, VM vm, Project project, PhysicalMachine pm, EmissionSource emissionSource, double sourceSpecificPower, Integer percentage) {
MainDataTableCreateInput input = new MainDataTableCreateInput();
// Copy datacenter-level information (if available)
input.setYear("2025");
input.setMonth("07");
// Note: These fields are no longer received in the message
// They need to be set via DataCenter CRUD operations first
if (dataCenter.getArea() != null && !dataCenter.getArea().getCities().isEmpty()) {
input.setCity(dataCenter.getArea().getCities().get(0).getId());
}
if (dataCenter.getArea() != null && !dataCenter.getArea().getDistricts().isEmpty()) {
input.setDistrict(dataCenter.getArea().getDistricts().get(0).getId());
}
if (dataCenter.getSector() != null) {
input.setSector(dataCenter.getSector().getId());
} else {
System.out.println("⚠️ Warning: DataCenter has no sector set - emission calculation may fail");
}
if (dataCenter.getSubSector() != null) {
input.setSubSector(dataCenter.getSubSector().getId());
}
// Use the specific emission source for this calculation
input.setEmissionSource(emissionSource.getId());
if (dataCenter.getActivitySubUnit() != null) {
input.setActivitySubUnit(dataCenter.getActivitySubUnit().getId());
}
if (dataCenter.getConsuptionUnit() != null) {
input.setConsuptionUnit(dataCenter.getConsuptionUnit().getId());
}
// Default to Kapsam-3 if no emission scope is set
input.setScope(dataCenter.getEmissionScope() != null ?
dataCenter.getEmissionScope().getTag().equals("Kapsam-3") : true);
try {
List<Organization> organizations = organizationRepo.findAll();
if (!organizations.isEmpty()) {
input.setOrganization(organizations.get(0).getId());
}
} catch (Exception e) {
System.err.println("❌ Error finding organization: " + e.getMessage());
}
// Set VM-specific fields
input.setVmId(vm.getId());
// Use the source-specific power consumption (percentage of total VM power)
input.setConsuptionAmount(String.valueOf(sourceSpecificPower));
System.out.println("🔍 VM Emission Input for Source:");
System.out.println(" VM ID: " + vm.getId());
System.out.println(" VM Name: " + vm.getVmName());
System.out.println(" Emission Source: " + emissionSource.getTag());
System.out.println(" Percentage: " + percentage + "%");
System.out.println(" Source Power: " + sourceSpecificPower + "W");
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"));
return input;
}
private void setupSecurityContext() { private void setupSecurityContext() {
User systemUser = new User("system", "", Collections.singletonList(new SimpleGrantedAuthority("dataset_create"))); User systemUser = new User("system", "", Collections.singletonList(new SimpleGrantedAuthority("dataset_create")));
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(systemUser, null, systemUser.getAuthorities()); UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(systemUser, null, systemUser.getAuthorities());

View File

@@ -17,14 +17,14 @@ 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=localhost
# spring.rabbitmq.port=5672 # spring.rabbitmq.port=5672
# spring.rabbitmq.username=guest # spring.rabbitmq.username=testuser
# spring.rabbitmq.password=guest # spring.rabbitmq.password=JGasF24561AZv2894De
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
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

View File

@@ -47,9 +47,12 @@ type Vm {
host: String host: String
flavorName: String flavorName: String
tag: String tag: String
emissionSource: EmissionSourceMap
config: Config config: Config
} }
scalar EmissionSourceMap
type Config { type Config {
id: ID id: ID
cpu: Int cpu: Int

View File

@@ -26,6 +26,7 @@ type MainDataTable {
proteinAmount:Float proteinAmount:Float
burnOrOpenBurn:Boolean burnOrOpenBurn:Boolean
scopeCheck:Boolean scopeCheck:Boolean
vm: Vm
} }