This is an automated email from the ASF dual-hosted git repository.

DaanHoogland pushed a commit to branch ghi3360-parameterisedParameters
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit ee65ee97b789f56f05a5dec934b2bd75ecbefec0
Author: Daan Hoogland <[email protected]>
AuthorDate: Wed Nov 4 17:58:40 2026 +0100

    techdebt: parameterise map typed API parameters
---
 .../apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java  |  8 +++-----
 .../api/command/admin/account/UpdateAccountCmd.java        |  9 +++------
 .../api/command/admin/cluster/AddClusterCmd.java           |  2 +-
 .../api/command/admin/cluster/UpdateClusterCmd.java        |  2 +-
 .../cloudstack/api/command/admin/guest/AddGuestOsCmd.java  |  4 ++--
 .../api/command/admin/guest/UpdateGuestOsCmd.java          |  2 +-
 .../cloudstack/api/command/admin/host/AddHostCmd.java      |  2 +-
 .../api/command/admin/host/AddSecondaryStorageCmd.java     |  2 +-
 .../cloudstack/api/command/admin/host/UpdateHostCmd.java   |  2 +-
 .../api/command/admin/network/NetworkOfferingBaseCmd.java  |  2 +-
 .../api/command/admin/network/bgp/CreateBgpPeerCmd.java    |  5 ++---
 .../api/command/admin/network/bgp/UpdateBgpPeerCmd.java    |  5 ++---
 .../api/command/admin/offering/CreateDiskOfferingCmd.java  |  2 +-
 .../command/admin/offering/CreateServiceOfferingCmd.java   |  4 ++--
 .../command/admin/offering/UpdateServiceOfferingCmd.java   |  2 +-
 .../api/command/admin/storage/AddImageStoreCmd.java        |  4 ++--
 .../api/command/admin/storage/AddObjectStoragePoolCmd.java |  4 ++--
 .../api/command/admin/storage/CreateStoragePoolCmd.java    |  4 ++--
 .../admin/storage/UpdateCloudToUseObjectStoreCmd.java      |  4 ++--
 .../api/command/admin/storage/UpdateStoragePoolCmd.java    |  6 +++---
 .../admin/vm/CheckVmwareCbtMigrationPrerequisitesCmd.java  |  2 +-
 .../api/command/admin/vm/StartVmwareCbtMigrationCmd.java   |  2 +-
 .../cloudstack/api/command/admin/zone/UpdateZoneCmd.java   |  4 ++--
 .../user/autoscale/CreateAutoScaleVmProfileCmd.java        |  2 +-
 .../user/autoscale/UpdateAutoScaleVmProfileCmd.java        |  2 +-
 .../bootgroup/CreateInstanceBootGroupReadinessRuleCmd.java |  5 ++---
 .../bootgroup/UpdateInstanceBootGroupReadinessRuleCmd.java |  5 ++---
 .../cloudstack/api/command/user/dns/AddDnsServerCmd.java   |  2 +-
 .../command/user/schedule/CreateResourceScheduleCmd.java   |  2 +-
 .../command/user/schedule/UpdateResourceScheduleCmd.java   |  2 +-
 .../api/command/user/template/CreateTemplateCmd.java       |  9 +++------
 .../user/template/GetUploadParamsForTemplateCmd.java       |  8 +++-----
 .../api/command/user/template/RegisterTemplateCmd.java     | 11 ++++-------
 .../api/command/user/template/RegisterVnfTemplateCmd.java  |  2 +-
 .../api/command/user/template/UpdateVnfTemplateCmd.java    |  2 +-
 .../cloudstack/api/command/user/vm/BaseDeployVMCmd.java    |  8 ++++----
 .../apache/cloudstack/api/command/user/vm/DeployVMCmd.java |  2 +-
 .../cloudstack/api/command/user/vm/ResetVMUserDataCmd.java |  2 +-
 .../cloudstack/api/command/user/vm/RestoreVMCmd.java       |  2 +-
 .../apache/cloudstack/api/command/user/vm/UpdateVMCmd.java |  2 +-
 .../api/command/user/volume/AddResourceDetailCmd.java      |  4 ++--
 .../apache/cloudstack/api/response/BgpPeerResponse.java    |  6 +++---
 .../org/apache/cloudstack/api/response/HostResponse.java   | 14 +++++++-------
 .../cloudstack/api/response/NetworkOfferingResponse.java   |  4 ++--
 .../cloudstack/api/response/NetworkProtocolResponse.java   |  8 ++++----
 .../org/apache/cloudstack/api/response/UserVmResponse.java |  6 +++---
 .../cloudstack/api/response/VolumeForImportResponse.java   |  6 +++---
 .../cloudstack/api/command/user/vm/DeployVMCmdTest.java    |  4 ++--
 .../cloudstack/api/response/BgpPeerResponseTest.java       |  5 +++--
 .../api/response/VolumeForImportResponseTest.java          |  5 +++--
 .../framework/extensions/api/AddCustomActionCmd.java       |  2 +-
 .../framework/extensions/api/CreateExtensionCmd.java       |  2 +-
 .../framework/extensions/api/RegisterExtensionCmd.java     |  2 +-
 .../framework/extensions/api/UpdateCustomActionCmd.java    |  2 +-
 .../framework/extensions/api/UpdateExtensionCmd.java       |  2 +-
 .../extensions/api/UpdateRegisteredExtensionCmd.java       |  2 +-
 .../kubernetes/cluster/CreateKubernetesClusterCmd.java     |  4 ++--
 .../oauth2/api/command/RegisterOAuthProviderCmd.java       |  7 +++----
 .../cloud/storage/upload/params/TemplateUploadParams.java  |  2 +-
 .../java/com/cloud/storage/upload/params/UploadParams.java |  2 +-
 .../com/cloud/storage/upload/params/UploadParamsBase.java  |  6 +++---
 61 files changed, 115 insertions(+), 131 deletions(-)

diff --git 
a/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java 
b/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
index 94c5d8ff39f..48320bf761b 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
@@ -76,7 +76,7 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends 
BaseCmd {
     protected Boolean isRoutingType;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, 
description = "Details in key/value pairs using format 
details[i].keyname=keyvalue. Example: 
details[0].hypervisortoolsversion=xenserver61")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
             type = CommandType.BOOLEAN,
@@ -144,13 +144,11 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends 
BaseCmd {
         return isRoutingType;
     }
 
-    public Map getDetails() {
+    public Map<String, String> getDetails() {
         if (this.details == null || this.details.isEmpty()) {
             return null;
         }
-
-        Collection paramsCollection = this.details.values();
-        return (Map) (paramsCollection.toArray())[0];
+        return this.details.values().iterator().next();
     }
 
     public boolean isCleanupDetails() {
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
index b6b975ae1ce..fbafab9edf2 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
@@ -70,7 +70,7 @@ public class UpdateAccountCmd extends BaseCmd implements 
UserCmd {
     private String networkDomain;
 
     @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, 
description = "Details for the Account used to store specific parameters")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.API_KEY_ACCESS, type = CommandType.STRING, 
description = "Determines if Api key access for this user is enabled, disabled 
or inherits the value from its parent, the domain level setting 
api.key.access", since = "4.20.1.0", authorized = {RoleType.Admin})
     private String apiKeyAccess;
@@ -104,14 +104,11 @@ public class UpdateAccountCmd extends BaseCmd implements 
UserCmd {
         return networkDomain;
     }
 
-    public Map getDetails() {
+    public Map<String, String> getDetails() {
         if (details == null || details.isEmpty()) {
             return null;
         }
-
-        Collection paramsCollection = details.values();
-        Map params = (Map)(paramsCollection.toArray())[0];
-        return params;
+        return details.values().iterator().next();
     }
 
     public String getApiKeyAccess() {
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
index d8fa2123d22..11cf1931d25 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
@@ -136,7 +136,7 @@ public class AddClusterCmd extends BaseCmd {
             type = CommandType.MAP,
             description = "Details in key/value pairs to be added to the 
extension-resource mapping. Use the format externaldetails[i].<key>=<value>. 
Example: externaldetails[0].endpoint.url=https://example.com";,
             since = "4.21.0")
-    protected Map externalDetails;
+    protected Map<Integer, Map<String, String>> externalDetails;
 
     public String getOvm3Pool() {
          return ovm3pool;
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java
index 77d0557af05..d76718b8fdd 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java
@@ -66,7 +66,7 @@ public class UpdateClusterCmd extends BaseCmd {
             type = CommandType.MAP,
             description = "Details in key/value pairs to be added to the 
extension-resource mapping. Use the format externaldetails[i].<key>=<value>. 
Example: externaldetails[0].endpoint.url=https://example.com";,
             since = "4.21.0")
-    protected Map externalDetails;
+    protected Map<Integer, Map<String, String>> externalDetails;
 
     public String getClusterName() {
         return clusterName;
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
index c0e995c497d..bb65b7bea21 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
@@ -58,7 +58,7 @@ public class AddGuestOsCmd extends BaseAsyncCreateCmd {
     private String osName;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = 
false, description = "Map of (key/value pairs)")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     @Parameter(name="forDisplay", type=CommandType.BOOLEAN, 
description="whether this guest OS is available for end users", authorized = 
{RoleType.Admin})
     private Boolean display;
@@ -79,7 +79,7 @@ public class AddGuestOsCmd extends BaseAsyncCreateCmd {
         return osName;
     }
 
-    public Map getDetails() {
+    public Map<String, String> getDetails() {
         Map<String, String> detailsMap = new HashMap<>();
         if (!MapUtils.isEmpty(details)) {
             Collection<?> servicesCollection = details.values();
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
index 035ff6a19e2..da4b454a2c7 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
@@ -54,7 +54,7 @@ public class UpdateGuestOsCmd extends BaseAsyncCmd {
     private String osDisplayName;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = 
false, description = "Map of (key/value pairs)")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     @Parameter(name="forDisplay", type=CommandType.BOOLEAN, 
description="whether this guest OS is available for end users", authorized = 
{RoleType.Admin})
     private Boolean display;
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddHostCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddHostCmd.java
index 5a175834560..7a378f08347 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddHostCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddHostCmd.java
@@ -86,7 +86,7 @@ public class AddHostCmd extends BaseCmd {
             type = CommandType.MAP,
             description = "Details in key/value pairs using format 
externaldetails[i].keyname=keyvalue. Example: 
externaldetails[0].endpoint.url=urlvalue",
             since = "4.21.0")
-    protected Map externalDetails;
+    protected Map<Integer, Map<String, String>> externalDetails;
 
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java
index 585fd1b87a8..e79083df4d3 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java
@@ -50,7 +50,7 @@ public class AddSecondaryStorageCmd extends BaseCmd {
     protected Long zoneId;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, 
description = "Details in key/value pairs using format 
details[i].keyname=keyvalue. Example: 
details[0].copytemplatesfromothersecondarystorages=true")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java
index 69bca7c79e2..83985f157e3 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java
@@ -75,7 +75,7 @@ public class UpdateHostCmd extends BaseCmd {
     private String annotation;
 
     @Parameter(name = ApiConstants.EXTERNAL_DETAILS, type = CommandType.MAP, 
description = "Details in key/value pairs using format 
externaldetails[i].keyname=keyvalue. Example: 
externaldetails[0].endpoint.url=urlvalue", since = "4.21.0")
-    protected Map externalDetails;
+    protected Map<Integer, Map<String, String>> externalDetails;
 
     @Parameter(name = ApiConstants.CLEAN_UP_EXTERNAL_DETAILS,
             type = CommandType.BOOLEAN,
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/NetworkOfferingBaseCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/NetworkOfferingBaseCmd.java
index 4b4d0dc9482..37b42070df2 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/NetworkOfferingBaseCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/NetworkOfferingBaseCmd.java
@@ -168,7 +168,7 @@ public abstract class NetworkOfferingBaseCmd extends 
BaseCmd {
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, since = 
"4.2.0", description = "Network offering details in key/value pairs."
             + " Supported keys are internallbprovider/publiclbprovider with 
service provider as a value, and"
             + " promiscuousmode/macaddresschanges/forgedtransmits with 
true/false as value to accept/reject the security settings if available for a 
nic/portgroup")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.EGRESS_DEFAULT_POLICY,
             type = CommandType.BOOLEAN,
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmd.java
index f1d9b672309..81cc53ced87 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmd.java
@@ -91,7 +91,7 @@ public class CreateBgpPeerCmd extends BaseAsyncCmd {
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
             description = "BGP peer details in key/value pairs.")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
@@ -134,8 +134,7 @@ public class CreateBgpPeerCmd extends BaseAsyncCmd {
         if (MapUtils.isEmpty(details)) {
             return null;
         }
-        Collection<String> paramsCollection = this.details.values();
-        return (Map<String, String>) (paramsCollection.toArray())[0];
+        return this.details.values().iterator().next();
     }
 
     @Override
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmd.java
index f45c1ee5a2f..300bf076d54 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmd.java
@@ -74,7 +74,7 @@ public class UpdateBgpPeerCmd extends BaseAsyncCmd {
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
             description = "BGP peer details in key/value pairs.")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
             type = CommandType.BOOLEAN,
@@ -105,8 +105,7 @@ public class UpdateBgpPeerCmd extends BaseAsyncCmd {
         if (MapUtils.isEmpty(details)) {
             return null;
         }
-        Collection<String> paramsCollection = this.details.values();
-        return (Map<String, String>) (paramsCollection.toArray())[0];
+        return this.details.values().iterator().next();
     }
 
     public boolean isCleanupDetails(){
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
index e1ff90e4bd8..a147e976769 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
@@ -164,7 +164,7 @@ public class CreateDiskOfferingCmd extends BaseCmd {
     private Boolean encrypt;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, 
description = "Details to specify disk offering parameters", since = "4.16")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
 
 
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
index 4363d6861ba..5fbd38cd909 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
@@ -130,7 +130,7 @@ public class CreateServiceOfferingCmd extends BaseCmd {
     private String deploymentPlanner;
 
     @Parameter(name = ApiConstants.SERVICE_OFFERING_DETAILS, type = 
CommandType.MAP, description = "Details for planner, used to store specific 
parameters")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.ROOT_DISK_SIZE, type = CommandType.LONG, 
since = "4.15", description = "The Root disk size in GB.")
     private Long rootDiskSize;
@@ -286,7 +286,7 @@ public class CreateServiceOfferingCmd extends BaseCmd {
             type = CommandType.MAP,
             description = "Details in key/value pairs using format 
externaldetails[i].keyname=keyvalue. Example: 
externaldetails[0].endpoint.url=urlvalue",
             since = "4.21.0")
-    private Map externalDetails;
+    private Map<Integer, Map<String, String>> externalDetails;
 
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java
index 8e37499c95e..95a94faec4f 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java
@@ -98,7 +98,7 @@ public class UpdateServiceOfferingCmd extends BaseCmd 
implements DomainAndZoneId
             type = CommandType.MAP,
             description = "Details in key/value pairs using format 
externaldetails[i].keyname=keyvalue. Example: 
externaldetails[0].endpoint.url=urlvalue",
             since = "4.21.0")
-    private Map externalDetails;
+    private Map<Integer, Map<String, String>> externalDetails;
 
     @Parameter(name = ApiConstants.CLEAN_UP_EXTERNAL_DETAILS,
             type = CommandType.BOOLEAN,
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java
index 72e2e96fe57..c3195bc74ef 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java
@@ -58,7 +58,7 @@ public class AddImageStoreCmd extends BaseCmd {
     @Parameter(name = ApiConstants.DETAILS,
                type = CommandType.MAP,
                description = "The details for the image store. Example: 
details[0].key=accesskey&details[0].value=s389ddssaa&details[1].key=secretkey&details[1].value=8dshfsss")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
@@ -108,7 +108,7 @@ public class AddImageStoreCmd extends BaseCmd {
         this.providerName = providerName;
     }
 
-    public void setDetails(Map<String, String> details) {
+    public void setDetails(Map<Integer, Map<String, String>> details) {
         this.details = details;
     }
 
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/AddObjectStoragePoolCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/AddObjectStoragePoolCmd.java
index c24d61b7200..e91346013f6 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/AddObjectStoragePoolCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/AddObjectStoragePoolCmd.java
@@ -51,7 +51,7 @@ public class AddObjectStoragePoolCmd extends BaseCmd {
     @Parameter(name = ApiConstants.DETAILS,
                type = CommandType.MAP,
                description = "the details for the object store. Example: 
details[0].key=accesskey&details[0].value=s389ddssaa&details[1].key=secretkey&details[1].value=8dshfsss")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, 
description = "the tags for the storage pool")
     private String tags;
@@ -103,7 +103,7 @@ public class AddObjectStoragePoolCmd extends BaseCmd {
         this.providerName = providerName;
     }
 
-    public void setDetails(Map<String, String> details) {
+    public void setDetails(Map<Integer, Map<String, String>> details) {
         this.details = details;
     }
 
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CreateStoragePoolCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CreateStoragePoolCmd.java
index 784b9e77bdb..2bae6a77d66 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CreateStoragePoolCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CreateStoragePoolCmd.java
@@ -50,7 +50,7 @@ public class CreateStoragePoolCmd extends BaseCmd {
     private Long clusterId;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, 
description = "The details for the storage pool")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = 
true, description = "The name for the storage pool")
     private String storagePoolName;
@@ -103,7 +103,7 @@ public class CreateStoragePoolCmd extends BaseCmd {
         return clusterId;
     }
 
-    public Map getDetails() {
+    public Map<Integer, Map<String, String>> getDetails() {
         return details;
     }
 
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateCloudToUseObjectStoreCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateCloudToUseObjectStoreCmd.java
index 022bbb9a905..d8318d0b723 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateCloudToUseObjectStoreCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateCloudToUseObjectStoreCmd.java
@@ -53,7 +53,7 @@ public class UpdateCloudToUseObjectStoreCmd extends BaseCmd {
     private String providerName;
 
     @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description = 
"The details for the image store. Example: 
details[0].key=accesskey&details[0].value=s389ddssaa&details[1].key=secretkey&details[1].value=8dshfsss")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
 
 
@@ -99,7 +99,7 @@ public class UpdateCloudToUseObjectStoreCmd extends BaseCmd {
         this.providerName = providerName;
     }
 
-    public void setDetails(Map<String, String> details) {
+    public void setDetails(Map<Integer, Map<String, String>> details) {
         this.details = details;
     }
 
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateStoragePoolCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateStoragePoolCmd.java
index fa55b424eaf..e45e2b788c8 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateStoragePoolCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateStoragePoolCmd.java
@@ -68,7 +68,7 @@ public class UpdateStoragePoolCmd extends BaseCmd {
                             required = false,
                             description = "the details for the storage pool",
                             since = "4.19.0")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.URL,
                             type = CommandType.STRING,
@@ -131,11 +131,11 @@ public class UpdateStoragePoolCmd extends BaseCmd {
         return ApiCommandResourceType.StoragePool;
     }
 
-    public Map<String,String> getDetails() {
+    public Map<Integer, Map<String, String>> getDetails() {
         return details;
     }
 
-    public void setDetails(Map<String,String> details) {
+    public void setDetails(Map<Integer, Map<String, String>> details) {
         this.details = details;
     }
 
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/CheckVmwareCbtMigrationPrerequisitesCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/CheckVmwareCbtMigrationPrerequisitesCmd.java
index cbbadc090ce..2263f686572 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/CheckVmwareCbtMigrationPrerequisitesCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/CheckVmwareCbtMigrationPrerequisitesCmd.java
@@ -113,7 +113,7 @@ public class CheckVmwareCbtMigrationPrerequisitesCmd 
extends BaseCmd {
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
             description = "optional service offering custom parameters and 
migration details")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     public Long getZoneId() {
         return zoneId;
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/StartVmwareCbtMigrationCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/StartVmwareCbtMigrationCmd.java
index 0746e40c34c..3e3c89e3b04 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/StartVmwareCbtMigrationCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/StartVmwareCbtMigrationCmd.java
@@ -154,7 +154,7 @@ public class StartVmwareCbtMigrationCmd extends 
BaseAsyncCmd {
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
             description = "optional migration details, including VDDK settings 
such as vddk.lib.dir, vddk.transports and vddk.thumbprint")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.NIC_NETWORK_LIST, type = CommandType.MAP,
             description = "VM NIC to network id mapping using keys NIC and 
network")
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java
index 888ee6603dd..76b9ff2f9bc 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java
@@ -76,7 +76,7 @@ public class UpdateZoneCmd extends BaseCmd {
     private String allocationState;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, 
description = "The details for the Zone")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.DHCP_PROVIDER, type = CommandType.STRING, 
description = "The DHCP Provider for the Zone")
     private String dhcpProvider;
@@ -143,7 +143,7 @@ public class UpdateZoneCmd extends BaseCmd {
         return allocationState;
     }
 
-    public Map getDetails() {
+    public Map<Integer, Map<String, String>> getDetails() {
         return details;
     }
 
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java
index 3f46576e53f..192ad3c09f1 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java
@@ -112,7 +112,7 @@ public class CreateAutoScaleVmProfileCmd extends 
BaseAsyncCreateCmd {
     private Long userDataId;
 
     @Parameter(name = ApiConstants.USER_DATA_DETAILS, type = CommandType.MAP, 
description = "used to specify the parameters values for the variables in 
userdata.", since = "4.18.1")
-    private Map userDataDetails;
+    private Map<Integer, Map<String, String>> userDataDetails;
 
     @Parameter(name = ApiConstants.AUTOSCALE_USER_ID,
                type = CommandType.UUID,
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java
index 4a0826bf84e..a4986c48671 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java
@@ -108,7 +108,7 @@ public class UpdateAutoScaleVmProfileCmd extends 
BaseAsyncCustomIdCmd {
 
     @Parameter(name = ApiConstants.USER_DATA_DETAILS, type = CommandType.MAP, 
description = "used to specify the parameters values for the variables in 
userdata.",
             since = "4.18.1")
-    private Map userDataDetails;
+    private Map<Integer, Map<String, String>> userDataDetails;
 
     @Parameter(name = ApiConstants.AUTOSCALE_USER_ID,
                type = CommandType.UUID,
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/bootgroup/CreateInstanceBootGroupReadinessRuleCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/bootgroup/CreateInstanceBootGroupReadinessRuleCmd.java
index 43c5dccc512..865a91675cd 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/bootgroup/CreateInstanceBootGroupReadinessRuleCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/bootgroup/CreateInstanceBootGroupReadinessRuleCmd.java
@@ -75,7 +75,7 @@ public class CreateInstanceBootGroupReadinessRuleCmd extends 
BaseCmd implements
     private Boolean enabled;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, 
description = "Rule-type-specific configuration, e.g. port/protocol, script, 
threshold_type/threshold_value")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     public Long getBootGroupId() {
         return bootGroupId;
@@ -105,8 +105,7 @@ public class CreateInstanceBootGroupReadinessRuleCmd 
extends BaseCmd implements
         if (this.details == null || this.details.isEmpty()) {
             return null;
         }
-        Collection<String> paramsCollection = this.details.values();
-        return (Map<String, String>) (paramsCollection.toArray())[0];
+        return this.details.values().iterator().next();
     }
 
     @Override
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/bootgroup/UpdateInstanceBootGroupReadinessRuleCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/bootgroup/UpdateInstanceBootGroupReadinessRuleCmd.java
index ea399f08565..414169e082c 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/bootgroup/UpdateInstanceBootGroupReadinessRuleCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/bootgroup/UpdateInstanceBootGroupReadinessRuleCmd.java
@@ -60,7 +60,7 @@ public class UpdateInstanceBootGroupReadinessRuleCmd extends 
BaseCmd implements
     private Boolean enabled;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, 
description = "Rule-type-specific configuration")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     public Long getId() {
         return id;
@@ -78,8 +78,7 @@ public class UpdateInstanceBootGroupReadinessRuleCmd extends 
BaseCmd implements
         if (this.details == null || this.details.isEmpty()) {
             return null;
         }
-        Collection<String> paramsCollection = this.details.values();
-        return (Map<String, String>) (paramsCollection.toArray())[0];
+        return this.details.values().iterator().next();
     }
 
     @Override
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/dns/AddDnsServerCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/dns/AddDnsServerCmd.java
index 21279b8719f..b70aac5c2c7 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/dns/AddDnsServerCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/dns/AddDnsServerCmd.java
@@ -88,7 +88,7 @@ public class AddDnsServerCmd extends BaseCmd {
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, 
description = "Details in key/value pairs using " +
             "format details[i].keyname=keyvalue. Example: 
details[0].pdnsServerId=localhost")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/schedule/CreateResourceScheduleCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/schedule/CreateResourceScheduleCmd.java
index f6268106c31..8284e577406 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/schedule/CreateResourceScheduleCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/schedule/CreateResourceScheduleCmd.java
@@ -68,7 +68,7 @@ public class CreateResourceScheduleCmd extends BaseCmd {
     private Boolean enabled;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = 
false, description = "Map of (key/value pairs) details for the schedule.")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     public ApiCommandResourceType getResourceType() {
         ApiCommandResourceType type = 
EnumUtils.getEnumIgnoreCase(ApiCommandResourceType.class, resourceType);
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/schedule/UpdateResourceScheduleCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/schedule/UpdateResourceScheduleCmd.java
index 5422588853e..b178a2cdf95 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/schedule/UpdateResourceScheduleCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/schedule/UpdateResourceScheduleCmd.java
@@ -59,7 +59,7 @@ public class UpdateResourceScheduleCmd extends BaseCmd {
     private Boolean enabled;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = 
false, description = "Map of (key/value pairs) details for the schedule.")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     public Long getId() {
         return id;
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java
index b5e41ff449c..cc6e0d72549 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java
@@ -123,7 +123,7 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd 
implements UserCmd {
     private String templateTag;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, 
description = "Template details in key/value pairs using format 
details[i].keyname=keyvalue. Example: 
details[0].hypervisortoolsversion=xenserver61")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE,
                type = CommandType.BOOLEAN,
@@ -214,14 +214,11 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd 
implements UserCmd {
         return StringUtils.isBlank(templateTag) ? null : templateTag;
     }
 
-    public Map getDetails() {
+    public Map<String, String> getDetails() {
         if (details == null || details.isEmpty()) {
             return null;
         }
-
-        Collection paramsCollection = details.values();
-        Map params = (Map)(paramsCollection.toArray())[0];
-        return params;
+        return details.values().iterator().next();
     }
 
     public boolean isDynamicallyScalable() {
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
index e6e178baada..98b8f7a43d7 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
@@ -65,7 +65,7 @@ public class GetUploadParamsForTemplateCmd extends 
AbstractGetUploadParamsCmd {
     private Integer bits;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, 
description = "Template details in key/value pairs.")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE, type = 
CommandType.BOOLEAN, description = "True if Template contains XS/VMWare tools 
in order to support dynamic scaling of Instance CPU/memory")
     private Boolean isDynamicallyScalable;
@@ -125,13 +125,11 @@ public class GetUploadParamsForTemplateCmd extends 
AbstractGetUploadParamsCmd {
         return bits;
     }
 
-    public Map getDetails() {
+    public Map<String, String> getDetails() {
         if (details == null || details.isEmpty()) {
             return null;
         }
-        Collection paramsCollection = details.values();
-        Map params = (Map)(paramsCollection.toArray())[0];
-        return params;
+        return details.values().iterator().next();
     }
 
     public Boolean isDynamicallyScalable() {
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
index 49992ac6661..0c7e4ed19ef 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
@@ -136,7 +136,7 @@ public class RegisterTemplateCmd extends BaseCmd implements 
UserCmd {
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
             description = "Template details in key/value pairs using format 
details[i].keyname=keyvalue. Example: 
details[0].hypervisortoolsversion=xenserver61")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE,
                type = CommandType.BOOLEAN,
@@ -190,7 +190,7 @@ public class RegisterTemplateCmd extends BaseCmd implements 
UserCmd {
     private Long extensionId;
 
     @Parameter(name = ApiConstants.EXTERNAL_DETAILS, type = CommandType.MAP, 
description = "Details in key/value pairs using format 
externaldetails[i].keyname=keyvalue. Example: 
externaldetails[0].endpoint.url=urlvalue", since = "4.21.0")
-    protected Map externalDetails;
+    protected Map<Integer, Map<String, String>> externalDetails;
 
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
@@ -282,14 +282,11 @@ public class RegisterTemplateCmd extends BaseCmd 
implements UserCmd {
         return StringUtils.isBlank(templateTag) ? null : templateTag;
     }
 
-    public Map getDetails() {
+    public Map<String, String> getDetails() {
         if (details == null || details.isEmpty()) {
             return null;
         }
-
-        Collection paramsCollection = details.values();
-        Map params = (Map)(paramsCollection.toArray())[0];
-        return params;
+        return details.values().iterator().next();
     }
 
     public Boolean isDynamicallyScalable() {
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterVnfTemplateCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterVnfTemplateCmd.java
index c3e99d5791f..b22cd92edd3 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterVnfTemplateCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterVnfTemplateCmd.java
@@ -52,7 +52,7 @@ public class RegisterVnfTemplateCmd extends 
RegisterTemplateCmd implements UserC
             type = CommandType.MAP,
             description = "VNF details in key/value pairs using format 
vnfdetails[i].keyname=keyvalue. "
                     + "Example: 
vnfdetails[0].vendor=xxx&&vnfdetails[0].version=2.0")
-    protected Map vnfDetails;
+    protected Map<Integer, Map<String, String>> vnfDetails;
 
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/template/UpdateVnfTemplateCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/template/UpdateVnfTemplateCmd.java
index 7479dd3be09..c5061224ce8 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/template/UpdateVnfTemplateCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/template/UpdateVnfTemplateCmd.java
@@ -52,7 +52,7 @@ public class UpdateVnfTemplateCmd extends UpdateTemplateCmd 
implements UserCmd {
             type = CommandType.MAP,
             description = "VNF details in key/value pairs using format 
vnfdetails[i].keyname=keyvalue. "
                     + "Example: 
vnfdetails[0].vendor=xxx&&vnfdetails[0].version=2.0")
-    protected Map vnfDetails;
+    protected Map<Integer, Map<String, String>> vnfDetails;
 
     @Parameter(name = ApiConstants.CLEAN_UP_VNF_DETAILS,
             type = CommandType.BOOLEAN,
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/BaseDeployVMCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/BaseDeployVMCmd.java
index 8d79ac4af45..6d70f1fc85d 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/BaseDeployVMCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/BaseDeployVMCmd.java
@@ -141,7 +141,7 @@ public abstract class BaseDeployVMCmd extends 
BaseAsyncCreateCustomIdCmd impleme
             since = "4.21.0",
             description = "Disk offering details for creating multiple data 
volumes. Mutually exclusive with diskOfferingId." +
                     " Example: 
datadisksdetails[0].diskofferingid=a2a73a84-19db-4852-8930-dfddef053341&datadisksdetails[0].size=10&datadisksdetails[0].miniops=100&datadisksdetails[0].maxiops=200&datadisksdetails[0].kmskeyid=<uuid>")
-    private Map dataDisksDetails;
+    private Map<Integer, Map<String, String>> dataDisksDetails;
 
     @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, 
description = "an optional group for the virtual machine")
     private String group;
@@ -164,7 +164,7 @@ public abstract class BaseDeployVMCmd extends 
BaseAsyncCreateCustomIdCmd impleme
     protected Long userdataId;
 
     @Parameter(name = ApiConstants.USER_DATA_DETAILS, type = CommandType.MAP, 
description = "used to specify the parameters values for the variables in 
userdata.", since = "4.18")
-    private Map userdataDetails;
+    private Map<Integer, Map<String, String>> userdataDetails;
 
     @Deprecated
     @Parameter(name = ApiConstants.SSH_KEYPAIR, type = CommandType.STRING, 
description = "name of the ssh key pair used to login to the virtual machine")
@@ -222,7 +222,7 @@ public abstract class BaseDeployVMCmd extends 
BaseAsyncCreateCustomIdCmd impleme
     protected Boolean displayVm;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, since = 
"4.3", description = "used to specify the custom parameters. 'extraconfig' is 
not allowed to be passed in details")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = 
CommandType.STRING, description = "Deployment planner to use for vm allocation. 
Available to ROOT admin only", since = "4.4", authorized = { RoleType.Admin })
     private String deploymentPlanner;
@@ -287,7 +287,7 @@ public abstract class BaseDeployVMCmd extends 
BaseAsyncCreateCustomIdCmd impleme
             type = CommandType.MAP,
             description = "Details in key/value pairs using format 
externaldetails[i].keyname=keyvalue. Example: 
externaldetails[0].server.type=typevalue",
             since = "4.21.0")
-    protected Map externalDetails;
+    protected Map<Integer, Map<String, String>> externalDetails;
 
     private List<VmDiskInfo> dataDiskInfoList;
 
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java 
b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
index 0a943fab118..e5c2b9d3830 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
@@ -159,7 +159,7 @@ public class DeployVMCmd extends BaseDeployVMCmd {
         this.affinityGroupIdList = ids;
     }
 
-    public void setDetails(Map details) {
+    public void setDetails(Map<Integer, Map<String, String>> details) {
         this.details = details;
     }
 
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMUserDataCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMUserDataCmd.java
index 84422e0498b..b6a1384df5a 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMUserDataCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMUserDataCmd.java
@@ -70,7 +70,7 @@ public class ResetVMUserDataCmd extends BaseCmd implements 
UserCmd {
     private Long userdataId;
 
     @Parameter(name = ApiConstants.USER_DATA_DETAILS, type = CommandType.MAP, 
description = "Used to specify the parameters values for the variables in 
userdata.")
-    private Map userdataDetails;
+    private Map<Integer, Map<String, String>> userdataDetails;
 
     //Owner information
     @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, 
description = "An optional Account for the Instance. Must be used with 
domainId.")
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java 
b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
index d3459347687..092c2ab7e58 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
@@ -75,7 +75,7 @@ public class RestoreVMCmd extends BaseAsyncCmd implements 
UserCmd {
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, since = 
"4.19.1",
                description = "used to specify the custom parameters")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.EXPUNGE,
                type = CommandType.BOOLEAN,
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java 
b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
index 618d14d90a6..3a5807f5a77 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
@@ -98,7 +98,7 @@ public class UpdateVMCmd extends BaseCustomIdCmd implements 
SecurityGroupAction,
     private Long userdataId;
 
     @Parameter(name = ApiConstants.USER_DATA_DETAILS, type = CommandType.MAP, 
description = "Used to specify the parameters values for the variables in 
userdata.", since = "4.18")
-    private Map userdataDetails;
+    private Map<Integer, Map<String, String>> userdataDetails;
 
     @Parameter(name = ApiConstants.DISPLAY_VM, type = CommandType.BOOLEAN, 
description = "An optional field, whether to the display the Instance to the 
end User or not.", authorized = {RoleType.Admin})
     private Boolean displayVm;
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java
index 9e1c1056fdf..9babd7d811a 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java
@@ -38,7 +38,7 @@ public class AddResourceDetailCmd extends BaseAsyncCmd {
     /////////////////////////////////////////////////////
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = 
true, description = "Map of (key/value pairs)")
-    private Map details;
+    private Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.RESOURCE_TYPE, type = CommandType.STRING, 
required = true, description = "Type of the resource")
     private String resourceType;
@@ -53,7 +53,7 @@ public class AddResourceDetailCmd extends BaseAsyncCmd {
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
 
-    public Map getDetails() {
+    public Map<String, String> getDetails() {
         return TaggedResources.parseKeyValueMap(details, true);
     }
 
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/response/BgpPeerResponse.java 
b/api/src/main/java/org/apache/cloudstack/api/response/BgpPeerResponse.java
index 344e65c6bad..5f654b9a95c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/BgpPeerResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/BgpPeerResponse.java
@@ -84,7 +84,7 @@ public class BgpPeerResponse extends BaseResponse {
 
     @SerializedName(ApiConstants.DETAILS)
     @Param(description = "additional key/value details of the bgp peer")
-    private Map details;
+    private Map<BgpPeer.Detail, String> details;
 
     public void setId(String id) {
         this.id = id;
@@ -138,7 +138,7 @@ public class BgpPeerResponse extends BaseResponse {
         this.domainName = domainName;
     }
 
-    public void setDetails(Map details) {
+    public void setDetails(Map<BgpPeer.Detail, String> details) {
         this.details = details;
     }
 
@@ -194,7 +194,7 @@ public class BgpPeerResponse extends BaseResponse {
         return projectName;
     }
 
-    public Map getDetails() {
+    public Map<BgpPeer.Detail, String> getDetails() {
         return details;
     }
 }
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/response/HostResponse.java 
b/api/src/main/java/org/apache/cloudstack/api/response/HostResponse.java
index 10bd62804fb..365281aceb7 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/HostResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/HostResponse.java
@@ -289,7 +289,7 @@ public class HostResponse extends 
BaseResponseWithAnnotations {
 
     @SerializedName(ApiConstants.DETAILS)
     @Param(description = "Host details in key/value pairs.", since = "4.5")
-    private Map details;
+    private Map<String, String> details;
 
     @SerializedName(ApiConstants.ANNOTATION)
     @Param(description = "The last annotation set on this host by an admin", 
since = "4.11")
@@ -672,13 +672,13 @@ public class HostResponse extends 
BaseResponseWithAnnotations {
         this.username = username;
     }
 
-    public void setDetails(Map details, Hypervisor.HypervisorType 
hypervisorType) {
+    public void setDetails(Map<String, String> details, 
Hypervisor.HypervisorType hypervisorType) {
 
         if (details == null) {
             return;
         }
 
-        final Map detailsCopy = new HashMap(details);
+        final Map<String, String> detailsCopy = new HashMap<>(details);
 
         // Fix for CVE ID 2015-3251
         // Remove sensitive host credential information from
@@ -687,7 +687,7 @@ public class HostResponse extends 
BaseResponseWithAnnotations {
         detailsCopy.remove("password");
 
         if (detailsCopy.containsKey(Host.HOST_VOLUME_ENCRYPTION)) {
-            this.setEncryptionSupported(Boolean.parseBoolean((String) 
detailsCopy.get(Host.HOST_VOLUME_ENCRYPTION)));
+            
this.setEncryptionSupported(Boolean.parseBoolean(detailsCopy.get(Host.HOST_VOLUME_ENCRYPTION)));
             detailsCopy.remove(Host.HOST_VOLUME_ENCRYPTION);
         } else {
             this.setEncryptionSupported(new Boolean(false)); // default
@@ -695,7 +695,7 @@ public class HostResponse extends 
BaseResponseWithAnnotations {
 
         if (Hypervisor.HypervisorType.KVM.equals(hypervisorType)) {
             if (detailsCopy.containsKey(Host.HOST_INSTANCE_CONVERSION)) {
-                
this.setInstanceConversionSupported(Boolean.parseBoolean((String) 
detailsCopy.get(Host.HOST_INSTANCE_CONVERSION)));
+                
this.setInstanceConversionSupported(Boolean.parseBoolean(detailsCopy.get(Host.HOST_INSTANCE_CONVERSION)));
                 detailsCopy.remove(Host.HOST_INSTANCE_CONVERSION);
             } else {
                 this.setInstanceConversionSupported(new Boolean(false)); // 
default
@@ -705,7 +705,7 @@ public class HostResponse extends 
BaseResponseWithAnnotations {
         this.details = detailsCopy;
     }
 
-    public Map getDetails() {
+    public Map<String, String> getDetails() {
         return details;
     }
 
@@ -972,7 +972,7 @@ public class HostResponse extends 
BaseResponseWithAnnotations {
         return hasEnoughCapacity;
     }
 
-    public void setDetails(Map details) {
+    public void setDetails(Map<String, String> details) {
         this.details = details;
     }
 
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
 
b/api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
index 740dd23604a..a47528339f3 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
@@ -121,7 +121,7 @@ public class NetworkOfferingResponse extends 
BaseResponseWithAnnotations {
 
     @SerializedName(ApiConstants.DETAILS)
     @Param(description = "Additional key/value details tied with network 
offering", since = "4.2.0")
-    private Map details;
+    private Map<NetworkOffering.Detail, String> details;
 
     @SerializedName(ApiConstants.EGRESS_DEFAULT_POLICY)
     @Param(description = "True if guest network default egress policy is 
allow; false if default egress policy is deny")
@@ -255,7 +255,7 @@ public class NetworkOfferingResponse extends 
BaseResponseWithAnnotations {
         this.isPersistent = isPersistent;
     }
 
-    public void setDetails(Map details) {
+    public void setDetails(Map<NetworkOffering.Detail, String> details) {
         this.details = details;
     }
 
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/response/NetworkProtocolResponse.java
 
b/api/src/main/java/org/apache/cloudstack/api/response/NetworkProtocolResponse.java
index 775333f7192..40989882a1b 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/response/NetworkProtocolResponse.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/response/NetworkProtocolResponse.java
@@ -40,7 +40,7 @@ public class NetworkProtocolResponse extends BaseResponse {
 
     @SerializedName(ApiConstants.DETAILS)
     @Param(description = "the details of the protocol parameter")
-    private Map details;
+    private Map<String, String> details;
 
     public NetworkProtocolResponse(Integer index, String name, String 
description) {
         this.index = index;
@@ -72,17 +72,17 @@ public class NetworkProtocolResponse extends BaseResponse {
         this.description = description;
     }
 
-    public Map getDetails() {
+    public Map<String, String> getDetails() {
         return details;
     }
 
-    public void setDetails(Map details) {
+    public void setDetails(Map<String, String> details) {
         this.details = details;
     }
 
     public void addDetail(String key, String value) {
         if (this.details == null) {
-            this.details = new LinkedHashMap();
+            this.details = new LinkedHashMap<>();
         }
         this.details.put(key, value);
     }
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java 
b/api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java
index e08c6019f15..2b7e1d649f3 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java
@@ -346,7 +346,7 @@ public class UserVmResponse extends 
BaseResponseWithTagInformation implements Co
 
     @SerializedName(ApiConstants.DETAILS)
     @Param(description = "Instance details in key/value pairs.", since = 
"4.2.1")
-    private Map details;
+    private Map<String, String> details;
 
     @SerializedName("readonlydetails")
     @Param(description = "List of read-only Instance details as comma 
separated string.", since = "4.16.0")
@@ -1115,7 +1115,7 @@ public class UserVmResponse extends 
BaseResponseWithTagInformation implements Co
         this.serviceState = state;
     }
 
-    public void setDetails(Map details) {
+    public void setDetails(Map<String, String> details) {
         this.details = details;
     }
 
@@ -1143,7 +1143,7 @@ public class UserVmResponse extends 
BaseResponseWithTagInformation implements Co
         this.tagIds = tagIds;
     }
 
-    public Map getDetails() {
+    public Map<String, String> getDetails() {
         return details;
     }
 
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/response/VolumeForImportResponse.java
 
b/api/src/main/java/org/apache/cloudstack/api/response/VolumeForImportResponse.java
index 803f154816a..609fe8650ae 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/response/VolumeForImportResponse.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/response/VolumeForImportResponse.java
@@ -72,7 +72,7 @@ public class VolumeForImportResponse extends BaseResponse {
 
     @SerializedName(ApiConstants.DETAILS)
     @Param(description = "volume details in key/value pairs.")
-    private Map details;
+    private Map<VolumeOnStorageTO.Detail, String> details;
 
     @SerializedName(ApiConstants.CHAIN_INFO)
     @Param(description = "the chain info of the volume")
@@ -158,11 +158,11 @@ public class VolumeForImportResponse extends BaseResponse 
{
         this.storagePoolType = storagePoolType;
     }
 
-    public Map getDetails() {
+    public Map<VolumeOnStorageTO.Detail, String> getDetails() {
         return details;
     }
 
-    public void setDetails(Map details) {
+    public void setDetails(Map<VolumeOnStorageTO.Detail, String> details) {
         this.details = details;
     }
 
diff --git 
a/api/src/test/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmdTest.java
 
b/api/src/test/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmdTest.java
index 09d396e4023..4c9f979003b 100644
--- 
a/api/src/test/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmdTest.java
+++ 
b/api/src/test/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmdTest.java
@@ -602,8 +602,8 @@ public class DeployVMCmdTest {
 
     @Test
     public void testSetDetails() {
-        Map<String, String> details = new HashMap<>();
-        details.put("key", "value");
+        Map<Integer, Map<String, String>> details = new HashMap<>();
+        details.put(0, Map.of("key", "value"));
         cmd.setDetails(details);
         assertEquals(details, ReflectionTestUtils.getField(cmd, "details"));
     }
diff --git 
a/api/src/test/java/org/apache/cloudstack/api/response/BgpPeerResponseTest.java 
b/api/src/test/java/org/apache/cloudstack/api/response/BgpPeerResponseTest.java
index 7c82eb84368..c5132bd9491 100644
--- 
a/api/src/test/java/org/apache/cloudstack/api/response/BgpPeerResponseTest.java
+++ 
b/api/src/test/java/org/apache/cloudstack/api/response/BgpPeerResponseTest.java
@@ -16,6 +16,7 @@
 // under the License.
 package org.apache.cloudstack.api.response;
 
+import org.apache.cloudstack.network.BgpPeer;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -59,8 +60,8 @@ public final class BgpPeerResponseTest {
         response.setZoneId(zoneId);
         response.setZoneName(zoneName);
         response.setCreated(created);
-        Map<String, String> details = new HashMap<>();
-        details.put("key", "value");
+        Map<BgpPeer.Detail, String> details = new HashMap<>();
+        details.put(BgpPeer.Detail.EBGP_MultiHop, "value");
         response.setDetails(details);
 
         Assert.assertEquals(uuid, response.getId());
diff --git 
a/api/src/test/java/org/apache/cloudstack/api/response/VolumeForImportResponseTest.java
 
b/api/src/test/java/org/apache/cloudstack/api/response/VolumeForImportResponseTest.java
index 7d0538836bf..602d244462b 100644
--- 
a/api/src/test/java/org/apache/cloudstack/api/response/VolumeForImportResponseTest.java
+++ 
b/api/src/test/java/org/apache/cloudstack/api/response/VolumeForImportResponseTest.java
@@ -18,6 +18,7 @@ package org.apache.cloudstack.api.response;
 
 import com.cloud.hypervisor.Hypervisor;
 import com.cloud.storage.Storage;
+import org.apache.cloudstack.storage.volume.VolumeOnStorageTO;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -57,8 +58,8 @@ public final class VolumeForImportResponseTest {
         response.setStoragePoolName(storagePoolName);
         response.setStoragePoolId(storagePoolId);
         response.setChainInfo(chainInfo);
-        Map<String, String> details = new HashMap<>();
-        details.put("key", "value");
+        Map<VolumeOnStorageTO.Detail, String> details = new HashMap<>();
+        details.put(VolumeOnStorageTO.Detail.FILE_FORMAT, "value");
         response.setDetails(details);
 
         Assert.assertEquals(path, response.getPath());
diff --git 
a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/AddCustomActionCmd.java
 
b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/AddCustomActionCmd.java
index dcea754430c..5a35097e53c 100644
--- 
a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/AddCustomActionCmd.java
+++ 
b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/AddCustomActionCmd.java
@@ -101,7 +101,7 @@ public class AddCustomActionCmd extends BaseCmd {
             type = CommandType.MAP,
             description = "Details in key/value pairs using format 
details[i].keyname=keyvalue. "
                     + "Example: details[0].vendor=xxx&&details[0].version=2.0")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
diff --git 
a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/CreateExtensionCmd.java
 
b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/CreateExtensionCmd.java
index 9d76a7e6ec2..2ec92942618 100644
--- 
a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/CreateExtensionCmd.java
+++ 
b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/CreateExtensionCmd.java
@@ -81,7 +81,7 @@ public class CreateExtensionCmd extends BaseCmd {
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
             description = "Details in key/value pairs using format 
details[i].keyname=keyvalue. Example: details[0].endpoint.url=urlvalue")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.RESERVED_RESOURCE_DETAILS, type = 
CommandType.STRING,
             description = "Resource detail names as comma separated string 
that should be reserved and not visible " +
diff --git 
a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/RegisterExtensionCmd.java
 
b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/RegisterExtensionCmd.java
index e8f71d7ac8c..57fe9b92bcc 100644
--- 
a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/RegisterExtensionCmd.java
+++ 
b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/RegisterExtensionCmd.java
@@ -66,7 +66,7 @@ public class RegisterExtensionCmd extends BaseCmd {
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
             description = "Details in key/value pairs using format 
details[i].keyname=keyvalue. Example: details[0].endpoint.url=urlvalue")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
diff --git 
a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/UpdateCustomActionCmd.java
 
b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/UpdateCustomActionCmd.java
index bb03be00c5d..a7f87c74290 100644
--- 
a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/UpdateCustomActionCmd.java
+++ 
b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/UpdateCustomActionCmd.java
@@ -107,7 +107,7 @@ public class UpdateCustomActionCmd extends BaseCmd {
             type = CommandType.MAP,
             description = "Details in key/value pairs using format 
details[i].keyname=keyvalue. "
                     + "Example: details[0].vendor=xxx&&details[0].version=2.0")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
             type = CommandType.BOOLEAN,
diff --git 
a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/UpdateExtensionCmd.java
 
b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/UpdateExtensionCmd.java
index 5baaea1709d..8c1a33ad4de 100644
--- 
a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/UpdateExtensionCmd.java
+++ 
b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/UpdateExtensionCmd.java
@@ -69,7 +69,7 @@ public class UpdateExtensionCmd extends BaseCmd {
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
             description = "Details in key/value pairs using format 
details[i].keyname=keyvalue. Example: details[0].endpoint.url=urlvalue")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
             type = CommandType.BOOLEAN,
diff --git 
a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/UpdateRegisteredExtensionCmd.java
 
b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/UpdateRegisteredExtensionCmd.java
index 6c755ecd1a5..3ecd87dbba6 100644
--- 
a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/UpdateRegisteredExtensionCmd.java
+++ 
b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/UpdateRegisteredExtensionCmd.java
@@ -61,7 +61,7 @@ public class UpdateRegisteredExtensionCmd extends BaseCmd {
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
             description = "Details in key/value pairs using format 
details[i].keyname=keyvalue. Example: details[0].endpoint.url=urlvalue")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     @Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
             type = CommandType.BOOLEAN,
diff --git 
a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/CreateKubernetesClusterCmd.java
 
b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/CreateKubernetesClusterCmd.java
index 8bf0f362550..d2fe8fd4bcd 100644
--- 
a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/CreateKubernetesClusterCmd.java
+++ 
b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/CreateKubernetesClusterCmd.java
@@ -216,7 +216,7 @@ public class CreateKubernetesClusterCmd extends 
BaseAsyncCreateCmd {
                     "Example: 
cniconfigdetails[0].key=accesskey&cniconfigdetails[0].value=s389ddssaa&" +
                     
"cniconfigdetails[1].key=secretkey&cniconfigdetails[1].value=8dshfsss",
             since = "4.21.0")
-    private Map cniConfigDetails;
+    private Map<Integer, Map<String, String>> cniConfigDetails;
 
     @Parameter(name = ApiConstants.ENABLE_CSI, type = CommandType.BOOLEAN, 
description = "if true, setups up CloudStack CSI driver", since = "4.22.0")
     private Boolean enableCsi;
@@ -381,7 +381,7 @@ public class CreateKubernetesClusterCmd extends 
BaseAsyncCreateCmd {
         return asNumber;
     }
 
-    public Map getCniConfigDetails() {
+    public Map<String, String> getCniConfigDetails() {
         return convertDetailsToMap(cniConfigDetails);
     }
 
diff --git 
a/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/RegisterOAuthProviderCmd.java
 
b/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/RegisterOAuthProviderCmd.java
index 956e6fca00a..c1a1b26be70 100644
--- 
a/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/RegisterOAuthProviderCmd.java
+++ 
b/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/RegisterOAuthProviderCmd.java
@@ -78,7 +78,7 @@ public class RegisterOAuthProviderCmd extends BaseCmd {
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
             description = "Any OAuth provider details in key/value pairs using 
format details[i].keyname=keyvalue. Example: 
details[0].clientsecret=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")
-    protected Map details;
+    protected Map<Integer, Map<String, String>> details;
 
     @Override
     public long getEntityOwnerId() {
@@ -121,12 +121,11 @@ public class RegisterOAuthProviderCmd extends BaseCmd {
         return tokenUrl;
     }
 
-    public Map getDetails() {
+    public Map<String, String> getDetails() {
         if (MapUtils.isEmpty(details)) {
             return null;
         }
-        Collection paramsCollection = this.details.values();
-        return (Map) (paramsCollection.toArray())[0];
+        return this.details.values().iterator().next();
     }
 
     @Inject
diff --git 
a/server/src/main/java/com/cloud/storage/upload/params/TemplateUploadParams.java
 
b/server/src/main/java/com/cloud/storage/upload/params/TemplateUploadParams.java
index aae7c0be812..202615b6ef9 100644
--- 
a/server/src/main/java/com/cloud/storage/upload/params/TemplateUploadParams.java
+++ 
b/server/src/main/java/com/cloud/storage/upload/params/TemplateUploadParams.java
@@ -29,7 +29,7 @@ public class TemplateUploadParams extends UploadParamsBase {
                                 Boolean isExtractable, String format, Long 
guestOSId,
                                 Long zoneId, Hypervisor.HypervisorType 
hypervisorType, String chksum,
                                 String templateTag, long templateOwnerId,
-                                Map details, Boolean sshkeyEnabled,
+                                Map<String, String> details, Boolean 
sshkeyEnabled,
                                 Boolean isDynamicallyScalable, Boolean 
isRoutingType, boolean deployAsIs,
                                 boolean forCks, String templateType) {
         super(userId, name, displayText, arch, bits, passwordEnabled, 
requiresHVM, isPublic, featured, isExtractable,
diff --git 
a/server/src/main/java/com/cloud/storage/upload/params/UploadParams.java 
b/server/src/main/java/com/cloud/storage/upload/params/UploadParams.java
index 5738cfaad88..283b9995865 100644
--- a/server/src/main/java/com/cloud/storage/upload/params/UploadParams.java
+++ b/server/src/main/java/com/cloud/storage/upload/params/UploadParams.java
@@ -41,7 +41,7 @@ public interface UploadParams {
     boolean isBootable();
     String getTemplateTag();
     long getTemplateOwnerId();
-    Map getDetails();
+    Map<String, String> getDetails();
     boolean isSshKeyEnabled();
     String getImageStoreUuid();
     boolean isDynamicallyScalable();
diff --git 
a/server/src/main/java/com/cloud/storage/upload/params/UploadParamsBase.java 
b/server/src/main/java/com/cloud/storage/upload/params/UploadParamsBase.java
index 945551a9318..36ec10e92b9 100644
--- a/server/src/main/java/com/cloud/storage/upload/params/UploadParamsBase.java
+++ b/server/src/main/java/com/cloud/storage/upload/params/UploadParamsBase.java
@@ -41,7 +41,7 @@ public abstract class UploadParamsBase implements 
UploadParams {
     private boolean bootable;
     private String templateTag;
     private long templateOwnerId;
-    private Map details;
+    private Map<String, String> details;
     private boolean sshkeyEnabled;
     private boolean isDynamicallyScalable;
     private boolean isRoutingType;
@@ -56,7 +56,7 @@ public abstract class UploadParamsBase implements 
UploadParams {
                      boolean isExtractable, String format, Long guestOSId,
                      Long zoneId, Hypervisor.HypervisorType hypervisorType, 
String checksum,
                      String templateTag, long templateOwnerId,
-                     Map details, boolean sshkeyEnabled,
+                     Map<String, String> details, boolean sshkeyEnabled,
                      boolean isDynamicallyScalable, boolean isRoutingType, 
boolean deployAsIs,
                      boolean forCks, String templateType) {
         this.userId = userId;
@@ -195,7 +195,7 @@ public abstract class UploadParamsBase implements 
UploadParams {
     }
 
     @Override
-    public Map getDetails() {
+    public Map<String, String> getDetails() {
         return details;
     }
 

Reply via email to