2626import java .nio .file .Paths ;
2727import java .security .InvalidParameterException ;
2828import java .util .ArrayList ;
29- import java .util .Arrays ;
3029import java .util .Collection ;
3130import java .util .Collections ;
3231import java .util .Comparator ;
158157import com .cloud .utils .db .SearchCriteria ;
159158import com .cloud .utils .db .Transaction ;
160159import com .cloud .utils .db .TransactionCallbackWithException ;
161- import com .google .gson .JsonArray ;
162160import com .google .gson .JsonElement ;
163161import com .google .gson .JsonObject ;
164162import com .google .gson .JsonParser ;
168166import com .cloud .vm .VirtualMachineProfile ;
169167import com .cloud .vm .VirtualMachineProfileImpl ;
170168import com .cloud .vm .VmDetailConstants ;
171- import com .cloud .vm .dao .VMInstanceDao ;
172169
173170public 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