Skip to content

Commit d9e6392

Browse files
committed
NE: apply Vishesh's suggestion part3
1 parent b048f66 commit d9e6392

6 files changed

Lines changed: 169 additions & 322 deletions

File tree

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,7 +1716,8 @@ public void implementNetworkElementsAndResources(final DeployDestination dest, f
17161716
}
17171717
}
17181718

1719-
for (final NetworkElement element : getNetworkElementsIncludingExtensions()) {
1719+
List<NetworkElement> allNetworkElements = getNetworkElementsIncludingExtensions();
1720+
for (final NetworkElement element : allNetworkElements) {
17201721
if (element instanceof AggregatedCommandExecutor && providersToImplement.contains(element.getProvider())) {
17211722
((AggregatedCommandExecutor) element).prepareAggregatedExecution(network, dest);
17221723
}
@@ -1733,7 +1734,7 @@ public void implementNetworkElementsAndResources(final DeployDestination dest, f
17331734
ex.addProxyObject(_entityMgr.findById(DataCenter.class, network.getDataCenterId()).getUuid());
17341735
throw ex;
17351736
}
1736-
for (final NetworkElement element : getNetworkElementsIncludingExtensions()) {
1737+
for (final NetworkElement element : allNetworkElements) {
17371738
if (element instanceof AggregatedCommandExecutor && providersToImplement.contains(element.getProvider())) {
17381739
if (!((AggregatedCommandExecutor) element).completeAggregatedExecution(network, dest)) {
17391740
logger.warn("Failed to re-program the network as a part of network {} implement due to aggregated commands execution failure!", network);
@@ -1747,7 +1748,7 @@ public void implementNetworkElementsAndResources(final DeployDestination dest, f
17471748
}
17481749
reconfigureAndApplyStaticRouteForVpcVpn(network);
17491750
} finally {
1750-
for (final NetworkElement element : getNetworkElementsIncludingExtensions()) {
1751+
for (final NetworkElement element : allNetworkElements) {
17511752
if (element instanceof AggregatedCommandExecutor && providersToImplement.contains(element.getProvider())) {
17521753
((AggregatedCommandExecutor) element).cleanupAggregatedExecution(network, dest);
17531754
}

framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/manager/ExtensionsManagerImpl.java

Lines changed: 32 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import java.nio.file.Paths;
2727
import java.security.InvalidParameterException;
2828
import java.util.ArrayList;
29-
import java.util.Arrays;
3029
import java.util.Collection;
3130
import java.util.Collections;
3231
import java.util.Comparator;
@@ -158,7 +157,6 @@
158157
import com.cloud.utils.db.SearchCriteria;
159158
import com.cloud.utils.db.Transaction;
160159
import com.cloud.utils.db.TransactionCallbackWithException;
161-
import com.google.gson.JsonArray;
162160
import com.google.gson.JsonElement;
163161
import com.google.gson.JsonObject;
164162
import com.google.gson.JsonParser;
@@ -168,7 +166,6 @@
168166
import com.cloud.vm.VirtualMachineProfile;
169167
import com.cloud.vm.VirtualMachineProfileImpl;
170168
import com.cloud.vm.VmDetailConstants;
171-
import com.cloud.vm.dao.VMInstanceDao;
172169

173170
public class ExtensionsManagerImpl extends ManagerBase implements ExtensionsManager, ExtensionHelper, PluggableService, Configurable {
174171

@@ -216,9 +213,6 @@ public class ExtensionsManagerImpl extends ManagerBase implements ExtensionsMana
216213
@Inject
217214
ExtensionCustomActionDetailsDao extensionCustomActionDetailsDao;
218215

219-
@Inject
220-
VMInstanceDao vmInstanceDao;
221-
222216
@Inject
223217
VirtualMachineManager virtualMachineManager;
224218

@@ -288,7 +282,7 @@ protected String getValidatedExtensionRelativePath(String name, String relativeP
288282

289283
protected Pair<Boolean, String> getResultFromAnswersString(String answersStr, Extension extension,
290284
ManagementServerHostVO msHost, String op) {
291-
Answer[] answers = null;
285+
Answer[] answers;
292286
try {
293287
answers = GsonHelper.getGson().fromJson(answersStr, Answer[].class);
294288
} catch (Exception e) {
@@ -461,10 +455,7 @@ protected Extension getExtensionWithCustomActionFromResource(ExtensionCustomActi
461455
// This correctly handles multiple different extensions on the same physical network.
462456
String providerName = networkServiceMapDao.getProviderForServiceInNetwork(network.getId(), Service.CustomAction);
463457
if (providerName != null) {
464-
Extension ext = getExtensionForPhysicalNetworkAndProvider(physicalNetworkId, providerName);
465-
if (ext != null) {
466-
return ext;
467-
}
458+
return getExtensionForPhysicalNetworkAndProvider(physicalNetworkId, providerName);
468459
}
469460
return null;
470461
} else if (ExtensionCustomAction.ResourceType.Vpc.equals(resourceType)) {
@@ -1135,7 +1126,7 @@ protected ExtensionResourceMap registerExtensionWithPhysicalNetwork(PhysicalNetw
11351126
}
11361127

11371128
// Resolve which services this extension provides from its network.services detail
1138-
Set<String> services = resolveExtensionServices(extension);
1129+
Set<Service> services = resolveExtensionServices(extension);
11391130

11401131
return Transaction.execute((TransactionCallbackWithException<ExtensionResourceMap, CloudRuntimeException>) status -> {
11411132
// 1. Persist the extension<->physical-network mapping
@@ -1178,9 +1169,9 @@ protected ExtensionResourceMap registerExtensionWithPhysicalNetwork(PhysicalNetw
11781169
* Resolves the set of network service names declared in the extension's
11791170
* {@code network.services} detail. Falls back to an empty set if not present
11801171
*/
1181-
private Set<String> resolveExtensionServices(Extension extension) {
1172+
private Set<Service> resolveExtensionServices(Extension extension) {
11821173
Map<String, String> extDetails = extensionDetailsDao.listDetailsKeyPairs(extension.getId());
1183-
Set<String> parsed = parseNetworkServicesFromDetailKeys(extDetails);
1174+
Set<Service> parsed = parseNetworkServicesFromDetailKeys(extDetails);
11841175
if (!parsed.isEmpty()) {
11851176
return parsed;
11861177
}
@@ -1192,19 +1183,19 @@ private Set<String> resolveExtensionServices(Extension extension) {
11921183
* Resolves the set of service names from the extension detail map.
11931184
* From {@code network.services} comma-separated key.
11941185
*/
1195-
private Set<String> parseNetworkServicesFromDetailKeys(Map<String, String> extDetails) {
1186+
private Set<Service> parseNetworkServicesFromDetailKeys(Map<String, String> extDetails) {
11961187
if (extDetails == null) {
11971188
return Collections.emptySet();
11981189
}
11991190
// New format: "network.services" = "SourceNat,StaticNat,..."
12001191
if (extDetails.containsKey(ExtensionHelper.NETWORK_SERVICES_DETAIL_KEY)) {
12011192
String value = extDetails.get(ExtensionHelper.NETWORK_SERVICES_DETAIL_KEY);
12021193
if (StringUtils.isNotBlank(value)) {
1203-
Set<String> services = new HashSet<>();
1194+
Set<Service> services = new HashSet<>();
12041195
for (String s : value.split(",")) {
1205-
String trimmed = s.trim();
1206-
if (!trimmed.isEmpty()) {
1207-
services.add(trimmed);
1196+
Service service = Network.Service.getService(s.trim());
1197+
if (service != null) {
1198+
services.add(service);
12081199
}
12091200
}
12101201
if (!services.isEmpty()) {
@@ -1228,7 +1219,7 @@ private Map<Service, Map<Capability, String>> buildCapabilitiesFromDetailKeys(
12281219
}
12291220
// New split format
12301221
if (extDetails.containsKey(ExtensionHelper.NETWORK_SERVICES_DETAIL_KEY)) {
1231-
Set<String> serviceNames = parseNetworkServicesFromDetailKeys(extDetails);
1222+
Set<Service> serviceNames = parseNetworkServicesFromDetailKeys(extDetails);
12321223
if (!serviceNames.isEmpty()) {
12331224
JsonObject capsObj = null;
12341225
if (extDetails.containsKey(ExtensionHelper.NETWORK_SERVICE_CAPABILITIES_DETAIL_KEY)) {
@@ -1241,15 +1232,10 @@ private Map<Service, Map<Capability, String>> buildCapabilitiesFromDetailKeys(
12411232
}
12421233
}
12431234
Map<Service, Map<Capability, String>> result = new HashMap<>();
1244-
for (String svcName : serviceNames) {
1245-
Service service = Service.getService(svcName);
1246-
if (service == null) {
1247-
logger.warn("Unknown network service '{}' in network.services — skipping", svcName);
1248-
continue;
1249-
}
1235+
for (Service service : serviceNames) {
12501236
Map<Capability, String> capMap = new HashMap<>();
1251-
if (capsObj != null && capsObj.has(svcName)) {
1252-
JsonObject svcCaps = capsObj.getAsJsonObject(svcName);
1237+
if (capsObj != null && capsObj.has(service.getName())) {
1238+
JsonObject svcCaps = capsObj.getAsJsonObject(service.getName());
12531239
for (Map.Entry<String, JsonElement> entry : svcCaps.entrySet()) {
12541240
Capability cap = Capability.getCapability(entry.getKey());
12551241
if (cap != null) {
@@ -1270,85 +1256,26 @@ private Map<Service, Map<Capability, String>> buildCapabilitiesFromDetailKeys(
12701256
* Sets the boolean service-provided flags on a {@link PhysicalNetworkServiceProviderVO}
12711257
* based on a set of service names.
12721258
*/
1273-
private void applyServicesToNsp(PhysicalNetworkServiceProviderVO nsp, Set<String> services) {
1274-
nsp.setSourcenatServiceProvided(services.contains("SourceNat"));
1275-
nsp.setStaticnatServiceProvided(services.contains("StaticNat"));
1276-
nsp.setPortForwardingServiceProvided(services.contains("PortForwarding"));
1277-
nsp.setFirewallServiceProvided(services.contains("Firewall"));
1278-
nsp.setGatewayServiceProvided(services.contains("Gateway"));
1279-
nsp.setDnsServiceProvided(services.contains("Dns"));
1280-
nsp.setDhcpServiceProvided(services.contains("Dhcp"));
1281-
nsp.setUserdataServiceProvided(services.contains("UserData"));
1282-
nsp.setLbServiceProvided(services.contains("Lb"));
1283-
nsp.setVpnServiceProvided(services.contains("Vpn"));
1284-
nsp.setSecuritygroupServiceProvided(services.contains("SecurityGroup"));
1285-
nsp.setNetworkAclServiceProvided(services.contains("NetworkACL"));
1286-
nsp.setCustomActionServiceProvided(services.contains("CustomAction"));
1259+
private void applyServicesToNsp(PhysicalNetworkServiceProviderVO nsp, Set<Service> services) {
1260+
nsp.setSourcenatServiceProvided(services.contains(Service.SourceNat));
1261+
nsp.setStaticnatServiceProvided(services.contains(Service.StaticNat));
1262+
nsp.setPortForwardingServiceProvided(services.contains(Service.PortForwarding));
1263+
nsp.setFirewallServiceProvided(services.contains(Service.Firewall));
1264+
nsp.setGatewayServiceProvided(services.contains(Service.Gateway));
1265+
nsp.setDnsServiceProvided(services.contains(Service.Dns));
1266+
nsp.setDhcpServiceProvided(services.contains(Service.Dhcp));
1267+
nsp.setUserdataServiceProvided(services.contains(Service.UserData));
1268+
nsp.setLbServiceProvided(services.contains(Service.Lb));
1269+
nsp.setVpnServiceProvided(services.contains(Service.Vpn));
1270+
nsp.setSecuritygroupServiceProvided(services.contains(Service.SecurityGroup));
1271+
nsp.setNetworkAclServiceProvided(services.contains(Service.NetworkACL));
1272+
nsp.setCustomActionServiceProvided(services.contains(Service.CustomAction));
12871273
}
12881274

12891275
/** Keys that are always stored with display=false (sensitive). */
12901276
private static final Set<String> SENSITIVE_DETAIL_KEYS =
12911277
Set.of("password", "sshkey");
12921278

1293-
/**
1294-
* Validates that the comma-separated or JSON-array {@code servicesValue} is a
1295-
* subset of the services declared in the extension's {@code network.services}
1296-
* Throws {@link InvalidParameterValueException} if any service in the request is not
1297-
* offered by the extension.
1298-
*/
1299-
protected void validateNetworkServicesSubset(Extension extension, String servicesValue) {
1300-
if (StringUtils.isBlank(servicesValue)) {
1301-
return;
1302-
}
1303-
Map<String, String> extDetails = extensionDetailsDao.listDetailsKeyPairs(extension.getId());
1304-
Set<String> allowedServices = parseNetworkServicesFromDetailKeys(extDetails);
1305-
if (allowedServices.isEmpty()) {
1306-
// No services declared → accept any
1307-
return;
1308-
}
1309-
1310-
// Parse the requested services: either comma-separated string or JSON array
1311-
List<String> requested = parseServicesList(servicesValue);
1312-
List<String> invalid = requested.stream()
1313-
.filter(s -> !allowedServices.contains(s))
1314-
.collect(Collectors.toList());
1315-
if (!invalid.isEmpty()) {
1316-
throw new InvalidParameterValueException(String.format(
1317-
"The following services are not supported by extension '%s': %s. "
1318-
+ "Supported services are: %s",
1319-
extension.getName(), invalid, allowedServices));
1320-
}
1321-
}
1322-
1323-
/**
1324-
* Parses a services list from either a comma-separated string (e.g.
1325-
* {@code "SourceNat,StaticNat"}) or a JSON array (e.g.
1326-
* {@code ["SourceNat","StaticNat"]}).
1327-
*/
1328-
private List<String> parseServicesList(String value) {
1329-
if (StringUtils.isBlank(value)) {
1330-
return Collections.emptyList();
1331-
}
1332-
value = value.trim();
1333-
if (value.startsWith("[")) {
1334-
try {
1335-
JsonArray arr = JsonParser.parseString(value).getAsJsonArray();
1336-
List<String> result = new ArrayList<>();
1337-
for (JsonElement el : arr) {
1338-
result.add(el.getAsString().trim());
1339-
}
1340-
return result;
1341-
} catch (Exception e) {
1342-
// fall through to comma-split
1343-
}
1344-
}
1345-
// Comma-separated
1346-
return Arrays.stream(value.split(","))
1347-
.map(String::trim)
1348-
.filter(s -> !s.isEmpty())
1349-
.collect(Collectors.toList());
1350-
}
1351-
13521279
@Override
13531280
@ActionEvent(eventType = EventTypes.EVENT_EXTENSION_RESOURCE_UNREGISTER, eventDescription = "unregistering extension resource")
13541281
public Extension unregisterExtensionWithResource(UnregisterExtensionCmd cmd) {
@@ -1894,7 +1821,7 @@ private CustomActionResultResponse runVirtualMachineCustomAction(VirtualMachine
18941821
runCustomActionCommand.setVmTO(virtualMachineTO);
18951822
Pair<Long, Long> clusterAndHostId = virtualMachineManager.findClusterAndHostIdForVm(virtualMachine, false);
18961823

1897-
Long clusterId = clusterAndHostId.first();;
1824+
Long clusterId = clusterAndHostId.first();
18981825
Long hostId = clusterAndHostId.second();
18991826
if (clusterId == null || hostId == null) {
19001827
logger.error(
@@ -1944,7 +1871,7 @@ private CustomActionResultResponse runVirtualMachineCustomAction(VirtualMachine
19441871
runCustomActionCommand.setWait(customActionVO.getTimeout());
19451872
try {
19461873
logger.info("Running custom action: {} with {} parameters", actionName,
1947-
(parameters != null ? parameters.keySet().size() : 0));
1874+
(parameters != null ? parameters.size() : 0));
19481875
Answer answer = agentMgr.send(hostId, runCustomActionCommand);
19491876
if (!(answer instanceof RunCustomActionAnswer)) {
19501877
logger.error("Unexpected answer [{}] received for {}", answer.getClass().getSimpleName(),
@@ -2003,7 +1930,7 @@ protected CustomActionResultResponse runNetworkCustomAction(Network network,
20031930
}
20041931

20051932
// Find the provider name for this network
2006-
String providerName = networkServiceMapDao.getProviderForServiceInNetwork(network.getId(), Service.CustomAction);;
1933+
String providerName = networkServiceMapDao.getProviderForServiceInNetwork(network.getId(), Service.CustomAction);
20071934
if (StringUtils.isBlank(providerName)) {
20081935
logger.error("No network service provider found for network {}", network);
20091936
result.put(ApiConstants.DETAILS, "No network service provider found for this network");
@@ -2091,7 +2018,7 @@ protected CustomActionResultResponse runVpcCustomAction(Vpc vpc,
20912018
}
20922019

20932020
// Find the provider name for this VPC
2094-
String providerName = vpcServiceMapDao.getProviderForServiceInVpc(vpc.getId(), Service.CustomAction);;
2021+
String providerName = vpcServiceMapDao.getProviderForServiceInVpc(vpc.getId(), Service.CustomAction);
20952022
if (StringUtils.isBlank(providerName)) {
20962023
logger.error("No VPC service provider found for VPC {}", vpc.getId());
20972024
result.put(ApiConstants.DETAILS, "No VPC service provider found for this VPC");

0 commit comments

Comments
 (0)