content: // Licensed to the Apache Software Foundation (ASF) under one
  // or more contributor license agreements.  See the NOTICE file
  // distributed with this work for additional information
  // regarding copyright ownership.  The ASF licenses this file
  // to you under the Apache License, Version 2.0 (the
  // "License"); you may not use this file except in compliance
  // with the License.  You may obtain a copy of the License at
  //
  //   http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing,
  // software distributed under the License is distributed on an
  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  // KIND, either express or implied.  See the License for the
  // specific language governing permissions and limitations
  // under the License.
  package com.cloud.api;
  
  import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
  
  import java.security.cert.Certificate;
  import java.security.cert.CertificateException;
  import java.text.DecimalFormat;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Calendar;
  import java.util.Date;
  import java.util.EnumSet;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.LinkedHashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Objects;
  import java.util.Set;
  import java.util.TimeZone;
  import java.util.function.Consumer;
  import java.util.stream.Collectors;
  
  import javax.inject.Inject;
  
  import com.cloud.bgp.ASNumber;
  import com.cloud.bgp.ASNumberRange;
  import com.cloud.configuration.ConfigurationService;
  import com.cloud.dc.ASNumberRangeVO;
  import com.cloud.dc.ASNumberVO;
  import com.cloud.dc.VlanDetailsVO;
  import com.cloud.dc.dao.ASNumberDao;
  import com.cloud.dc.dao.ASNumberRangeDao;
  import com.cloud.dc.dao.VlanDetailsDao;
  import com.cloud.hypervisor.Hypervisor;
  import com.cloud.network.vpc.VpcGateway;
  import com.cloud.storage.BucketVO;
  import org.apache.cloudstack.acl.ControlledEntity;
  import org.apache.cloudstack.acl.ControlledEntity.ACLType;
  import org.apache.cloudstack.affinity.AffinityGroup;
  import org.apache.cloudstack.affinity.AffinityGroupResponse;
  import org.apache.cloudstack.annotation.AnnotationService;
  import org.apache.cloudstack.annotation.dao.AnnotationDao;
  import org.apache.cloudstack.api.ApiConstants;
  import org.apache.cloudstack.api.ApiConstants.DomainDetails;
  import org.apache.cloudstack.api.ApiConstants.HostDetails;
  import org.apache.cloudstack.api.ApiConstants.VMDetails;
  import org.apache.cloudstack.api.BaseResponseWithAssociatedNetwork;
  import org.apache.cloudstack.api.ResponseGenerator;
  import org.apache.cloudstack.api.ResponseObject.ResponseView;
  import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
  import org.apache.cloudstack.api.response.ASNRangeResponse;
  import org.apache.cloudstack.api.response.ASNumberResponse;
  import org.apache.cloudstack.api.response.AccountResponse;
  import org.apache.cloudstack.api.response.ApplicationLoadBalancerInstanceResponse;
  import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse;
  import org.apache.cloudstack.api.response.ApplicationLoadBalancerRuleResponse;
  import org.apache.cloudstack.api.response.AsyncJobResponse;
  import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
  import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
  import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
  import org.apache.cloudstack.api.response.BackupOfferingResponse;
  import org.apache.cloudstack.api.response.BackupRepositoryResponse;
  import org.apache.cloudstack.api.response.BackupScheduleResponse;
  import org.apache.cloudstack.api.response.BgpPeerResponse;
  import org.apache.cloudstack.api.response.BucketResponse;
  import org.apache.cloudstack.api.response.CapabilityResponse;
  import org.apache.cloudstack.api.response.CapacityResponse;
  import org.apache.cloudstack.api.response.ClusterResponse;
  import org.apache.cloudstack.api.response.ConditionResponse;
  import org.apache.cloudstack.api.response.ConfigurationGroupResponse;
  import org.apache.cloudstack.api.response.ConfigurationResponse;
  import org.apache.cloudstack.api.response.ConfigurationSubGroupResponse;
  import org.apache.cloudstack.api.response.ConsoleSessionResponse;
  import org.apache.cloudstack.api.response.ControlledEntityResponse;
  import org.apache.cloudstack.api.response.ControlledViewEntityResponse;
  import org.apache.cloudstack.api.response.CounterResponse;
  import org.apache.cloudstack.api.response.CreateCmdResponse;
  import org.apache.cloudstack.api.response.CreateSSHKeyPairResponse;
  import org.apache.cloudstack.api.response.DataCenterGuestIpv6PrefixResponse;
  import org.apache.cloudstack.api.response.DirectDownloadCertificateHostStatusResponse;
  import org.apache.cloudstack.api.response.DirectDownloadCertificateResponse;
  import org.apache.cloudstack.api.response.DiskOfferingResponse;
  import org.apache.cloudstack.api.response.DomainResponse;
  import org.apache.cloudstack.api.response.DomainRouterResponse;
  import org.apache.cloudstack.api.response.EventResponse;
  import org.apache.cloudstack.api.response.ExtractResponse;
  import org.apache.cloudstack.api.response.FirewallResponse;
  import org.apache.cloudstack.api.response.FirewallRuleResponse;
  import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
  import org.apache.cloudstack.api.response.GuestOSCategoryResponse;
  import org.apache.cloudstack.api.response.GuestOSResponse;
  import org.apache.cloudstack.api.response.GuestOsMappingResponse;
  import org.apache.cloudstack.api.response.GuestVlanRangeResponse;
  import org.apache.cloudstack.api.response.GuestVlanResponse;
  import org.apache.cloudstack.api.response.GuiThemeResponse;
  import org.apache.cloudstack.api.response.HostForMigrationResponse;
  import org.apache.cloudstack.api.response.HostResponse;
  import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse;
  import org.apache.cloudstack.api.response.HypervisorGuestOsNamesResponse;
  import org.apache.cloudstack.api.response.HypervisorGuestOsResponse;
  import org.apache.cloudstack.api.response.IPAddressResponse;
  import org.apache.cloudstack.api.response.ImageStoreResponse;
  import org.apache.cloudstack.api.response.InstanceGroupResponse;
  import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse;
  import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
  import org.apache.cloudstack.api.response.IpQuarantineResponse;
  import org.apache.cloudstack.api.response.IpRangeResponse;
  import org.apache.cloudstack.api.response.Ipv4RouteResponse;
  import org.apache.cloudstack.api.response.Ipv6RouteResponse;
  import org.apache.cloudstack.api.response.IsolationMethodResponse;
  import org.apache.cloudstack.api.response.LBHealthCheckPolicyResponse;
  import org.apache.cloudstack.api.response.LBHealthCheckResponse;
  import org.apache.cloudstack.api.response.LBStickinessPolicyResponse;
  import org.apache.cloudstack.api.response.LBStickinessResponse;
  import org.apache.cloudstack.api.response.ListResponse;
  import org.apache.cloudstack.api.response.LoadBalancerResponse;
  import org.apache.cloudstack.api.response.ManagementServerResponse;
  import org.apache.cloudstack.api.response.NetworkACLItemResponse;
  import org.apache.cloudstack.api.response.NetworkACLResponse;
  import org.apache.cloudstack.api.response.NetworkOfferingResponse;
  import org.apache.cloudstack.api.response.NetworkPermissionsResponse;
  import org.apache.cloudstack.api.response.NetworkResponse;
  import org.apache.cloudstack.api.response.NicExtraDhcpOptionResponse;
  import org.apache.cloudstack.api.response.NicResponse;
  import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
  import org.apache.cloudstack.api.response.ObjectStoreResponse;
  import org.apache.cloudstack.api.response.OvsProviderResponse;
  import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
  import org.apache.cloudstack.api.response.PodResponse;
  import org.apache.cloudstack.api.response.PortableIpRangeResponse;
  import org.apache.cloudstack.api.response.PortableIpResponse;
  import org.apache.cloudstack.api.response.PrivateGatewayResponse;
  import org.apache.cloudstack.api.response.ProjectAccountResponse;
  import org.apache.cloudstack.api.response.ProjectInvitationResponse;
  import org.apache.cloudstack.api.response.ProjectResponse;
  import org.apache.cloudstack.api.response.ProviderResponse;
  import org.apache.cloudstack.api.response.RegionResponse;
  import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
  import org.apache.cloudstack.api.response.ResourceCountResponse;
  import org.apache.cloudstack.api.response.ResourceIconResponse;
  import org.apache.cloudstack.api.response.ResourceLimitResponse;
  import org.apache.cloudstack.api.response.ResourceTagResponse;
  import org.apache.cloudstack.api.response.RollingMaintenanceHostSkippedResponse;
  import org.apache.cloudstack.api.response.RollingMaintenanceHostUpdatedResponse;
  import org.apache.cloudstack.api.response.RollingMaintenanceResponse;
  import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
  import org.apache.cloudstack.api.response.SSHKeyPairResponse;
  import org.apache.cloudstack.api.response.SecondaryStorageHeuristicsResponse;
  import org.apache.cloudstack.api.response.SecurityGroupResponse;
  import org.apache.cloudstack.api.response.SecurityGroupRuleResponse;
  import org.apache.cloudstack.api.response.ServiceOfferingResponse;
  import org.apache.cloudstack.api.response.ServiceResponse;
  import org.apache.cloudstack.api.response.SharedFSResponse;
  import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse;
  import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse;
  import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse;
  import org.apache.cloudstack.api.response.SnapshotPolicyResponse;
  import org.apache.cloudstack.api.response.SnapshotResponse;
  import org.apache.cloudstack.api.response.SnapshotScheduleResponse;
  import org.apache.cloudstack.api.response.StaticRouteResponse;
  import org.apache.cloudstack.api.response.StorageNetworkIpRangeResponse;
  import org.apache.cloudstack.api.response.StoragePoolResponse;
  import org.apache.cloudstack.api.response.SystemVmInstanceResponse;
  import org.apache.cloudstack.api.response.SystemVmResponse;
  import org.apache.cloudstack.api.response.TemplatePermissionsResponse;
  import org.apache.cloudstack.api.response.TemplateResponse;
  import org.apache.cloudstack.api.response.TrafficMonitorResponse;
  import org.apache.cloudstack.api.response.TrafficTypeResponse;
  import org.apache.cloudstack.api.response.UnmanagedInstanceDiskResponse;
  import org.apache.cloudstack.api.response.UnmanagedInstanceResponse;
  import org.apache.cloudstack.api.response.UpgradeRouterTemplateResponse;
  import org.apache.cloudstack.api.response.UsageRecordResponse;
  import org.apache.cloudstack.api.response.UserDataResponse;
  import org.apache.cloudstack.api.response.UserResponse;
  import org.apache.cloudstack.api.response.UserVmResponse;
  import org.apache.cloudstack.api.response.VMSnapshotResponse;
  import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
  import org.apache.cloudstack.api.response.VlanIpRangeResponse;
  import org.apache.cloudstack.api.response.VolumeResponse;
  import org.apache.cloudstack.api.response.VpcOfferingResponse;
  import org.apache.cloudstack.api.response.VpcResponse;
  import org.apache.cloudstack.api.response.VpnUsersResponse;
  import org.apache.cloudstack.api.response.ZoneResponse;
  import org.apache.cloudstack.backup.BackupOffering;
  import org.apache.cloudstack.backup.BackupRepository;
  import org.apache.cloudstack.backup.BackupSchedule;
  import org.apache.cloudstack.backup.dao.BackupOfferingDao;
  import org.apache.cloudstack.backup.dao.BackupRepositoryDao;
  import org.apache.cloudstack.config.Configuration;
  import org.apache.cloudstack.config.ConfigurationGroup;
  import org.apache.cloudstack.config.ConfigurationSubGroup;
  import org.apache.cloudstack.consoleproxy.ConsoleSession;
  import org.apache.cloudstack.context.CallContext;
  import org.apache.cloudstack.direct.download.DirectDownloadCertificate;
  import org.apache.cloudstack.direct.download.DirectDownloadCertificateHostMap;
  import org.apache.cloudstack.direct.download.DirectDownloadManager;
  import org.apache.cloudstack.direct.download.DirectDownloadManager.HostCertificateStatus.CertificateStatus;
  import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
  import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
  import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
  import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
  import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
  import org.apache.cloudstack.framework.jobs.AsyncJob;
  import org.apache.cloudstack.framework.jobs.AsyncJobManager;
  import org.apache.cloudstack.gui.theme.GuiThemeJoin;
  import org.apache.cloudstack.management.ManagementServerHost;
  import org.apache.cloudstack.network.BgpPeerVO;
  import org.apache.cloudstack.network.RoutedIpv4Manager;
  import org.apache.cloudstack.network.dao.BgpPeerDao;
  import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
  import org.apache.cloudstack.region.PortableIp;
  import org.apache.cloudstack.region.PortableIpRange;
  import org.apache.cloudstack.region.Region;
  import org.apache.cloudstack.secstorage.heuristics.Heuristic;
  import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
  import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
  import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
  import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
  import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
  import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
  import org.apache.cloudstack.storage.object.Bucket;
  import org.apache.cloudstack.storage.object.ObjectStore;
  import org.apache.cloudstack.storage.sharedfs.SharedFS;
  import org.apache.cloudstack.storage.sharedfs.query.vo.SharedFSJoinVO;
  import org.apache.cloudstack.usage.Usage;
  import org.apache.cloudstack.usage.UsageService;
  import org.apache.cloudstack.usage.UsageTypes;
  import org.apache.cloudstack.vm.UnmanagedInstanceTO;
  import org.apache.commons.collections.CollectionUtils;
  import org.apache.commons.lang3.ObjectUtils;
  import org.apache.commons.lang3.StringUtils;
  import org.apache.logging.log4j.LogManager;
  import org.apache.logging.log4j.Logger;
  
  import com.cloud.agent.api.VgpuTypesInfo;
  import com.cloud.api.query.ViewResponseHelper;
  import com.cloud.api.query.dao.UserVmJoinDao;
  import com.cloud.api.query.vo.AccountJoinVO;
  import com.cloud.api.query.vo.AsyncJobJoinVO;
  import com.cloud.api.query.vo.ControlledViewEntity;
  import com.cloud.api.query.vo.DataCenterJoinVO;
  import com.cloud.api.query.vo.DiskOfferingJoinVO;
  import com.cloud.api.query.vo.DomainRouterJoinVO;
  import com.cloud.api.query.vo.EventJoinVO;
  import com.cloud.api.query.vo.HostJoinVO;
  import com.cloud.api.query.vo.ImageStoreJoinVO;
  import com.cloud.api.query.vo.InstanceGroupJoinVO;
  import com.cloud.api.query.vo.NetworkOfferingJoinVO;
  import com.cloud.api.query.vo.ProjectAccountJoinVO;
  import com.cloud.api.query.vo.ProjectInvitationJoinVO;
  import com.cloud.api.query.vo.ProjectJoinVO;
  import com.cloud.api.query.vo.ResourceTagJoinVO;
  import com.cloud.api.query.vo.SecurityGroupJoinVO;
  import com.cloud.api.query.vo.ServiceOfferingJoinVO;
  import com.cloud.api.query.vo.StoragePoolJoinVO;
  import com.cloud.api.query.vo.TemplateJoinVO;
  import com.cloud.api.query.vo.UserAccountJoinVO;
  import com.cloud.api.query.vo.UserVmJoinVO;
  import com.cloud.api.query.vo.VolumeJoinVO;
  import com.cloud.api.query.vo.VpcOfferingJoinVO;
  import com.cloud.api.response.ApiResponseSerializer;
  import com.cloud.capacity.Capacity;
  import com.cloud.capacity.CapacityVO;
  import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
  import com.cloud.configuration.ConfigurationManager;
  import com.cloud.configuration.Resource.ResourceOwnerType;
  import com.cloud.configuration.Resource.ResourceType;
  import com.cloud.configuration.ResourceCount;
  import com.cloud.configuration.ResourceLimit;
  import com.cloud.dc.ClusterDetailsDao;
  import com.cloud.dc.ClusterVO;
  import com.cloud.dc.DataCenter;
  import com.cloud.dc.DataCenterGuestIpv6Prefix;
  import com.cloud.dc.DataCenterVO;
  import com.cloud.dc.HostPodVO;
  import com.cloud.dc.Pod;
  import com.cloud.dc.StorageNetworkIpRange;
  import com.cloud.dc.Vlan;
  import com.cloud.dc.Vlan.VlanType;
  import com.cloud.dc.VlanVO;
  import com.cloud.domain.Domain;
  import com.cloud.domain.DomainVO;
  import com.cloud.event.Event;
  import com.cloud.exception.InvalidParameterValueException;
  import com.cloud.exception.PermissionDeniedException;
  import com.cloud.host.ControlState;
  import com.cloud.host.Host;
  import com.cloud.host.HostVO;
  import com.cloud.hypervisor.HypervisorCapabilities;
  import com.cloud.network.GuestVlan;
  import com.cloud.network.GuestVlanRange;
  import com.cloud.network.IpAddress;
  import com.cloud.network.Ipv6Service;
  import com.cloud.network.Network;
  import com.cloud.network.Network.Capability;
  import com.cloud.network.Network.Provider;
  import com.cloud.network.Network.Service;
  import com.cloud.network.NetworkModel;
  import com.cloud.network.NetworkPermission;
  import com.cloud.network.NetworkProfile;
  import com.cloud.network.Networks.BroadcastDomainType;
  import com.cloud.network.Networks.IsolationType;
  import com.cloud.network.Networks.TrafficType;
  import com.cloud.network.OvsProvider;
  import com.cloud.network.PhysicalNetwork;
  import com.cloud.network.PhysicalNetworkServiceProvider;
  import com.cloud.network.PhysicalNetworkTrafficType;
  import com.cloud.network.PublicIpQuarantine;
  import com.cloud.network.RemoteAccessVpn;
  import com.cloud.network.RouterHealthCheckResult;
  import com.cloud.network.Site2SiteCustomerGateway;
  import com.cloud.network.Site2SiteVpnConnection;
  import com.cloud.network.Site2SiteVpnGateway;
  import com.cloud.network.VirtualRouterProvider;
  import com.cloud.network.VpnUser;
  import com.cloud.network.VpnUserVO;
  import com.cloud.network.as.AutoScalePolicy;
  import com.cloud.network.as.AutoScaleVmGroup;
  import com.cloud.network.as.AutoScaleVmProfile;
  import com.cloud.network.as.AutoScaleVmProfileVO;
  import com.cloud.network.as.Condition;
  import com.cloud.network.as.ConditionVO;
  import com.cloud.network.as.Counter;
  import com.cloud.network.dao.FirewallRulesDao;
  import com.cloud.network.dao.IPAddressDao;
  import com.cloud.network.dao.IPAddressVO;
  import com.cloud.network.dao.LoadBalancerVO;
  import com.cloud.network.dao.NetworkDao;
  import com.cloud.network.dao.NetworkDetailVO;
  import com.cloud.network.dao.NetworkDetailsDao;
  import com.cloud.network.dao.NetworkServiceMapDao;
  import com.cloud.network.dao.NetworkVO;
  import com.cloud.network.dao.PhysicalNetworkVO;
  import com.cloud.network.router.VirtualRouter;
  import com.cloud.network.rules.FirewallRule;
  import com.cloud.network.rules.HealthCheckPolicy;
  import com.cloud.network.rules.LoadBalancer;
  import com.cloud.network.rules.LoadBalancerContainer.Scheme;
  import com.cloud.network.rules.PortForwardingRule;
  import com.cloud.network.rules.PortForwardingRuleVO;
  import com.cloud.network.rules.StaticNatRule;
  import com.cloud.network.rules.StickinessPolicy;
  import com.cloud.network.security.SecurityGroup;
  import com.cloud.network.security.SecurityGroupVO;
  import com.cloud.network.security.SecurityRule;
  import com.cloud.network.security.SecurityRule.SecurityRuleType;
  import com.cloud.network.vpc.NetworkACL;
  import com.cloud.network.vpc.NetworkACLItem;
  import com.cloud.network.vpc.PrivateGateway;
  import com.cloud.network.vpc.StaticRoute;
  import com.cloud.network.vpc.Vpc;
  import com.cloud.network.vpc.VpcOffering;
  import com.cloud.network.vpc.VpcVO;
  import com.cloud.network.vpc.dao.VpcOfferingDao;
  import com.cloud.offering.DiskOffering;
  import com.cloud.offering.NetworkOffering;
  import com.cloud.offering.NetworkOffering.Detail;
  import com.cloud.offering.ServiceOffering;
  import com.cloud.offerings.NetworkOfferingVO;
  import com.cloud.offerings.dao.NetworkOfferingDao;
  import com.cloud.org.Cluster;
  import com.cloud.projects.Project;
  import com.cloud.projects.ProjectAccount;
  import com.cloud.projects.ProjectInvitation;
  import com.cloud.region.ha.GlobalLoadBalancerRule;
  import com.cloud.resource.RollingMaintenanceManager;
  import com.cloud.resource.icon.ResourceIconVO;
  import com.cloud.server.ResourceIcon;
  import com.cloud.server.ResourceIconManager;
  import com.cloud.server.ResourceTag;
  import com.cloud.server.ResourceTag.ResourceObjectType;
  import com.cloud.service.ServiceOfferingVO;
  import com.cloud.storage.DataStoreRole;
  import com.cloud.storage.DiskOfferingVO;
  import com.cloud.storage.GuestOS;
  import com.cloud.storage.GuestOSCategoryVO;
  import com.cloud.storage.GuestOSHypervisor;
  import com.cloud.storage.GuestOsCategory;
  import com.cloud.storage.ImageStore;
  import com.cloud.storage.Snapshot;
  import com.cloud.storage.SnapshotVO;
  import com.cloud.storage.StoragePool;
  import com.cloud.storage.Upload;
  import com.cloud.storage.VMTemplateVO;
  import com.cloud.storage.Volume;
  import com.cloud.storage.VolumeVO;
  import com.cloud.storage.dao.GuestOSCategoryDao;
  import com.cloud.storage.dao.GuestOSDao;
  import com.cloud.storage.dao.VolumeDao;
  import com.cloud.storage.snapshot.SnapshotPolicy;
  import com.cloud.storage.snapshot.SnapshotSchedule;
  import com.cloud.tags.dao.ResourceTagDao;
  import com.cloud.template.VirtualMachineTemplate;
  import com.cloud.user.Account;
  import com.cloud.user.AccountManager;
  import com.cloud.user.SSHKeyPair;
  import com.cloud.user.User;
  import com.cloud.user.UserAccount;
  import com.cloud.user.UserData;
  import com.cloud.user.UserStatisticsVO;
  import com.cloud.user.dao.UserDataDao;
  import com.cloud.user.dao.UserStatisticsDao;
  import com.cloud.uservm.UserVm;
  import com.cloud.utils.Pair;
  import com.cloud.utils.crypt.DBEncryptionUtil;
  import com.cloud.utils.db.EntityManager;
  import com.cloud.utils.db.SearchBuilder;
  import com.cloud.utils.db.SearchCriteria;
  import com.cloud.utils.db.SearchCriteria.Op;
  import com.cloud.utils.exception.CloudRuntimeException;
  import com.cloud.utils.net.Dhcp;
  import com.cloud.utils.net.Ip;
  import com.cloud.utils.net.NetUtils;
  import com.cloud.utils.security.CertificateHelper;
  import com.cloud.vm.ConsoleProxyVO;
  import com.cloud.vm.InstanceGroup;
  import com.cloud.vm.Nic;
  import com.cloud.vm.NicExtraDhcpOptionVO;
  import com.cloud.vm.NicProfile;
  import com.cloud.vm.NicSecondaryIp;
  import com.cloud.vm.NicVO;
  import com.cloud.vm.VMInstanceVO;
  import com.cloud.vm.VirtualMachine;
  import com.cloud.vm.VirtualMachine.Type;
  import com.cloud.vm.dao.NicExtraDhcpOptionDao;
  import com.cloud.vm.dao.NicSecondaryIpVO;
  import com.cloud.vm.snapshot.VMSnapshot;
  import com.cloud.vm.snapshot.VMSnapshotVO;
  import com.cloud.vm.snapshot.dao.VMSnapshotDao;
  
  import sun.security.x509.X509CertImpl;
  
  public class ApiResponseHelper implements ResponseGenerator {
  
      protected Logger logger = LogManager.getLogger(ApiResponseHelper.class);
      private static final DecimalFormat s_percentFormat = new DecimalFormat("##.##");
  
      @Inject
      private EntityManager _entityMgr;
      @Inject
      private UsageService _usageSvc;
      @Inject
      NetworkModel _ntwkModel;
      @Inject
      protected AccountManager _accountMgr;
      @Inject
      protected AsyncJobManager _jobMgr;
      @Inject
      ConfigurationManager _configMgr;
      @Inject
      SnapshotDataFactory snapshotfactory;
      @Inject
      private VolumeDao _volumeDao;
      @Inject
      private DataStoreManager _dataStoreMgr;
      @Inject
      private SnapshotDataStoreDao _snapshotStoreDao;
      @Inject
      private PrimaryDataStoreDao _storagePoolDao;
      @Inject
      private ClusterDetailsDao _clusterDetailsDao;
      @Inject
      private ResourceTagDao _resourceTagDao;
      @Inject
      private NicExtraDhcpOptionDao _nicExtraDhcpOptionDao;
      @Inject
      private IPAddressDao userIpAddressDao;
      @Inject
      NetworkDetailsDao networkDetailsDao;
      @Inject
      private VMSnapshotDao vmSnapshotDao;
      @Inject
      private BackupOfferingDao backupOfferingDao;
      @Inject
      private GuestOSCategoryDao _guestOsCategoryDao;
      @Inject
      private GuestOSDao _guestOsDao;
      @Inject
      private AnnotationDao annotationDao;
      @Inject
      private UserStatisticsDao userStatsDao;
      @Inject
      private NetworkDao networkDao;
      @Inject
      NetworkOfferingDao networkOfferingDao;
      @Inject
      Ipv6Service ipv6Service;
      @Inject
      UserVmJoinDao userVmJoinDao;
      @Inject
      NetworkServiceMapDao ntwkSrvcDao;
      @Inject
      FirewallRulesDao firewallRulesDao;
      @Inject
      UserDataDao userDataDao;
      @Inject
      VlanDetailsDao vlanDetailsDao;
      @Inject
      BackupRepositoryDao backupRepositoryDao;
      @Inject
      private ASNumberRangeDao asNumberRangeDao;
      @Inject
      private ASNumberDao asNumberDao;
  
      @Inject
      ObjectStoreDao _objectStoreDao;
      @Inject
      VpcOfferingDao vpcOfferingDao;
      @Inject
      BgpPeerDao bgpPeerDao;
      @Inject
      RoutedIpv4Manager routedIpv4Manager;
      @Inject
      ResourceIconManager resourceIconManager;
  
      public static String getPrettyDomainPath(String path) {
          if (path == null) {
              return null;
          }
          StringBuilder domainPath = new StringBuilder("ROOT");
          (domainPath.append(path)).deleteCharAt(domainPath.length() - 1);
          return domainPath.toString();
      }
  
      @Override
      public UserResponse createUserResponse(User user) {
          UserAccountJoinVO vUser = ApiDBUtils.newUserView(user);
          return ApiDBUtils.newUserResponse(vUser);
      }
  
      // this method is used for response generation via createAccount (which
      // creates an account + user)
      @Override
      public AccountResponse createUserAccountResponse(ResponseView view, UserAccount user) {
          return ApiDBUtils.newAccountResponse(view, EnumSet.of(DomainDetails.all), ApiDBUtils.findAccountViewById(user.getAccountId()));
      }
  
      @Override
      public AccountResponse createAccountResponse(ResponseView view, Account account) {
          AccountJoinVO vUser = ApiDBUtils.newAccountView(account);
          return ApiDBUtils.newAccountResponse(view, EnumSet.of(DomainDetails.all), vUser);
      }
  
      @Override
      public UserResponse createUserResponse(UserAccount user) {
          UserAccountJoinVO vUser = ApiDBUtils.newUserView(user);
          return ApiDBUtils.newUserResponse(vUser);
      }
  
      @Override
      public DomainResponse createDomainResponse(Domain domain) {
          DomainResponse domainResponse = new DomainResponse();
          domainResponse.setDomainName(domain.getName());
          domainResponse.setId(domain.getUuid());
          domainResponse.setLevel(domain.getLevel());
          domainResponse.setCreated(domain.getCreated());
          domainResponse.setNetworkDomain(domain.getNetworkDomain());
          Domain parentDomain = ApiDBUtils.findDomainById(domain.getParent());
          if (parentDomain != null) {
              domainResponse.setParentDomainId(parentDomain.getUuid());
          }
          domainResponse.setPath(getPrettyDomainPath(domain.getPath()));
          if (domain.getParent() != null) {
              domainResponse.setParentDomainName(ApiDBUtils.findDomainById(domain.getParent()).getName());
          }
          if (domain.getChildCount() > 0) {
              domainResponse.setHasChild(true);
          }
          domainResponse.setObjectName("domain");
          return domainResponse;
      }
  
      @Override
      public DiskOfferingResponse createDiskOfferingResponse(DiskOffering offering) {
          DiskOfferingJoinVO vOffering = ApiDBUtils.newDiskOfferingView(offering);
          return ApiDBUtils.newDiskOfferingResponse(vOffering);
      }
  
      @Override
      public ResourceLimitResponse createResourceLimitResponse(ResourceLimit limit) {
          ResourceLimitResponse resourceLimitResponse = new ResourceLimitResponse();
          if (limit.getResourceOwnerType() == ResourceOwnerType.Domain) {
              populateDomain(resourceLimitResponse, limit.getOwnerId());
          } else if (limit.getResourceOwnerType() == ResourceOwnerType.Account) {
              Account accountTemp = ApiDBUtils.findAccountById(limit.getOwnerId());
              populateAccount(resourceLimitResponse, limit.getOwnerId());
              populateDomain(resourceLimitResponse, accountTemp.getDomainId());
          }
          resourceLimitResponse.setResourceType(limit.getType());
  
          if (ResourceType.isStorageType(limit.getType()) && limit.getMax() >= 0) {
              resourceLimitResponse.setMax((long)Math.ceil((double)limit.getMax() / ResourceType.bytesToGiB));
          } else {
              resourceLimitResponse.setMax(limit.getMax());
          }
          resourceLimitResponse.setTag(limit.getTag());
          resourceLimitResponse.setObjectName("resourcelimit");
  
          return resourceLimitResponse;
      }
  
      @Override
      public ResourceCountResponse createResourceCountResponse(ResourceCount resourceCount) {
          ResourceCountResponse resourceCountResponse = new ResourceCountResponse();
  
          if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Account) {
              Account accountTemp = ApiDBUtils.findAccountById(resourceCount.getOwnerId());
              if (accountTemp != null) {
                  populateAccount(resourceCountResponse, accountTemp.getId());
                  populateDomain(resourceCountResponse, accountTemp.getDomainId());
              }
          } else if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Domain) {
              populateDomain(resourceCountResponse, resourceCount.getOwnerId());
          }
  
          resourceCountResponse.setResourceType(resourceCount.getType());
          resourceCountResponse.setResourceCount(resourceCount.getCount());
          resourceCountResponse.setObjectName(ApiConstants.RESOURCE_COUNT);
          if (StringUtils.isNotEmpty(resourceCount.getTag())) {
              resourceCountResponse.setTag(resourceCount.getTag());
          }
          return resourceCountResponse;
      }
  
      @Override
      public ServiceOfferingResponse createServiceOfferingResponse(ServiceOffering offering) {
          ServiceOfferingJoinVO vOffering = ApiDBUtils.newServiceOfferingView(offering);
          return ApiDBUtils.newServiceOfferingResponse(vOffering);
      }
  
      @Override
      public ConfigurationResponse createConfigurationResponse(Configuration cfg) {
          ConfigurationResponse cfgResponse = new ConfigurationResponse();
          cfgResponse.setCategory(cfg.getCategory());
          Pair<String, String> configGroupAndSubGroup = _configMgr.getConfigurationGroupAndSubGroup(cfg.getName());
          cfgResponse.setGroup(configGroupAndSubGroup.first());
          cfgResponse.setSubGroup(configGroupAndSubGroup.second());
          cfgResponse.setDescription(cfg.getDescription());
          cfgResponse.setName(cfg.getName());
          if (cfg.isEncrypted()) {
              cfgResponse.setValue(DBEncryptionUtil.encrypt(cfg.getValue()));
          } else {
              cfgResponse.setValue(cfg.getValue());
          }
          cfgResponse.setDefaultValue(cfg.getDefaultValue());
          cfgResponse.setIsDynamic(cfg.isDynamic());
          cfgResponse.setComponent(cfg.getComponent());
          if (cfg.getParent() != null) {
              cfgResponse.setParent(cfg.getParent());
          }
          cfgResponse.setDisplayText(cfg.getDisplayText());
          cfgResponse.setType(_configMgr.getConfigurationType(cfg.getName()));
          if (cfg.getOptions() != null) {
              cfgResponse.setOptions(cfg.getOptions());
          }
          cfgResponse.setObjectName("configuration");
  
          return cfgResponse;
      }
  
      @Override
      public ConfigurationGroupResponse createConfigurationGroupResponse(ConfigurationGroup cfgGroup) {
          ConfigurationGroupResponse cfgGroupResponse = new ConfigurationGroupResponse();
          cfgGroupResponse.setGroupName(cfgGroup.getName());
          cfgGroupResponse.setDescription(cfgGroup.getDescription());
          cfgGroupResponse.setPrecedence(cfgGroup.getPrecedence());
  
          List<? extends ConfigurationSubGroup> subgroups = _configMgr.getConfigurationSubGroups(cfgGroup.getId());
          List<ConfigurationSubGroupResponse> cfgSubGroupResponses = new ArrayList<>();
          for (ConfigurationSubGroup subgroup : subgroups) {
              ConfigurationSubGroupResponse cfgSubGroupResponse = createConfigurationSubGroupResponse(subgroup);
              cfgSubGroupResponses.add(cfgSubGroupResponse);
          }
          cfgGroupResponse.setSubGroups(cfgSubGroupResponses);
          cfgGroupResponse.setObjectName("configurationgroup");
          return cfgGroupResponse;
      }
  
      private ConfigurationSubGroupResponse createConfigurationSubGroupResponse(ConfigurationSubGroup cfgSubGroup) {
          ConfigurationSubGroupResponse cfgSubGroupResponse = new ConfigurationSubGroupResponse();
          cfgSubGroupResponse.setSubGroupName(cfgSubGroup.getName());
          cfgSubGroupResponse.setPrecedence(cfgSubGroup.getPrecedence());
          cfgSubGroupResponse.setObjectName("subgroup");
          return cfgSubGroupResponse;
      }
  
      @Override
      public SnapshotResponse createSnapshotResponse(Snapshot snapshot) {
          SnapshotResponse snapshotResponse = new SnapshotResponse();
          snapshotResponse.setId(snapshot.getUuid());
  
          populateOwner(snapshotResponse, snapshot);
  
          VolumeVO volume = findVolumeById(snapshot.getVolumeId());
          String snapshotTypeStr = snapshot.getRecurringType().name();
          snapshotResponse.setSnapshotType(snapshotTypeStr);
          if (volume != null) {
              snapshotResponse.setVolumeId(volume.getUuid());
              snapshotResponse.setVolumeName(volume.getName());
              snapshotResponse.setVolumeType(volume.getVolumeType().name());
              snapshotResponse.setVolumeState(volume.getState().name());
              snapshotResponse.setVirtualSize(volume.getSize());
              DataCenter zone = ApiDBUtils.findZoneById(volume.getDataCenterId());
              if (zone != null) {
                  snapshotResponse.setZoneId(zone.getUuid());
                  snapshotResponse.setZoneName(zone.getName());
              }
  
              if (volume.getVolumeType() == Volume.Type.ROOT && volume.getInstanceId() != null) {
                  //TODO combine lines and 489 into a join in the volume dao
                  VMInstanceVO instance = ApiDBUtils.findVMInstanceById(volume.getInstanceId());
                  if (instance != null) {
                      GuestOS guestOs = ApiDBUtils.findGuestOSById(instance.getGuestOSId());
                      if (guestOs != null) {
                          snapshotResponse.setOsTypeId(guestOs.getUuid());
                          snapshotResponse.setOsDisplayName(guestOs.getDisplayName());
                      }
                  }
              }
          }
          snapshotResponse.setCreated(snapshot.getCreated());
          snapshotResponse.setName(snapshot.getName());
          snapshotResponse.setIntervalType(ApiDBUtils.getSnapshotIntervalTypes(snapshot.getId()));
          snapshotResponse.setState(snapshot.getState());
          snapshotResponse.setLocationType(ApiDBUtils.getSnapshotLocationType(snapshot.getId()));
  
          SnapshotInfo snapshotInfo = null;
  
          if (snapshot instanceof SnapshotInfo) {
              snapshotInfo = (SnapshotInfo)snapshot;
          } else {
              DataStoreRole dataStoreRole = getDataStoreRole(snapshot, _snapshotStoreDao, _dataStoreMgr);
  
              snapshotInfo = snapshotfactory.getSnapshotWithRoleAndZone(snapshot.getId(), dataStoreRole, volume.getDataCenterId());
          }
  
          if (snapshotInfo == null) {
              logger.debug("Unable to find info for image store snapshot with uuid " + snapshot.getUuid());
              snapshotResponse.setRevertable(false);
          } else {
          snapshotResponse.setRevertable(snapshotInfo.isRevertable());
          snapshotResponse.setPhysicalSize(snapshotInfo.getPhysicalSize());
          }
  
          // set tag information
          List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.Snapshot, snapshot.getId());
          List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
          for (ResourceTag tag : tags) {
              ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
              CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
          }
          snapshotResponse.setTags(new HashSet<>(tagResponses));
          snapshotResponse.setHasAnnotation(annotationDao.hasAnnotations(snapshot.getUuid(), AnnotationService.EntityType.SNAPSHOT.name(),
                  _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
  
          snapshotResponse.setObjectName("snapshot");
          return snapshotResponse;
      }
  
      public static DataStoreRole getDataStoreRole(Snapshot snapshot, SnapshotDataStoreDao snapshotStoreDao, DataStoreManager dataStoreMgr) {
          SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findOneBySnapshotAndDatastoreRole(snapshot.getId(), DataStoreRole.Primary);
  
          if (snapshotStore == null) {
              return DataStoreRole.Image;
          }
  
          long storagePoolId = snapshotStore.getDataStoreId();
          DataStore dataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
          if (dataStore == null) {
              return DataStoreRole.Image;
          }
  
          Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
  
          if (mapCapabilities != null) {
              String value = mapCapabilities.get(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString());
              Boolean supportsStorageSystemSnapshots = new Boolean(value);
  
              if (supportsStorageSystemSnapshots) {
                  return DataStoreRole.Primary;
              }
          }
  
          return DataStoreRole.Image;
      }
  
      @Override
      public VMSnapshotResponse createVMSnapshotResponse(VMSnapshot vmSnapshot) {
          VMSnapshotResponse vmSnapshotResponse = new VMSnapshotResponse();
          vmSnapshotResponse.setId(vmSnapshot.getUuid());
          vmSnapshotResponse.setName(vmSnapshot.getName());
          vmSnapshotResponse.setState(vmSnapshot.getState());
          vmSnapshotResponse.setCreated(vmSnapshot.getCreated());
          vmSnapshotResponse.setDescription(vmSnapshot.getDescription());
          vmSnapshotResponse.setDisplayName(vmSnapshot.getDisplayName());
          UserVm vm = ApiDBUtils.findUserVmById(vmSnapshot.getVmId());
          if (vm != null) {
              vmSnapshotResponse.setVirtualMachineId(vm.getUuid());
              vmSnapshotResponse.setVirtualMachineName(StringUtils.isEmpty(vm.getDisplayName()) ? vm.getHostName() : vm.getDisplayName());
              vmSnapshotResponse.setHypervisor(vm.getHypervisorType().getHypervisorDisplayName());
              DataCenterVO datacenter = ApiDBUtils.findZoneById(vm.getDataCenterId());
              if (datacenter != null) {
                  vmSnapshotResponse.setZoneId(datacenter.getUuid());
                  vmSnapshotResponse.setZoneName(datacenter.getName());
              }
          }
          if (vmSnapshot.getParent() != null) {
              VMSnapshot vmSnapshotParent = ApiDBUtils.getVMSnapshotById(vmSnapshot.getParent());
              if (vmSnapshotParent != null) {
                  vmSnapshotResponse.setParent(vmSnapshotParent.getUuid());
                  vmSnapshotResponse.setParentName(vmSnapshotParent.getDisplayName());
              }
          }
          populateOwner(vmSnapshotResponse, vmSnapshot);
  
          List<? extends ResourceTag> tags = _resourceTagDao.listBy(vmSnapshot.getId(), ResourceObjectType.VMSnapshot);
          List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
          for (ResourceTag tag : tags) {
              ResourceTagResponse tagResponse = createResourceTagResponse(tag, false);
              CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
          }
          vmSnapshotResponse.setTags(new HashSet<>(tagResponses));
          vmSnapshotResponse.setHasAnnotation(annotationDao.hasAnnotations(vmSnapshot.getUuid(), AnnotationService.EntityType.VM_SNAPSHOT.name(),
                  _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
  
          vmSnapshotResponse.setCurrent(vmSnapshot.getCurrent());
          vmSnapshotResponse.setType(vmSnapshot.getType().toString());
          vmSnapshotResponse.setObjectName("vmsnapshot");
          return vmSnapshotResponse;
      }
  
      @Override
      public SnapshotPolicyResponse createSnapshotPolicyResponse(SnapshotPolicy policy) {
          SnapshotPolicyResponse policyResponse = new SnapshotPolicyResponse();
          policyResponse.setId(policy.getUuid());
          Volume vol = ApiDBUtils.findVolumeById(policy.getVolumeId());
          if (vol != null) {
              policyResponse.setVolumeId(vol.getUuid());
              policyResponse.setVolumeName(vol.getName());
          }
          policyResponse.setSchedule(policy.getSchedule());
          policyResponse.setIntervalType(policy.getInterval());
          policyResponse.setMaxSnaps(policy.getMaxSnaps());
          policyResponse.setTimezone(policy.getTimezone());
          policyResponse.setForDisplay(policy.isDisplay());
          policyResponse.setObjectName("snapshotpolicy");
  
          List<? extends ResourceTag> tags = _resourceTagDao.listBy(policy.getId(), ResourceObjectType.SnapshotPolicy);
          List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
          for (ResourceTag tag : tags) {
              ResourceTagResponse tagResponse = createResourceTagResponse(tag, false);
              CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
          }
          policyResponse.setTags(new HashSet<>(tagResponses));
          List<ZoneResponse> zoneResponses = new ArrayList<>();
          List<DataCenterVO> zones = ApiDBUtils.findSnapshotPolicyZones(policy, vol);
          for (DataCenterVO zone : zones) {
              ZoneResponse zoneResponse = new ZoneResponse();
              zoneResponse.setId(zone.getUuid());
              zoneResponse.setName(zone.getName());
              zoneResponse.setTags(null);
              zoneResponses.add(zoneResponse);
          }
          policyResponse.setZones(new HashSet<>(zoneResponses));
          List<StoragePoolResponse> poolResponses = new ArrayList<>();
          List<StoragePoolVO> pools = ApiDBUtils.findSnapshotPolicyPools(policy, vol);
          for (StoragePoolVO pool : pools) {
              StoragePoolResponse storagePoolResponse = new StoragePoolResponse();
              storagePoolResponse.setId(pool.getUuid());
              storagePoolResponse.setName(pool.getName());
              poolResponses.add(storagePoolResponse);
          }
          policyResponse.setStoragePools(new HashSet<>(poolResponses));
  
          return policyResponse;
      }
  
      @Override
      public HostResponse createHostResponse(Host host) {
          return createHostResponse(host, EnumSet.of(HostDetails.all));
      }
  
      @Override
      public HostResponse createHostResponse(Host host, EnumSet<HostDetails> details) {
          List<HostJoinVO> viewHosts = ApiDBUtils.newHostView(host);
          List<HostResponse> listHosts = ViewResponseHelper.createHostResponse(details, viewHosts.toArray(new HostJoinVO[viewHosts.size()]));
          assert listHosts != null && listHosts.size() == 1 : "There should be one host returned";
          return listHosts.get(0);
      }
  
      @Override
      public HostForMigrationResponse createHostForMigrationResponse(Host host) {
          return createHostForMigrationResponse(host, EnumSet.of(HostDetails.all));
      }
  
      @Override
      public HostForMigrationResponse createHostForMigrationResponse(Host host, EnumSet<HostDetails> details) {
          List<HostJoinVO> viewHosts = ApiDBUtils.newHostView(host);
          List<HostForMigrationResponse> listHosts = ViewResponseHelper.createHostForMigrationResponse(details, viewHosts.toArray(new HostJoinVO[viewHosts.size()]));
          assert listHosts != null && listHosts.size() == 1 : "There should be one host returned";
          return listHosts.get(0);
      }
  
      @Override
      public VlanIpRangeResponse createVlanIpRangeResponse(Vlan vlan) {
          return createVlanIpRangeResponse(VlanIpRangeResponse.class, vlan);
      }
  
      @Override
      public VlanIpRangeResponse createVlanIpRangeResponse(Class<? extends VlanIpRangeResponse> subClass, Vlan vlan) {
          try {
              Long podId = ApiDBUtils.getPodIdForVlan(vlan.getId());
  
              VlanIpRangeResponse vlanResponse = subClass.newInstance();
              vlanResponse.setId(vlan.getUuid());
              if (vlan.getVlanType() != null) {
                  vlanResponse.setForVirtualNetwork(vlan.getVlanType().equals(VlanType.VirtualNetwork));
              }
              vlanResponse.setVlan(vlan.getVlanTag());
              DataCenter zone = ApiDBUtils.findZoneById(vlan.getDataCenterId());
              if (zone != null) {
                  vlanResponse.setZoneId(zone.getUuid());
              }
  
              if (podId != null) {
                  HostPodVO pod = ApiDBUtils.findPodById(podId);
                  if (pod != null) {
                      vlanResponse.setPodId(pod.getUuid());
                      vlanResponse.setPodName(pod.getName());
                  }
              }
  
              String gateway = vlan.getVlanGateway();
              String netmask = vlan.getVlanNetmask();
              vlanResponse.setGateway(gateway);
              vlanResponse.setNetmask(netmask);
              if (StringUtils.isNotEmpty(gateway) && StringUtils.isNotEmpty(netmask)) {
                  vlanResponse.setCidr(NetUtils.getCidrFromGatewayAndNetmask(gateway, netmask));
              }
  
              // get start ip and end ip of corresponding vlan
              String ipRange = vlan.getIpRange();
              if (ipRange != null) {
                  String[] range = ipRange.split("-");
                  vlanResponse.setStartIp(range[0]);
                  vlanResponse.setEndIp(range[1]);
              }
  
              vlanResponse.setIp6Gateway(vlan.getIp6Gateway());
              vlanResponse.setIp6Cidr(vlan.getIp6Cidr());
  
              String ip6Range = vlan.getIp6Range();
              if (ip6Range != null) {
                  String[] range = ip6Range.split("-");
                  vlanResponse.setStartIpv6(range[0]);
                  vlanResponse.setEndIpv6(range[1]);
              }
  
              if (vlan.getNetworkId() != null) {
                  Network nw = ApiDBUtils.findNetworkById(vlan.getNetworkId());
                  if (nw != null) {
                      vlanResponse.setNetworkId(nw.getUuid());
                  }
              }
              Account owner = ApiDBUtils.getVlanAccount(vlan.getId());
              if (owner != null) {
                  populateAccount(vlanResponse, owner.getId());
                  populateDomain(vlanResponse, owner.getDomainId());
              } else {
                  Domain domain = ApiDBUtils.getVlanDomain(vlan.getId());
                  if (domain != null) {
                      populateDomain(vlanResponse, domain.getId());
                  } else {
                      Long networkId = vlan.getNetworkId();
                      if (networkId != null) {
                          Network network = _ntwkModel.getNetwork(networkId);
                          if (network != null && TrafficType.Guest.equals(network.getTrafficType())) {
                              Long accountId = network.getAccountId();
                              populateAccount(vlanResponse, accountId);
                              populateDomain(vlanResponse, ApiDBUtils.findAccountById(accountId).getDomainId());
                          }
                      }
                  }
              }
  
              if (vlan.getPhysicalNetworkId() != null) {
                  PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(vlan.getPhysicalNetworkId());
                  if (pnw != null) {
                      vlanResponse.setPhysicalNetworkId(pnw.getUuid());
                  }
              }
              vlanResponse.setForSystemVms(isForSystemVms(vlan.getId()));
              vlanResponse.setProvider(getProviderFromVlanDetailKey(vlan));
              vlanResponse.setObjectName("vlan");
              return vlanResponse;
          } catch (InstantiationException | IllegalAccessException e) {
              throw new CloudRuntimeException("Failed to create Vlan IP Range response", e);
          }
      }
  
      private String getProviderFromVlanDetailKey(Vlan vlan) {
          for (Map.Entry<String, String> entry : ConfigurationService.ProviderDetailKeyMap.entrySet()) {
              VlanDetailsVO vlanDetail = vlanDetailsDao.findDetail(vlan.getId(), entry.getValue());
              if (Objects.nonNull(vlanDetail) && "true".equals(vlanDetail.getValue())) {
                  return entry.getKey();
              }
          }
          return null;
      }
      /**
       * Return true if vlan IP range is dedicated for system vms (SSVM and CPVM), false if not
       * @param vlanId vlan id
       * @return true if VLAN IP range is dedicated to system vms
       */
      private boolean isForSystemVms(long vlanId){
          SearchBuilder<IPAddressVO> sb = userIpAddressDao.createSearchBuilder();
          sb.and("vlanId", sb.entity().getVlanId(), SearchCriteria.Op.EQ);
          SearchCriteria<IPAddressVO> sc = sb.create();
          sc.setParameters("vlanId", vlanId);
          IPAddressVO userIpAddresVO = userIpAddressDao.findOneBy(sc);
          return userIpAddresVO != null ? userIpAddresVO.isForSystemVms() : false;
      }
  
      private void addVmDetailsInIpResponse(IPAddressResponse response, IpAddress ipAddress) {
          if (ipAddress.getAllocatedToAccountId() != null && ipAddress.getAllocatedToAccountId() == Account.ACCOUNT_ID_SYSTEM) {
              NicVO nic = ApiDBUtils.findByIp4AddressAndNetworkId(ipAddress.getAddress().toString(), ipAddress.getNetworkId());
              if (nic != null) {
                  addSystemVmInfoToIpResponse(nic, response);
              }
          }
          if (ipAddress.isForRouter()) {
              response.setVirtualMachineType(Type.DomainRouter.toString());
          }
          if (ipAddress.getAssociatedWithVmId() != null) {
              addUserVmDetailsInIpResponse(response, ipAddress);
          }
      }
  
      private void addSystemVmInfoToIpResponse(NicVO nic, IPAddressResponse ipResponse) {
          final boolean isAdmin = Account.Type.ADMIN.equals(CallContext.current().getCallingAccount().getType());
          if (!isAdmin) {
              return;
          }
          try {
              nic.getInstanceId();
          } catch (NullPointerException ex) {
              return;
          }
  
          VirtualMachine vm = ApiDBUtils.findVMInstanceById(nic.getInstanceId());
          if (vm == null) {
              return;
          }
          ipResponse.setVirtualMachineId(vm.getUuid());
          ipResponse.setVirtualMachineName(vm.getHostName());
          ipResponse.setVirtualMachineType(vm.getType().toString());
      }
  
      private void addUserVmDetailsInIpResponse(IPAddressResponse response, IpAddress ipAddress) {
          VirtualMachine vm = ApiDBUtils.findVMInstanceById(ipAddress.getAssociatedWithVmId());
          if (vm == null) {
              return;
          }
          if (vm.getType().equals(Type.User)) {
              UserVm userVm = ApiDBUtils.findUserVmById(ipAddress.getAssociatedWithVmId());
              if (userVm != null) {
                  response.setVirtualMachineId(userVm.getUuid());
                  response.setVirtualMachineName(userVm.getHostName());
                  response.setVirtualMachineType(userVm.getType().toString());
                  response.setVirtualMachineDisplayName(ObjectUtils.firstNonNull(userVm.getDisplayName(), userVm.getHostName()));
              }
          } else if (vm.getType().equals(Type.DomainRouter)) {
              final boolean isAdmin = Account.Type.ADMIN.equals(CallContext.current().getCallingAccount().getType());
              if (isAdmin) {
                  response.setVirtualMachineId(vm.getUuid());
                  response.setVirtualMachineName(vm.getHostName());
              }
              response.setVirtualMachineType(vm.getType().toString());
          }
      }
  
      @Override
      public IPAddressResponse createIPAddressResponse(ResponseView view, IpAddress ipAddr) {
          VlanVO vlan = ApiDBUtils.findVlanById(ipAddr.getVlanId());
          boolean forVirtualNetworks = vlan.getVlanType().equals(VlanType.VirtualNetwork);
          long zoneId = ipAddr.getDataCenterId();
  
          IPAddressResponse ipResponse = new IPAddressResponse();
          ipResponse.setId(ipAddr.getUuid());
          ipResponse.setIpAddress(ipAddr.getAddress().toString());
          if (ipAddr.getAllocatedTime() != null) {
              ipResponse.setAllocated(ipAddr.getAllocatedTime());
          }
          DataCenter zone = ApiDBUtils.findZoneById(ipAddr.getDataCenterId());
          if (zone != null) {
              ipResponse.setZoneId(zone.getUuid());
              ipResponse.setZoneName(zone.getName());
          }
          ipResponse.setSourceNat(ipAddr.isSourceNat());
          ipResponse.setIsSystem(ipAddr.getSystem());
  
          // get account information
          if (ipAddr.getAllocatedToAccountId() != null) {
              populateOwner(ipResponse, ipAddr);
          }
  
          ipResponse.setForVirtualNetwork(forVirtualNetworks);
          ipResponse.setStaticNat(ipAddr.isOneToOneNat());
  
          addVmDetailsInIpResponse(ipResponse, ipAddr);
          if (ipAddr.getVmIp() != null) {
              ipResponse.setVirtualMachineIp(ipAddr.getVmIp());
          }
  
          if (ipAddr.getAssociatedWithNetworkId() != null) {
              Network ntwk = ApiDBUtils.findNetworkById(ipAddr.getAssociatedWithNetworkId());
              if (ntwk != null) {
                  ipResponse.setAssociatedNetworkId(ntwk.getUuid());
                  ipResponse.setAssociatedNetworkName(ntwk.getName());
              }
          }
  
  
          setVpcIdInResponse(ipAddr.getVpcId(), ipResponse::setVpcId, ipResponse::setVpcName);
  
  
          // Network id the ip is associated with (if associated networkId is
          // null, try to get this information from vlan)
          Long vlanNetworkId = ApiDBUtils.getVlanNetworkId(ipAddr.getVlanId());
  
          // Network id the ip belongs to
          Long networkId;
          if (vlanNetworkId != null) {
              networkId = vlanNetworkId;
          } else {
              networkId = ApiDBUtils.getPublicNetworkIdByZone(zoneId);
          }
  
          if (networkId != null) {
              NetworkVO nw = ApiDBUtils.findNetworkById(networkId);
              if (nw != null) {
                  ipResponse.setNetworkId(nw.getUuid());
                  ipResponse.setNetworkName(nw.getName());
              }
          }
          ipResponse.setState(ipAddr.getState().toString());
  
          if (ipAddr.getPhysicalNetworkId() != null) {
              PhysicalNetworkVO pnw = ApiDBUtils.findPhysicalNetworkById(ipAddr.getPhysicalNetworkId());
              if (pnw != null) {
                  ipResponse.setPhysicalNetworkId(pnw.getUuid());
              }
          }
  
          // show vm info for shared networks
          showVmInfoForSharedNetworks(forVirtualNetworks, ipAddr, ipResponse);
  
          // show this info to full view only
          if (view == ResponseView.Full) {
              VlanVO vl = ApiDBUtils.findVlanById(ipAddr.getVlanId());
              if (vl != null) {
                  ipResponse.setVlanId(vl.getUuid());
                  ipResponse.setVlanName(vl.getVlanTag());
              }
          }
  
          if (ipAddr.getSystem()) {
              if (ipAddr.isOneToOneNat()) {
                  ipResponse.setPurpose(IpAddress.Purpose.StaticNat.toString());
              } else {
                  ipResponse.setPurpose(IpAddress.Purpose.Lb.toString());
              }
          }
  
          ipResponse.setForDisplay(ipAddr.isDisplay());
  
          ipResponse.setPortable(ipAddr.isPortable());
          ipResponse.setForSystemVms(ipAddr.isForSystemVms());
          if (Objects.nonNull(getProviderFromVlanDetailKey(vlan))) {
              ipResponse.setForProvider(true);
          }
  
          //set tag information
          List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.PublicIpAddress, ipAddr.getId());
          List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
          for (ResourceTag tag : tags) {
              ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
              CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
          }
          ipResponse.setTags(tagResponses);
          ipResponse.setHasAnnotation(annotationDao.hasAnnotations(ipAddr.getUuid(), AnnotationService.EntityType.PUBLIC_IP_ADDRESS.name(),
                  _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
  
          ipResponse.setHasRules(firewallRulesDao.countRulesByIpId(ipAddr.getId()) > 0);
          ipResponse.setObjectName("ipaddress");
          return ipResponse;
      }
  
  
      private void setVpcIdInResponse(Long vpcId, Consumer<String> vpcUuidSetter, Consumer<String> vpcNameSetter) {
          if (vpcId != null) {
              Vpc vpc = ApiDBUtils.findVpcById(vpcId);
              if (vpc != null) {
                  try {
                      _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, false, vpc);
                      vpcUuidSetter.accept(vpc.getUuid());
                  } catch (PermissionDeniedException e) {
                      logger.debug("Not setting the vpcId to the response because the caller does not have access to the VPC");
                  }
                  vpcNameSetter.accept(vpc.getName());
              }
          }
      }
  
      private void showVmInfoForSharedNetworks(boolean forVirtualNetworks, IpAddress ipAddr, IPAddressResponse ipResponse) {
          if (!forVirtualNetworks) {
              NicVO nic = ApiDBUtils.findByIp4AddressAndNetworkId(ipAddr.getAddress().toString(), ipAddr.getNetworkId());
  
              if (nic == null) {  // find in nic_secondary_ips, user vm only
                  NicSecondaryIpVO secondaryIp =
                          ApiDBUtils.findSecondaryIpByIp4AddressAndNetworkId(ipAddr.getAddress().toString(), ipAddr.getNetworkId());
                  if (secondaryIp != null) {
                      UserVm vm = ApiDBUtils.findUserVmById(secondaryIp.getVmId());
                      if (vm != null) {
                          ipResponse.setVirtualMachineId(vm.getUuid());
                          ipResponse.setVirtualMachineName(vm.getHostName());
                          if (vm.getDisplayName() != null) {
                              ipResponse.setVirtualMachineDisplayName(vm.getDisplayName());
                          } else {
                              ipResponse.setVirtualMachineDisplayName(vm.getHostName());
                          }
                      }
                  }
              } else if (nic.getVmType() == VirtualMachine.Type.User) {
                  UserVm vm = ApiDBUtils.findUserVmById(nic.getInstanceId());
                  if (vm != null) {
                      ipResponse.setVirtualMachineId(vm.getUuid());
                      ipResponse.setVirtualMachineName(vm.getHostName());
                      if (vm.getDisplayName() != null) {
                          ipResponse.setVirtualMachineDisplayName(vm.getDisplayName());
                      } else {
                          ipResponse.setVirtualMachineDisplayName(vm.getHostName());
                      }
                  }
              } else if (nic.getVmType() == Type.DomainRouter) {
                  VirtualMachine vm = ApiDBUtils.findVMInstanceById(nic.getInstanceId());
                  if (vm != null) {
                      ipResponse.setVirtualMachineId(vm.getUuid());
                      ipResponse.setVirtualMachineName(vm.getHostName());
                      ipResponse.setVirtualMachineType(vm.getType().toString());
                  }
              } else if (nic.getVmType().isUsedBySystem()) {
                  ipResponse.setIsSystem(true);
                  addSystemVmInfoToIpResponse(nic, ipResponse);
              }
          }
      }
  
      @Override
      public LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer) {
          LoadBalancerResponse lbResponse = new LoadBalancerResponse();
          lbResponse.setId(loadBalancer.getUuid());
          lbResponse.setName(loadBalancer.getName());
          lbResponse.setDescription(loadBalancer.getDescription());
          List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(loadBalancer.getId());
          lbResponse.setCidrList(StringUtils.join(cidrs, ","));
  
          IPAddressVO publicIp = ApiDBUtils.findIpAddressById(loadBalancer.getSourceIpAddressId());
          lbResponse.setPublicIpId(publicIp.getUuid());
          lbResponse.setPublicIp(publicIp.getAddress().addr());
          lbResponse.setPublicPort(Integer.toString(loadBalancer.getSourcePortStart()));
          lbResponse.setPrivatePort(Integer.toString(loadBalancer.getDefaultPortStart()));
          lbResponse.setAlgorithm(loadBalancer.getAlgorithm());
          lbResponse.setLbProtocol(loadBalancer.getLbProtocol());
          lbResponse.setForDisplay(loadBalancer.isDisplay());
          FirewallRule.State state = loadBalancer.getState();
          String stateToSet = state.toString();
          if (state.equals(FirewallRule.State.Revoke)) {
              stateToSet = "Deleting";
          }
          lbResponse.setState(stateToSet);
          populateOwner(lbResponse, loadBalancer);
          DataCenter zone = ApiDBUtils.findZoneById(publicIp.getDataCenterId());
          if (zone != null) {
              lbResponse.setZoneId(zone.getUuid());
              lbResponse.setZoneName(zone.getName());
          }
  
          //set tag information
          List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.LoadBalancer, loadBalancer.getId());
          List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
          for (ResourceTag tag : tags) {
              ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
              CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
          }
          lbResponse.setTags(tagResponses);
  
          Network ntwk = ApiDBUtils.findNetworkById(loadBalancer.getNetworkId());
          lbResponse.setNetworkId(ntwk.getUuid());
  
          lbResponse.setCidrList(loadBalancer.getCidrList());
  
          lbResponse.setObjectName("loadbalancer");
          return lbResponse;
      }
  
      @Override
      public GlobalLoadBalancerResponse createGlobalLoadBalancerResponse(GlobalLoadBalancerRule globalLoadBalancerRule) {
          GlobalLoadBalancerResponse response = new GlobalLoadBalancerResponse();
          response.setAlgorithm(globalLoadBalancerRule.getAlgorithm());
          response.setStickyMethod(globalLoadBalancerRule.getPersistence());
          response.setServiceType(globalLoadBalancerRule.getServiceType());
          response.setServiceDomainName(globalLoadBalancerRule.getGslbDomain() + "." + ApiDBUtils.getDnsNameConfiguredForGslb());
          response.setName(globalLoadBalancerRule.getName());
          response.setDescription(globalLoadBalancerRule.getDescription());
          response.setRegionIdId(globalLoadBalancerRule.getRegion());
          response.setId(globalLoadBalancerRule.getUuid());
          populateOwner(response, globalLoadBalancerRule);
          response.setObjectName("globalloadbalancer");
  
          List<LoadBalancerResponse> siteLbResponses = new ArrayList<LoadBalancerResponse>();
          List<? extends LoadBalancer> siteLoadBalaners = ApiDBUtils.listSiteLoadBalancers(globalLoadBalancerRule.getId());
          for (LoadBalancer siteLb : siteLoadBalaners) {
              LoadBalancerResponse siteLbResponse = createLoadBalancerResponse(siteLb);
              siteLbResponses.add(siteLbResponse);
          }
          response.setSiteLoadBalancers(siteLbResponses);
          return response;
      }
  
      @Override
      public PodResponse createMinimalPodResponse(Pod pod) {
          PodResponse podResponse = new PodResponse();
          podResponse.setId(pod.getUuid());
          podResponse.setName(pod.getName());
          podResponse.setObjectName("pod");
          return podResponse;
      }
  
      @Override
      public PodResponse createPodResponse(Pod pod, Boolean showCapacities) {
          String[] ipRange = new String[2];
          List<String> startIps = new ArrayList<String>();
          List<String> endIps = new ArrayList<String>();
          List<String> forSystemVms = new ArrayList<String>();
          List<String> vlanIds = new ArrayList<String>();
  
          List<IpRangeResponse> ipRanges = new ArrayList<>();
  
          if (pod.getDescription() != null && pod.getDescription().length() > 0) {
              final String[] existingPodIpRanges = pod.getDescription().split(",");
  
              for(String podIpRange: existingPodIpRanges) {
                  IpRangeResponse ipRangeResponse = new IpRangeResponse();
                  final String[] existingPodIpRange = podIpRange.split("-");
  
                  String startIp = ((existingPodIpRange.length > 0) && (existingPodIpRange[0] != null)) ? existingPodIpRange[0] : "";
                  ipRangeResponse.setStartIp(startIp);
                  startIps.add(startIp);
  
                  String endIp = ((existingPodIpRange.length > 1) && (existingPodIpRange[1] != null)) ? existingPodIpRange[1] : "";
                  ipRangeResponse.setEndIp(endIp);
                  endIps.add(endIp);
  
                  String forSystemVm = (existingPodIpRange.length > 2) && (existingPodIpRange[2] != null) ? existingPodIpRange[2] : "0";
                  ipRangeResponse.setForSystemVms(forSystemVm);
                  forSystemVms.add(forSystemVm);
  
                  String vlanId = (existingPodIpRange.length > 3) &&
                          (existingPodIpRange[3] != null && !existingPodIpRange[3].equals("untagged")) ?
                          BroadcastDomainType.Vlan.toUri(existingPodIpRange[3]).toString() :
                          BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED).toString();
                  ipRangeResponse.setVlanId(vlanId);
                  vlanIds.add(vlanId);
  
                  ipRanges.add(ipRangeResponse);
              }
          }
  
          PodResponse podResponse = new PodResponse();
          podResponse.setId(pod.getUuid());
          podResponse.setName(pod.getName());
          DataCenterVO zone = ApiDBUtils.findZoneById(pod.getDataCenterId());
          if (zone != null) {
              podResponse.setZoneId(zone.getUuid());
              podResponse.setZoneName(zone.getName());
          }
          podResponse.setNetmask(NetUtils.getCidrNetmask(pod.getCidrSize()));
          podResponse.setIpRanges(ipRanges);
          podResponse.setStartIp(startIps);
          podResponse.setEndIp(endIps);
          podResponse.setForSystemVms(forSystemVms);
          podResponse.setVlanId(vlanIds);
          podResponse.setGateway(pod.getGateway());
          podResponse.setAllocationState(pod.getAllocationState().toString());
          podResponse.setStorageAccessGroups(pod.getStorageAccessGroups());
          podResponse.setZoneStorageAccessGroups(zone.getStorageAccessGroups());
          if (showCapacities != null && showCapacities) {
              List<SummedCapacity> capacities = ApiDBUtils.getCapacityByClusterPodZone(null, pod.getId(), null);
              Set<CapacityResponse> capacityResponses = new HashSet<CapacityResponse>();
              for (SummedCapacity capacity : capacities) {
                  CapacityResponse capacityResponse = new CapacityResponse();
                  capacityResponse.setCapacityType(capacity.getCapacityType());
                  capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
                  capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity());
                  if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
                      List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, pod.getId(), null);
                      capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity());
                      capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity());
                  } else {
                      capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
                  }
                  if (capacityResponse.getCapacityTotal() != 0) {
                      capacityResponse.setPercentUsed(s_percentFormat.format((float)capacityResponse.getCapacityUsed() / (float)capacityResponse.getCapacityTotal() * 100f));
                  } else {
                      capacityResponse.setPercentUsed(s_percentFormat.format(0L));
                  }
                  capacityResponses.add(capacityResponse);
              }
              // Do it for stats as well.
              capacityResponses.addAll(getStatsCapacityresponse(null, null, pod.getId(), pod.getDataCenterId()));
              podResponse.setCapacities(new ArrayList<CapacityResponse>(capacityResponses));
          }
  
          podResponse.setHasAnnotation(annotationDao.hasAnnotations(pod.getUuid(), AnnotationService.EntityType.POD.name(),
                  _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
          podResponse.setObjectName("pod");
          return podResponse;
      }
  
      @Override
      public ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities, Boolean showResourceIcon) {
          DataCenterJoinVO vOffering = ApiDBUtils.newDataCenterView(dataCenter);
          return ApiDBUtils.newDataCenterResponse(view, vOffering, showCapacities, showResourceIcon);
      }
  
      public static List<CapacityResponse> getDataCenterCapacityResponse(Long zoneId) {
          List<SummedCapacity> capacities = ApiDBUtils.getCapacityByClusterPodZone(zoneId, null, null);
          Set<CapacityResponse> capacityResponses = new HashSet<CapacityResponse>();
  
          for (SummedCapacity capacity : capacities) {
              CapacityResponse capacityResponse = new CapacityResponse();
              capacityResponse.setCapacityType(capacity.getCapacityType());
              capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
              capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity());
              if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
                  List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(zoneId, null, null);
                  capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity());
                  capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity());
              } else {
                  capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
              }
              if (capacityResponse.getCapacityTotal() != 0) {
                  capacityResponse.setPercentUsed(s_percentFormat.format((float)capacityResponse.getCapacityUsed() / (float)capacityResponse.getCapacityTotal() * 100f));
              } else {
                  capacityResponse.setPercentUsed(s_percentFormat.format(0L));
              }
              capacityResponses.add(capacityResponse);
          }
          // Do it for stats as well.
          capacityResponses.addAll(getStatsCapacityresponse(null, null, null, zoneId));
  
          return new ArrayList<CapacityResponse>(capacityResponses);
      }
  
      private static List<CapacityResponse> getStatsCapacityresponse(Long poolId, Long clusterId, Long podId, Long zoneId) {
          List<CapacityVO> capacities = new ArrayList<CapacityVO>();
          capacities.add(ApiDBUtils.getStoragePoolUsedStats(poolId, clusterId, podId, zoneId));
          if (clusterId == null && podId == null) {
              capacities.add(ApiDBUtils.getSecondaryStorageUsedStats(poolId, zoneId));
              capacities.add(ApiDBUtils.getObjectStorageUsedStats(zoneId));
          }
  
          List<CapacityResponse> capacityResponses = new ArrayList<CapacityResponse>();
          for (CapacityVO capacity : capacities) {
              CapacityResponse capacityResponse = new CapacityResponse();
              capacityResponse.setCapacityType(capacity.getCapacityType());
              capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
              capacityResponse.setCapacityUsed(capacity.getUsedCapacity());
              capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
              if (capacityResponse.getCapacityTotal() != 0) {
                  capacityResponse.setPercentUsed(s_percentFormat.format((float)capacityResponse.getCapacityUsed() / (float)capacityResponse.getCapacityTotal() * 100f));
              } else {
                  capacityResponse.setPercentUsed(s_percentFormat.format(0L));
              }
              capacityResponses.add(capacityResponse);
          }
  
          return capacityResponses;
      }
  
      @Override
      public DataCenterGuestIpv6PrefixResponse createDataCenterGuestIpv6PrefixResponse(DataCenterGuestIpv6Prefix prefix) {
          DataCenterGuestIpv6PrefixResponse response = new DataCenterGuestIpv6PrefixResponse();
          response.setId(prefix.getUuid());
          response.setPrefix(prefix.getPrefix());
          DataCenter dc = ApiDBUtils.findZoneById(prefix.getDataCenterId());
          response.setZoneId(dc.getUuid());
          Pair<Integer, Integer> usedTotal = ipv6Service.getUsedTotalIpv6SubnetForPrefix(prefix);
          int used = usedTotal.first();
          int total = usedTotal.second();
          response.setUsedSubnets(used);
          response.setAvailableSubnets(total - used);
          response.setTotalSubnets(total);
          response.setCreated(prefix.getCreated());
          return response;
      }
  
      @Override
      public VolumeResponse createVolumeResponse(ResponseView view, Volume volume) {
          List<VolumeJoinVO> viewVrs = ApiDBUtils.newVolumeView(volume);
          List<VolumeResponse> listVrs = ViewResponseHelper.createVolumeResponse(view, viewVrs.toArray(new VolumeJoinVO[viewVrs.size()]));
          assert listVrs != null && listVrs.size() == 1 : "There should be one volume returned";
          return listVrs.get(0);
      }
  
      @Override
      public InstanceGroupResponse createInstanceGroupResponse(InstanceGroup group) {
          InstanceGroupJoinVO vgroup = ApiDBUtils.newInstanceGroupView(group);
          return ApiDBUtils.newInstanceGroupResponse(vgroup);
  
      }
  
      @Override
      public StoragePoolResponse createStoragePoolResponse(StoragePool pool) {
          List<StoragePoolJoinVO> viewPools = ApiDBUtils.newStoragePoolView(pool);
          List<StoragePoolResponse> listPools = ViewResponseHelper.createStoragePoolResponse(false, viewPools.toArray(new StoragePoolJoinVO[viewPools.size()]));
          assert listPools != null && listPools.size() == 1 : "There should be one storage pool returned";
          return listPools.get(0);
      }
  
      @Override
      public ImageStoreResponse createImageStoreResponse(ImageStore os) {
          List<ImageStoreJoinVO> viewStores = ApiDBUtils.newImageStoreView(os);
          List<ImageStoreResponse> listStores = ViewResponseHelper.createImageStoreResponse(viewStores.toArray(new ImageStoreJoinVO[viewStores.size()]));
          assert listStores != null && listStores.size() == 1 : "There should be one image data store returned";
          return listStores.get(0);
      }
  
      @Override
      public StoragePoolResponse createStoragePoolForMigrationResponse(StoragePool pool) {
          List<StoragePoolJoinVO> viewPools = ApiDBUtils.newStoragePoolView(pool);
          List<StoragePoolResponse> listPools = ViewResponseHelper.createStoragePoolForMigrationResponse(viewPools.toArray(new StoragePoolJoinVO[viewPools.size()]));
          assert listPools != null && listPools.size() == 1 : "There should be one storage pool returned";
          return listPools.get(0);
      }
  
      @Override
      public ClusterResponse createMinimalClusterResponse(Cluster cluster) {
          ClusterResponse clusterResponse = new ClusterResponse();
          clusterResponse.setId(cluster.getUuid());
          clusterResponse.setName(cluster.getName());
          clusterResponse.setObjectName("cluster");
          return clusterResponse;
      }
  
      @Override
      public ClusterResponse createClusterResponse(Cluster cluster, Boolean showCapacities) {
          ClusterResponse clusterResponse = new ClusterResponse();
          clusterResponse.setInternalId(cluster.getId());
          clusterResponse.setId(cluster.getUuid());
          clusterResponse.setName(cluster.getName());
          HostPodVO pod = ApiDBUtils.findPodById(cluster.getPodId());
          if (pod != null) {
              clusterResponse.setPodId(pod.getUuid());
              clusterResponse.setPodName(pod.getName());
          }
          DataCenterVO dc = ApiDBUtils.findZoneById(cluster.getDataCenterId());
          if (dc != null) {
              clusterResponse.setZoneId(dc.getUuid());
              clusterResponse.setZoneName(dc.getName());
          }
          clusterResponse.setHypervisorType(cluster.getHypervisorType().getHypervisorDisplayName());
          clusterResponse.setClusterType(cluster.getClusterType().toString());
          clusterResponse.setAllocationState(cluster.getAllocationState().toString());
          clusterResponse.setManagedState(cluster.getManagedState().toString());
          String cpuOvercommitRatio = ApiDBUtils.findClusterDetails(cluster.getId(), "cpuOvercommitRatio");
          String memoryOvercommitRatio = ApiDBUtils.findClusterDetails(cluster.getId(), "memoryOvercommitRatio");
          clusterResponse.setCpuOvercommitRatio(cpuOvercommitRatio);
          clusterResponse.setMemoryOvercommitRatio(memoryOvercommitRatio);
          clusterResponse.setResourceDetails(_clusterDetailsDao.findDetails(cluster.getId()));
          if (cluster.getArch() != null) {
              clusterResponse.setArch(cluster.getArch().getType());
          }
  
          clusterResponse.setStorageAccessGroups(cluster.getStorageAccessGroups());
          clusterResponse.setPodStorageAccessGroups(pod.getStorageAccessGroups());
          clusterResponse.setZoneStorageAccessGroups(dc.getStorageAccessGroups());
  
          if (showCapacities != null && showCapacities) {
              List<SummedCapacity> capacities = ApiDBUtils.getCapacityByClusterPodZone(null, null, cluster.getId());
              Set<CapacityResponse> capacityResponses = new HashSet<CapacityResponse>();
  
              for (SummedCapacity capacity : capacities) {
                  CapacityResponse capacityResponse = new CapacityResponse();
                  capacityResponse.setCapacityType(capacity.getCapacityType());
                  capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
                  capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity());
  
                  if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
                      List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, null, cluster.getId());
                      capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity());
                      capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity());
                  } else {
                      capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
                  }
                  if (capacityResponse.getCapacityTotal() != 0) {
                      capacityResponse.setPercentUsed(s_percentFormat.format((float)capacityResponse.getCapacityUsed() / (float)capacityResponse.getCapacityTotal() * 100f));
                  } else {
                      capacityResponse.setPercentUsed(s_percentFormat.format(0L));
                  }
                  capacityResponses.add(capacityResponse);
              }
              // Do it for stats as well.
              capacityResponses.addAll(getStatsCapacityresponse(null, cluster.getId(), pod.getId(), pod.getDataCenterId()));
              clusterResponse.setCapacities(new ArrayList<CapacityResponse>(capacityResponses));
          }
          clusterResponse.setHasAnnotation(annotationDao.hasAnnotations(cluster.getUuid(), AnnotationService.EntityType.CLUSTER.name(),
                  _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
          clusterResponse.setObjectName("cluster");
          return clusterResponse;
      }
  
      @Override
      public FirewallRuleResponse createPortForwardingRuleResponse(PortForwardingRule fwRule) {
          FirewallRuleResponse response = new FirewallRuleResponse();
          response.setId(fwRule.getUuid());
          response.setPrivateStartPort(Integer.toString(fwRule.getDestinationPortStart()));
          response.setPrivateEndPort(Integer.toString(fwRule.getDestinationPortEnd()));
          response.setProtocol(fwRule.getProtocol());
          response.setPublicStartPort(Integer.toString(fwRule.getSourcePortStart()));
          response.setPublicEndPort(Integer.toString(fwRule.getSourcePortEnd()));
          List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId());
          response.setCidrList(StringUtils.join(cidrs, ","));
  
          Network guestNtwk = ApiDBUtils.findNetworkById(fwRule.getNetworkId());
          response.setNetworkId(guestNtwk.getUuid());
  
  
          IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
  
          if (ip != null)
          {
              response.setPublicIpAddressId(ip.getUuid());
              response.setPublicIpAddress(ip.getAddress().addr());
              if (fwRule.getDestinationIpAddress() != null)
              {
                  response.setDestNatVmIp(fwRule.getDestinationIpAddress().toString());
                  UserVm vm = ApiDBUtils.findUserVmById(fwRule.getVirtualMachineId());
                  if (vm != null) {
                      response.setVirtualMachineId(vm.getUuid());
                      response.setVirtualMachineName(vm.getHostName());
  
                      if (vm.getDisplayName() != null) {
                          response.setVirtualMachineDisplayName(vm.getDisplayName());
                      } else {
                          response.setVirtualMachineDisplayName(vm.getHostName());
                      }
                  }
              }
          }
          FirewallRule.State state = fwRule.getState();
          String stateToSet = state.toString();
          if (state.equals(FirewallRule.State.Revoke)) {
              stateToSet = "Deleting";
          }
  
          // set tag information
          List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.PortForwardingRule, fwRule.getId());
          List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
          for (ResourceTag tag : tags) {
              ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
              CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
          }
          response.setTags(tagResponses);
  
          response.setState(stateToSet);
          response.setForDisplay(fwRule.isDisplay());
          response.setObjectName("portforwardingrule");
          return response;
      }
  
      @Override
      public IpForwardingRuleResponse createIpForwardingRuleResponse(StaticNatRule fwRule) {
          IpForwardingRuleResponse response = new IpForwardingRuleResponse();
          response.setId(fwRule.getUuid());
          response.setProtocol(fwRule.getProtocol());
  
          IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
  
          if (ip != null) {
              response.setPublicIpAddressId(ip.getId());
              response.setPublicIpAddress(ip.getAddress().addr());
              if (fwRule.getDestIpAddress() != null) {
                  UserVm vm = ApiDBUtils.findUserVmById(ip.getAssociatedWithVmId());
                  if (vm != null) {// vm might be destroyed
                      response.setVirtualMachineId(vm.getUuid());
                      response.setVirtualMachineName(vm.getHostName());
                      if (vm.getDisplayName() != null) {
                          response.setVirtualMachineDisplayName(vm.getDisplayName());
                      } else {
                          response.setVirtualMachineDisplayName(vm.getHostName());
                      }
                  }
              }
          }
          FirewallRule.State state = fwRule.getState();
          String stateToSet = state.toString();
          if (state.equals(FirewallRule.State.Revoke)) {
              stateToSet = "Deleting";
          }
  
          response.setStartPort(fwRule.getSourcePortStart());
          response.setEndPort(fwRule.getSourcePortEnd());
          response.setProtocol(fwRule.getProtocol());
          response.setState(stateToSet);
          response.setObjectName("ipforwardingrule");
          return response;
      }
  
      /*
      @Override
      public List<UserVmResponse> createUserVmResponse(String objectName, UserVm... userVms) {
          return createUserVmResponse(null, objectName, userVms);
      }
  
      @Override
      public List<UserVmResponse> createUserVmResponse(String objectName, EnumSet<VMDetails> details, UserVm... userVms) {
          return createUserVmResponse(null, objectName, userVms);
      }
      */
  
      @Override
      public List<UserVmResponse> createUserVmResponse(ResponseView view, String objectName, EnumSet<VMDetails> details, UserVm... userVms) {
          List<UserVmJoinVO> viewVms = ApiDBUtils.newUserVmView(userVms);
          return ViewResponseHelper.createUserVmResponse(view, objectName, details, viewVms.toArray(new UserVmJoinVO[viewVms.size()]));
  
      }
  
      @Override
      public List<UserVmResponse> createUserVmResponse(ResponseView view, String objectName, UserVm... userVms) {
          List<UserVmJoinVO> viewVms = ApiDBUtils.newUserVmView(userVms);
          return ViewResponseHelper.createUserVmResponse(view, objectName, viewVms.toArray(new UserVmJoinVO[viewVms.size()]));
      }
  
      @Override
      public DomainRouterResponse createDomainRouterResponse(VirtualRouter router) {
          List<DomainRouterJoinVO> viewVrs = ApiDBUtils.newDomainRouterView(router);
          List<DomainRouterResponse> listVrs = ViewResponseHelper.createDomainRouterResponse(viewVrs.toArray(new DomainRouterJoinVO[viewVrs.size()]));
          assert listVrs != null && listVrs.size() == 1 : "There should be one virtual router returned";
          return listVrs.get(0);
      }
  
  
      @Override
      public SystemVmResponse createSystemVmResponse(VirtualMachine vm) {
          SystemVmResponse vmResponse = new SystemVmResponse();
          if (vm.getType() == Type.SecondaryStorageVm || vm.getType() == Type.ConsoleProxy || vm.getType() == Type.DomainRouter || vm.getType() == Type.NetScalerVm) {
              vmResponse.setId(vm.getUuid());
              vmResponse.setSystemVmType(vm.getType().toString().toLowerCase());
              vmResponse.setName(vm.getHostName());
  
              if (vm.getPodIdToDeployIn() != null) {
                  HostPodVO pod = ApiDBUtils.findPodById(vm.getPodIdToDeployIn());
                  if (pod != null) {
                      vmResponse.setPodId(pod.getUuid());
                      vmResponse.setPodName(pod.getName());
                  }
              }
              VMTemplateVO template = ApiDBUtils.findTemplateById(vm.getTemplateId());
              if (template != null) {
                  vmResponse.setTemplateId(template.getUuid());
                  vmResponse.setTemplateName(template.getName());
                  vmResponse.setArch(template.getArch().getType());
              }
              vmResponse.setCreated(vm.getCreated());
              vmResponse.setHypervisor(vm.getHypervisorType().getHypervisorDisplayName());
  
              ServiceOffering serviceOffering = ApiDBUtils.findServiceOfferingById(vm.getServiceOfferingId());
              if (serviceOffering != null) {
                  vmResponse.setServiceOfferingId(serviceOffering.getUuid());
                  vmResponse.setServiceOfferingName(serviceOffering.getName());
              }
  
              if (vm.getHostId() != null) {
                  Host host = ApiDBUtils.findHostById(vm.getHostId());
                  if (host != null) {
                      vmResponse.setHostId(host.getUuid());
                      vmResponse.setHostName(host.getName());
                      vmResponse.setHostControlState(ControlState.getControlState(host.getStatus(), host.getResourceState()).toString());
                  }
              }
  
              if (VirtualMachine.systemVMs.contains(vm.getType())) {
                  Host systemVmHost = ApiDBUtils.findHostByTypeNameAndZoneId(vm.getDataCenterId(), vm.getHostName(),
                          Type.SecondaryStorageVm.equals(vm.getType()) ? Host.Type.SecondaryStorageVM : Host.Type.ConsoleProxy);
                  if (systemVmHost != null) {
                      vmResponse.setAgentState(systemVmHost.getStatus());
                      vmResponse.setDisconnectedOn(systemVmHost.getDisconnectedOn());
                      vmResponse.setVersion(systemVmHost.getVersion());
                  }
              }
  
              if (vm.getState() != null) {
                  vmResponse.setState(vm.getState().toString());
              }
  
              vmResponse.setDynamicallyScalable(vm.isDynamicallyScalable());
              // for console proxies, add the active sessions
              if (vm.getType() == Type.ConsoleProxy) {
                  ConsoleProxyVO proxy = ApiDBUtils.findConsoleProxy(vm.getId());
                  // proxy can be already destroyed
                  if (proxy != null) {
                      vmResponse.setActiveViewerSessions(proxy.getActiveSession());
                  }
              }
  
              DataCenter zone = ApiDBUtils.findZoneById(vm.getDataCenterId());
              if (zone != null) {
                  vmResponse.setZoneId(zone.getUuid());
                  vmResponse.setZoneName(zone.getName());
                  vmResponse.setDns1(zone.getDns1());
                  vmResponse.setDns2(zone.getDns2());
              }
  
              vmResponse.setHasAnnotation(annotationDao.hasAnnotations(vm.getUuid(), AnnotationService.EntityType.SYSTEM_VM.name(),
                      _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
              List<NicProfile> nicProfiles = ApiDBUtils.getNics(vm);
              for (NicProfile singleNicProfile : nicProfiles) {
                  Network network = ApiDBUtils.findNetworkById(singleNicProfile.getNetworkId());
                  if (network != null) {
                      if (network.getTrafficType() == TrafficType.Management) {
                          vmResponse.setPrivateIp(singleNicProfile.getIPv4Address());
                          vmResponse.setPrivateMacAddress(singleNicProfile.getMacAddress());
                          vmResponse.setPrivateNetmask(singleNicProfile.getIPv4Netmask());
                      } else if (network.getTrafficType() == TrafficType.Control) {
                          vmResponse.setLinkLocalIp(singleNicProfile.getIPv4Address());
                          vmResponse.setLinkLocalMacAddress(singleNicProfile.getMacAddress());
                          vmResponse.setLinkLocalNetmask(singleNicProfile.getIPv4Netmask());
                      } else if (network.getTrafficType() == TrafficType.Public) {
                          vmResponse.setPublicIp(singleNicProfile.getIPv4Address());
                          vmResponse.setPublicMacAddress(singleNicProfile.getMacAddress());
                          vmResponse.setPublicNetmask(singleNicProfile.getIPv4Netmask());
                          vmResponse.setGateway(singleNicProfile.getIPv4Gateway());
                      } else if (network.getTrafficType() == TrafficType.Guest) {
                          /*
                            * In basic zone, public ip has TrafficType.Guest in case EIP service is not enabled.
                            * When EIP service is enabled in the basic zone, system VM by default get the public
                            * IP allocated for EIP. So return the guest/public IP accordingly.
                            * */
                          NetworkOffering networkOffering = ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId());
                          if (networkOffering.isElasticIp()) {
                              IpAddress ip = ApiDBUtils.findIpByAssociatedVmId(vm.getId());
                              if (ip != null) {
                                  Vlan vlan = ApiDBUtils.findVlanById(ip.getVlanId());
                                  vmResponse.setPublicIp(ip.getAddress().addr());
                                  vmResponse.setPublicNetmask(vlan.getVlanNetmask());
                                  vmResponse.setGateway(vlan.getVlanGateway());
                              }
                          } else {
                              vmResponse.setPublicIp(singleNicProfile.getIPv4Address());
                              vmResponse.setPublicMacAddress(singleNicProfile.getMacAddress());
                              vmResponse.setPublicNetmask(singleNicProfile.getIPv4Netmask());
                              vmResponse.setGateway(singleNicProfile.getIPv4Gateway());
                          }
                      }
                  }
              }
          }
          vmResponse.setObjectName("systemvm");
          return vmResponse;
      }
  
      @Override
      public Host findHostById(Long hostId) {
          return ApiDBUtils.findHostById(hostId);
      }
  
      @Override
      public User findUserById(Long userId) {
          return ApiDBUtils.findUserById(userId);
      }
  
      @Override
      public UserVm findUserVmById(Long vmId) {
          return ApiDBUtils.findUserVmById(vmId);
  
      }
  
      @Override
      public VolumeVO findVolumeById(Long volumeId) {
          return ApiDBUtils.findVolumeById(volumeId);
      }
  
  
      @Override
      public Account findAccountByNameDomain(String accountName, Long domainId) {
          return ApiDBUtils.findAccountByNameDomain(accountName, domainId);
      }
  
      @Override
      public VirtualMachineTemplate findTemplateById(Long templateId) {
          return ApiDBUtils.findTemplateById(templateId);
      }
  
      @Override
      public DiskOfferingVO findDiskOfferingById(Long diskOfferingId) {
          return ApiDBUtils.findDiskOfferingById(diskOfferingId);
      }
  
      @Override
      public VpnUsersResponse createVpnUserResponse(VpnUser vpnUser) {
          VpnUsersResponse vpnResponse = new VpnUsersResponse();
          vpnResponse.setId(vpnUser.getUuid());
          vpnResponse.setUserName(vpnUser.getUsername());
          vpnResponse.setState(vpnUser.getState().toString());
  
          populateOwner(vpnResponse, vpnUser);
  
          vpnResponse.setObjectName("vpnuser");
          return vpnResponse;
      }
  
      @Override
      public RemoteAccessVpnResponse createRemoteAccessVpnResponse(RemoteAccessVpn vpn) {
          RemoteAccessVpnResponse vpnResponse = new RemoteAccessVpnResponse();
          IpAddress ip = ApiDBUtils.findIpAddressById(vpn.getServerAddressId());
          if (ip != null) {
              vpnResponse.setPublicIpId(ip.getUuid());
              vpnResponse.setPublicIp(ip.getAddress().addr());
          }
          vpnResponse.setIpRange(vpn.getIpRange());
          vpnResponse.setPresharedKey(vpn.getIpsecPresharedKey());
          populateOwner(vpnResponse, vpn);
          vpnResponse.setState(vpn.getState().toString());
          vpnResponse.setId(vpn.getUuid());
          vpnResponse.setForDisplay(vpn.isDisplay());
          vpnResponse.setObjectName("remoteaccessvpn");
  
          return vpnResponse;
      }
  
      @Override
      public TemplateResponse createTemplateUpdateResponse(ResponseView view, VirtualMachineTemplate result) {
          List<TemplateJoinVO> tvo = ApiDBUtils.newTemplateView(result);
          List<TemplateResponse> listVrs = ViewResponseHelper.createTemplateUpdateResponse(view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
          assert listVrs != null && listVrs.size() == 1 : "There should be one template returned";
          return listVrs.get(0);
      }
  
      @Override
      public List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachineTemplate result, Long zoneId, boolean readyOnly) {
          List<TemplateJoinVO> tvo = null;
          if (zoneId == null || zoneId == -1 || result.isCrossZones()) {
              tvo = ApiDBUtils.newTemplateView(result);
          } else {
              tvo = ApiDBUtils.newTemplateView(result, zoneId, readyOnly);
  
          }
          return ViewResponseHelper.createTemplateResponse(EnumSet.of(DomainDetails.all), view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
      }
  
      @Override
      public List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachineTemplate result,
                                                            List<Long> zoneIds, boolean readyOnly) {
          List<TemplateJoinVO> tvo = null;
          if (zoneIds == null) {
              return createTemplateResponses(view, result, (Long)null, readyOnly);
          } else {
              for (Long zoneId: zoneIds){
                  if (tvo == null)
                      tvo = ApiDBUtils.newTemplateView(result, zoneId, readyOnly);
                  else
                      tvo.addAll(ApiDBUtils.newTemplateView(result, zoneId, readyOnly));
              }
          }
          return ViewResponseHelper.createTemplateResponse(EnumSet.of(DomainDetails.all), view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
      }
  
      @Override
      public List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long zoneId, boolean readyOnly) {
          VirtualMachineTemplate template = findTemplateById(templateId);
          return createTemplateResponses(view, template, zoneId, readyOnly);
      }
  
      @Override
      public List<TemplateResponse> createIsoResponses(ResponseView view, VirtualMachineTemplate result, Long zoneId, boolean readyOnly) {
          List<TemplateJoinVO> tvo = null;
          if (zoneId == null || zoneId == -1) {
              tvo = ApiDBUtils.newTemplateView(result);
          } else {
              tvo = ApiDBUtils.newTemplateView(result, zoneId, readyOnly);
          }
  
          return ViewResponseHelper.createIsoResponse(view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
      }
  
      @Override
      public SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group) {
          List<SecurityGroupJoinVO> viewSgs = ApiDBUtils.newSecurityGroupView(group);
          List<SecurityGroupResponse> listSgs = ViewResponseHelper.createSecurityGroupResponses(viewSgs);
          assert listSgs != null && listSgs.size() == 1 : "There should be one security group returned";
          return listSgs.get(0);
      }
  
      private ExtractResponse createExtractResponse (Long zoneId, Long accountId, String url) {
          ExtractResponse response = new ExtractResponse();
          if (zoneId != null) {
              DataCenter zone = ApiDBUtils.findZoneById(zoneId);
              response.setZoneId(zone.getUuid());
              response.setZoneName(zone.getName());
          }
          response.setUrl(url);
          response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString());
          Account account = ApiDBUtils.findAccountById(accountId);
          response.setAccountId(account.getUuid());
          return response;
      }
  
      @Override
      public ExtractResponse createVolumeExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url) {
          ExtractResponse response = createExtractResponse(zoneId, accountId, url);
          response.setObjectName("volume");
          response.setMode(mode);
          Volume volume = ApiDBUtils.findVolumeById(id);
          response.setId(volume.getUuid());
          response.setName(volume.getName());
          return response;
      }
  
      @Override
      public ExtractResponse createSnapshotExtractResponse(Long id, Long zoneId, Long accountId, String url) {
          ExtractResponse response = createExtractResponse(zoneId, accountId, url);
          response.setObjectName("snapshot");
          Snapshot snapshot = ApiDBUtils.findSnapshotById(id);
          response.setId(snapshot.getUuid());
          response.setName(snapshot.getName());
          return response;
      }
  
      @Override
      public ExtractResponse createImageExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url) {
          ExtractResponse response = createExtractResponse(zoneId, accountId, url);
          response.setMode(mode);
          VMTemplateVO template = ApiDBUtils.findTemplateById(id);
          response.setId(template.getUuid());
          response.setName(template.getName());
          return response;
      }
  
      @Override
      public String toSerializedString(CreateCmdResponse response, String responseType) {
          return ApiResponseSerializer.toSerializedString(response, responseType);
      }
  
      @Override
      public List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long snapshotId, Long volumeId, boolean readyOnly) {
          Long zoneId = null;
  
          if (snapshotId != null) {
              Snapshot snapshot = ApiDBUtils.findSnapshotById(snapshotId);
              VolumeVO volume = findVolumeById(snapshot.getVolumeId());
  
              // it seems that the volume can actually be removed from the DB at some point if it's deleted
              // if volume comes back null, use another technique to try to discover the zone
              if (volume == null) {
                  SnapshotDataStoreVO snapshotStore = _snapshotStoreDao.findOneBySnapshotAndDatastoreRole(snapshot.getId(), DataStoreRole.Primary);
  
                  if (snapshotStore != null) {
                      long storagePoolId = snapshotStore.getDataStoreId();
  
                      StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
  
                      if (storagePool != null) {
                          zoneId = storagePool.getDataCenterId();
                      }
                  }
              }
              else {
                  zoneId = volume.getDataCenterId();
              }
          } else {
              VolumeVO volume = findVolumeById(volumeId);
  
              zoneId = volume.getDataCenterId();
          }
  
          if (zoneId == null) {
              throw new CloudRuntimeException("Unable to determine the zone ID");
          }
  
          return createTemplateResponses(view, templateId, zoneId, readyOnly);
      }
  
      @Override
      public List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long vmId) {
          UserVm vm = findUserVmById(vmId);
          Long hostId = (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId());
          Host host = findHostById(hostId);
          return createTemplateResponses(view, templateId, host.getDataCenterId(), true);
      }
  
      @Override
      public EventResponse createEventResponse(Event event) {
          EventJoinVO vEvent = ApiDBUtils.newEventView(event);
          return ApiDBUtils.newEventResponse(vEvent);
      }
  
      protected boolean capacityListingForSingleTag(List<? extends Capacity> capacities) {
          String tag = capacities.get(0).getTag();
          if (tag == null) {
              return false;
          }
          List<? extends Capacity> taggedCapacities = capacities.stream().filter(x -> tag.equals(x.getTag())).collect(Collectors.toList());
          return taggedCapacities.size() == capacities.size();
      }
  
      protected boolean capacityListingForSingleNonGpuType(List<? extends Capacity> capacities) {
          short type = capacities.get(0).getCapacityType();
          List<? extends Capacity> typeCapacities = capacities.stream().filter(x -> x.getCapacityType() == type).collect(Collectors.toList());
          return typeCapacities.size() == capacities.size();
      }
  
      @Override
      public List<CapacityResponse> createCapacityResponse(List<? extends Capacity> result, DecimalFormat format) {
          List<CapacityResponse> capacityResponses = new ArrayList<CapacityResponse>();
  
          for (Capacity summedCapacity : result) {
              if (summedCapacity.getTotalCapacity() == 0 &&
                      (summedCapacity.getCapacityType() == Capacity.CAPACITY_TYPE_BACKUP_STORAGE ||
                       summedCapacity.getCapacityType() == Capacity.CAPACITY_TYPE_OBJECT_STORAGE)) {
                  continue;
              }
              CapacityResponse capacityResponse = new CapacityResponse();
              capacityResponse.setCapacityTotal(summedCapacity.getTotalCapacity());
              if (summedCapacity.getAllocatedCapacity() != null) {
                  capacityResponse.setCapacityAllocated(summedCapacity.getAllocatedCapacity());
              }
              capacityResponse.setCapacityType(summedCapacity.getCapacityType());
              capacityResponse.setCapacityName(CapacityVO.getCapacityName(summedCapacity.getCapacityType()));
              capacityResponse.setCapacityUsed(summedCapacity.getUsedCapacity());
              if (summedCapacity.getPodId() != null) {
                  capacityResponse.setPodId(ApiDBUtils.findPodById(summedCapacity.getPodId()).getUuid());
                  HostPodVO pod = ApiDBUtils.findPodById(summedCapacity.getPodId());
                  if (pod != null) {
                      capacityResponse.setPodId(pod.getUuid());
                      capacityResponse.setPodName(pod.getName());
                  }
              }
              if (summedCapacity.getClusterId() != null) {
                  ClusterVO cluster = ApiDBUtils.findClusterById(summedCapacity.getClusterId());
                  if (cluster != null) {
                      capacityResponse.setClusterId(cluster.getUuid());
                      capacityResponse.setClusterName(cluster.getName());
                      if (summedCapacity.getPodId() == null) {
                          HostPodVO pod = ApiDBUtils.findPodById(cluster.getPodId());
                          capacityResponse.setPodId(pod.getUuid());
                          capacityResponse.setPodName(pod.getName());
                      }
                  }
              }
              DataCenter zone = ApiDBUtils.findZoneById(summedCapacity.getDataCenterId());
              if (zone != null) {
                  capacityResponse.setZoneId(zone.getUuid());
                  capacityResponse.setZoneName(zone.getName());
              }
              if (summedCapacity.getUsedPercentage() != null) {
                  capacityResponse.setPercentUsed(format.format(summedCapacity.getUsedPercentage() * 100f));
              } else if (summedCapacity.getTotalCapacity() != 0) {
                  capacityResponse.setPercentUsed(format.format((float)summedCapacity.getUsedCapacity() / (float)summedCapacity.getTotalCapacity() * 100f));
              } else {
                  capacityResponse.setPercentUsed(format.format(0L));
              }
              capacityResponse.setTag(summedCapacity.getTag());
  
              capacityResponse.setObjectName("capacity");
              capacityResponses.add(capacityResponse);
          }
  
          List<VgpuTypesInfo> gpuCapacities;
          if (result.size() > 1 &&
                  !capacityListingForSingleTag(result) &&
                  !capacityListingForSingleNonGpuType(result) &&
                  (gpuCapacities = ApiDBUtils.getGpuCapacites(result.get(0).getDataCenterId(),
                          result.get(0).getPodId(), result.get(0).getClusterId())) != null) {
              HashMap<String, Long> vgpuVMs = ApiDBUtils.getVgpuVmsCount(result.get(0).getDataCenterId(), result.get(0).getPodId(), result.get(0).getClusterId());
  
              long capacityUsed = 0;
              long capacityMax = 0;
              for (VgpuTypesInfo capacity : gpuCapacities) {
                  if (vgpuVMs.containsKey(capacity.getGroupName().concat(capacity.getModelName()))) {
                      capacityUsed += vgpuVMs.get(capacity.getGroupName().concat(capacity.getModelName()));
                  }
                  capacityMax += capacity.getMaxCapacity();
              }
  
              DataCenter zone = ApiDBUtils.findZoneById(result.get(0).getDataCenterId());
              CapacityResponse capacityResponse = new CapacityResponse();
              if (zone != null) {
                  capacityResponse.setZoneId(zone.getUuid());
                  capacityResponse.setZoneName(zone.getName());
              }
              if (result.get(0).getPodId() != null) {
                  HostPodVO pod = ApiDBUtils.findPodById(result.get(0).getPodId());
                  capacityResponse.setPodId(pod.getUuid());
                  capacityResponse.setPodName(pod.getName());
              }
              if (result.get(0).getClusterId() != null) {
                  ClusterVO cluster = ApiDBUtils.findClusterById(result.get(0).getClusterId());
                  capacityResponse.setClusterId(cluster.getUuid());
                  capacityResponse.setClusterName(cluster.getName());
              }
              capacityResponse.setCapacityType(Capacity.CAPACITY_TYPE_GPU);
              capacityResponse.setCapacityName(CapacityVO.getCapacityName(Capacity.CAPACITY_TYPE_GPU));
              capacityResponse.setCapacityUsed(capacityUsed);
              capacityResponse.setCapacityAllocated(capacityUsed);
              capacityResponse.setCapacityTotal(capacityMax);
              if (capacityMax > 0) {
                  capacityResponse.setPercentUsed(format.format((float)capacityUsed / capacityMax * 100f));
              } else {
                  capacityResponse.setPercentUsed(format.format(0));
              }
              capacityResponse.setObjectName("capacity");
              capacityResponses.add(capacityResponse);
          }
          return capacityResponses;
      }
  
      @Override
      public TemplatePermissionsResponse createTemplatePermissionsResponse(ResponseView view, List<String> accountNames, Long id) {
          Long templateOwnerDomain = null;
          VirtualMachineTemplate template = ApiDBUtils.findTemplateById(id);
          Account templateOwner = ApiDBUtils.findAccountById(template.getAccountId());
          if (view == ResponseView.Full) {
              // FIXME: we have just template id and need to get template owner
              // from that
              if (templateOwner != null) {
                  templateOwnerDomain = templateOwner.getDomainId();
              }
          }
  
          TemplatePermissionsResponse response = new TemplatePermissionsResponse();
          response.setId(template.getUuid());
          response.setPublicTemplate(template.isPublicTemplate());
          if ((view == ResponseView.Full) && (templateOwnerDomain != null)) {
              Domain domain = ApiDBUtils.findDomainById(templateOwnerDomain);
              if (domain != null) {
                  response.setDomainId(domain.getUuid());
              }
          }
  
          // Set accounts
          List<String> projectIds = new ArrayList<String>();
          List<String> regularAccounts = new ArrayList<String>();
          for (String accountName : accountNames) {
              Account account = ApiDBUtils.findAccountByNameDomain(accountName, templateOwner.getDomainId());
              if (account == null) {
                  logger.error("Missing Account " + accountName + " in domain " + templateOwner.getDomainId());
                  continue;
              }
  
              if (account.getType() != Account.Type.PROJECT) {
                  regularAccounts.add(accountName);
              } else {
                  // convert account to projectIds
                  Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
  
                  if (project.getUuid() != null && !project.getUuid().isEmpty()) {
                      projectIds.add(project.getUuid());
                  } else {
                      projectIds.add(String.valueOf(project.getId()));
                  }
              }
          }
  
          if (!projectIds.isEmpty()) {
              response.setProjectIds(projectIds);
          }
  
          if (!regularAccounts.isEmpty()) {
              response.setAccountNames(regularAccounts);
          }
  
          response.setObjectName("templatepermission");
          return response;
      }
  
      @Override
      public AsyncJobResponse queryJobResult(final QueryAsyncJobResultCmd cmd) {
          final Account caller = CallContext.current().getCallingAccount();
  
          final AsyncJob job = _entityMgr.findByIdIncludingRemoved(AsyncJob.class, cmd.getId());
          if (job == null) {
              throw new InvalidParameterValueException("Unable to find a job by id " + cmd.getId());
          }
  
          final User userJobOwner = _accountMgr.getUserIncludingRemoved(job.getUserId());
          final Account jobOwner = _accountMgr.getAccount(userJobOwner.getAccountId());
  
          //check permissions
          if (_accountMgr.isNormalUser(caller.getId())) {
              //regular users can see only jobs they own
              if (caller.getId() != jobOwner.getId()) {
                  throw new PermissionDeniedException("Account " + caller + " is not authorized to see job id=" + job.getId());
              }
          } else if (_accountMgr.isDomainAdmin(caller.getId())) {
              _accountMgr.checkAccess(caller, null, true, jobOwner);
          }
  
          return createAsyncJobResponse(_jobMgr.queryJob(cmd.getId(), true));
      }
  
      public AsyncJobResponse createAsyncJobResponse(AsyncJob job) {
          AsyncJobJoinVO vJob = ApiDBUtils.newAsyncJobView(job);
          return ApiDBUtils.newAsyncJobResponse(vJob);
      }
  
      @Override
      public SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List<? extends SecurityRule> securityRules) {
          SecurityGroupResponse response = new SecurityGroupResponse();
          Map<Long, Account> securiytGroupAccounts = new HashMap<Long, Account>();
  
          if ((securityRules != null) && !securityRules.isEmpty()) {
              SecurityGroupJoinVO securityGroup = ApiDBUtils.findSecurityGroupViewById(securityRules.get(0).getSecurityGroupId()).get(0);
              response.setId(securityGroup.getUuid());
              response.setName(securityGroup.getName());
              response.setDescription(securityGroup.getDescription());
  
              populateOwner(response, securityGroup);
  
              for (SecurityRule securityRule : securityRules) {
                  SecurityGroupRuleResponse securityGroupData = new SecurityGroupRuleResponse();
  
                  securityGroupData.setRuleId(securityRule.getUuid());
                  securityGroupData.setProtocol(securityRule.getProtocol());
                  if ("icmp".equalsIgnoreCase(securityRule.getProtocol())) {
                      securityGroupData.setIcmpType(securityRule.getStartPort());
                      securityGroupData.setIcmpCode(securityRule.getEndPort());
                  } else {
                      securityGroupData.setStartPort(securityRule.getStartPort());
                      securityGroupData.setEndPort(securityRule.getEndPort());
                  }
  
                  Long allowedSecurityGroupId = securityRule.getAllowedNetworkId();
                  if (allowedSecurityGroupId != null) {
                      List<SecurityGroupJoinVO> sgs = ApiDBUtils.findSecurityGroupViewById(allowedSecurityGroupId);
                      if (sgs != null && sgs.size() > 0) {
                          SecurityGroupJoinVO sg = sgs.get(0);
                          securityGroupData.setSecurityGroupName(sg.getName());
                          securityGroupData.setAccountName(sg.getAccountName());
                      }
                  } else {
                      securityGroupData.setCidr(securityRule.getAllowedSourceIpCidr());
                  }
                  if (securityRule.getRuleType() == SecurityRuleType.IngressRule) {
                      securityGroupData.setObjectName("ingressrule");
                      response.addSecurityGroupIngressRule(securityGroupData);
                  } else {
                      securityGroupData.setObjectName("egressrule");
                      response.addSecurityGroupEgressRule(securityGroupData);
                  }
  
              }
              response.setObjectName("securitygroup");
  
          }
          return response;
      }
  
      @Override
      public NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering) {
          if (!(offering instanceof NetworkOfferingJoinVO)) {
              offering = ApiDBUtils.newNetworkOfferingView(offering);
          }
          NetworkOfferingResponse response = ApiDBUtils.newNetworkOfferingResponse(offering);
          response.setNetworkRate(ApiDBUtils.getNetworkRate(offering.getId()));
          Long so = null;
          if (offering.getServiceOfferingId() != null) {
              so = offering.getServiceOfferingId();
          } else {
              so = ApiDBUtils.findDefaultRouterServiceOffering();
          }
          if (so != null) {
              ServiceOffering soffering = ApiDBUtils.findServiceOfferingById(so);
              if (soffering != null) {
                  response.setServiceOfferingId(soffering.getUuid());
              }
          }
          Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listNetworkOfferingServices(offering.getId());
          List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();
          for (Map.Entry<Service,Set<Provider>> entry : serviceProviderMap.entrySet()) {
              Service service = entry.getKey();
              Set<Provider> srvc_providers = entry.getValue();
              ServiceResponse svcRsp = new ServiceResponse();
              // skip gateway service
              if (service == Service.Gateway) {
                  continue;
              }
              svcRsp.setName(service.getName());
              List<ProviderResponse> providers = new ArrayList<ProviderResponse>();
              for (Provider provider : srvc_providers) {
                  if (provider != null) {
                      ProviderResponse providerRsp = new ProviderResponse();
                      providerRsp.setName(provider.getName());
                      providers.add(providerRsp);
                  }
              }
              svcRsp.setProviders(providers);
              if (Service.Lb == service) {
                  List<CapabilityResponse> lbCapResponse = new ArrayList<CapabilityResponse>();
  
                  CapabilityResponse lbIsoaltion = new CapabilityResponse();
                  lbIsoaltion.setName(Capability.SupportedLBIsolation.getName());
                  lbIsoaltion.setValue(offering.isDedicatedLB() ? "dedicated" : "shared");
                  lbCapResponse.add(lbIsoaltion);
  
                  CapabilityResponse eLb = new CapabilityResponse();
                  eLb.setName(Capability.ElasticLb.getName());
                  eLb.setValue(offering.isElasticLb() ? "true" : "false");
                  lbCapResponse.add(eLb);
  
                  CapabilityResponse inline = new CapabilityResponse();
                  inline.setName(Capability.InlineMode.getName());
                  inline.setValue(offering.isInline() ? "true" : "false");
                  lbCapResponse.add(inline);
  
                  CapabilityResponse vmAutoScaling = new CapabilityResponse();
                  vmAutoScaling.setName(Capability.VmAutoScaling.getName());
                  vmAutoScaling.setValue(offering.isSupportsVmAutoScaling() ? "true" : "false");
                  lbCapResponse.add(vmAutoScaling);
  
                  svcRsp.setCapabilities(lbCapResponse);
              } else if (Service.SourceNat == service) {
                  List<CapabilityResponse> capabilities = new ArrayList<CapabilityResponse>();
                  CapabilityResponse sharedSourceNat = new CapabilityResponse();
                  sharedSourceNat.setName(Capability.SupportedSourceNatTypes.getName());
                  sharedSourceNat.setValue(offering.isSharedSourceNat() ? "perzone" : "peraccount");
                  capabilities.add(sharedSourceNat);
  
                  CapabilityResponse redundantRouter = new CapabilityResponse();
                  redundantRouter.setName(Capability.RedundantRouter.getName());
                  redundantRouter.setValue(offering.isRedundantRouter() ? "true" : "false");
                  capabilities.add(redundantRouter);
  
                  svcRsp.setCapabilities(capabilities);
              } else if (service == Service.StaticNat) {
                  List<CapabilityResponse> staticNatCapResponse = new ArrayList<CapabilityResponse>();
  
                  CapabilityResponse eIp = new CapabilityResponse();
                  eIp.setName(Capability.ElasticIp.getName());
                  eIp.setValue(offering.isElasticIp() ? "true" : "false");
                  staticNatCapResponse.add(eIp);
  
                  CapabilityResponse associatePublicIp = new CapabilityResponse();
                  associatePublicIp.setName(Capability.AssociatePublicIP.getName());
                  associatePublicIp.setValue(offering.isAssociatePublicIP() ? "true" : "false");
                  staticNatCapResponse.add(associatePublicIp);
  
                  svcRsp.setCapabilities(staticNatCapResponse);
              }
              serviceResponses.add(svcRsp);
          }
          response.setForVpc(_configMgr.isOfferingForVpc(offering));
          response.setForTungsten(_ntwkModel.isProviderForNetworkOffering(Provider.Tungsten, offering.getId()));
          response.setForNsx(_ntwkModel.isProviderForNetworkOffering(Provider.Nsx, offering.getId()));
          if (offering.getNetworkMode() != null) {
              response.setNetworkMode(offering.getNetworkMode().name());
          }
          response.setServices(serviceResponses);
          //set network offering details
          Map<Detail, String> details = _ntwkModel.getNtwkOffDetails(offering.getId());
          if (details != null && !details.isEmpty()) {
              response.setDetails(details);
          }
          response.setHasAnnotation(annotationDao.hasAnnotations(offering.getUuid(), AnnotationService.EntityType.NETWORK_OFFERING.name(),
                  _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
          return response;
      }
  
      private void createCapabilityResponse(List<CapabilityResponse> capabilityResponses,
                                            String name,
                                            String value,
                                            boolean canChoose,
                                            String objectName) {
          CapabilityResponse capabilityResponse = new CapabilityResponse();
          capabilityResponse.setName(name);
          capabilityResponse.setValue(value);
          capabilityResponse.setCanChoose(canChoose);
          capabilityResponse.setObjectName(objectName);
  
          capabilityResponses.add(capabilityResponse);
      }
  
      private void createCapabilityResponse(List<CapabilityResponse> capabilityResponses,
                                            String name,
                                            String value,
                                            boolean canChoose) {
          createCapabilityResponse(capabilityResponses, name, value, canChoose, null);
      }
  
      @Override
      public NetworkResponse createNetworkResponse(ResponseView view, Network network) {
          // need to get network profile in order to retrieve dns information from
          // there
          NetworkProfile profile = ApiDBUtils.getNetworkProfile(network.getId());
          NetworkResponse response = new NetworkResponse();
          response.setId(network.getUuid());
          response.setName(network.getName());
          response.setDisplaytext(network.getDisplayText());
          if (network.getBroadcastDomainType() != null) {
              response.setBroadcastDomainType(network.getBroadcastDomainType().toString());
          }
  
          if (network.getTrafficType() != null) {
              response.setTrafficType(network.getTrafficType().name());
          }
  
          if (network.getGuestType() != null) {
              response.setType(network.getGuestType().toString());
          }
  
          response.setGateway(com.cloud.utils.StringUtils.getFirstValueFromCommaSeparatedString(network.getGateway()));
          String cidr = com.cloud.utils.StringUtils.getFirstValueFromCommaSeparatedString(network.getCidr());
  
          // FIXME - either set netmask or cidr
          response.setCidr(cidr);
          if (network.getNetworkCidr() != null) {
              response.setNetworkCidr((network.getNetworkCidr()));
          }
          // If network has reservation its entire network cidr is defined by
          // getNetworkCidr()
          // if no reservation is present then getCidr() will define the entire
          // network cidr
          if (network.getNetworkCidr() != null) {
              response.setNetmask(NetUtils.cidr2Netmask(network.getNetworkCidr()));
          }
          if ((cidr != null) && (network.getNetworkCidr() == null)) {
              response.setNetmask(NetUtils.cidr2Netmask(cidr));
          }
  
          response.setIp6Gateway(com.cloud.utils.StringUtils.getFirstValueFromCommaSeparatedString(network.getIp6Gateway()));
          response.setIp6Cidr(com.cloud.utils.StringUtils.getFirstValueFromCommaSeparatedString(network.getIp6Cidr()));
  
          // create response for reserved IP ranges that can be used for
          // non-cloudstack purposes
          String reservation = null;
          if ((cidr != null) && (NetUtils.isNetworkAWithinNetworkB(cidr, network.getNetworkCidr()))) {
              String[] guestVmCidrPair = cidr.split("\\/");
              String[] guestCidrPair = network.getNetworkCidr().split("\\/");
  
              Long guestVmCidrSize = Long.valueOf(guestVmCidrPair[1]);
              Long guestCidrSize = Long.valueOf(guestCidrPair[1]);
  
              String[] guestVmIpRange = NetUtils.getIpRangeFromCidr(guestVmCidrPair[0], guestVmCidrSize);
              String[] guestIpRange = NetUtils.getIpRangeFromCidr(guestCidrPair[0], guestCidrSize);
              long startGuestIp = NetUtils.ip2Long(guestIpRange[0]);
              long endGuestIp = NetUtils.ip2Long(guestIpRange[1]);
              long startVmIp = NetUtils.ip2Long(guestVmIpRange[0]);
              long endVmIp = NetUtils.ip2Long(guestVmIpRange[1]);
  
              if (startVmIp == startGuestIp && endVmIp < endGuestIp - 1) {
                  reservation = (NetUtils.long2Ip(endVmIp + 1) + "-" + NetUtils.long2Ip(endGuestIp));
              }
              if (endVmIp == endGuestIp && startVmIp > startGuestIp + 1) {
                  reservation = (NetUtils.long2Ip(startGuestIp) + "-" + NetUtils.long2Ip(startVmIp - 1));
              }
              if (startVmIp > startGuestIp + 1 && endVmIp < endGuestIp - 1) {
                  reservation = (NetUtils.long2Ip(startGuestIp) + "-" + NetUtils.long2Ip(startVmIp - 1) + " ,  " + NetUtils.long2Ip(endVmIp + 1) + "-" + NetUtils.long2Ip(endGuestIp));
              }
          }
          response.setReservedIpRange(reservation);
          // return vlan information only to Root admin
          if (network.getBroadcastUri() != null && view == ResponseView.Full) {
              String broadcastUri = network.getBroadcastUri().toString();
              response.setBroadcastUri(broadcastUri);
              String vlan = "N/A";
              switch (BroadcastDomainType.getSchemeValue(network.getBroadcastUri())) {
              case Vlan:
              case Vxlan:
                  vlan = BroadcastDomainType.getValue(network.getBroadcastUri());
                  break;
              }
              // return vlan information only to Root admin
              response.setVlan(vlan);
          }
  
          // return network details only to Root admin
          if (view == ResponseView.Full) {
              Map<String, String> details = new HashMap<>();
              for (NetworkDetailVO detail: networkDetailsDao.listDetails(network.getId())) {
                  details.put(detail.getName(),detail.getValue());
              }
              response.setDetails(details);
          }
  
          DataCenter zone = ApiDBUtils.findZoneById(network.getDataCenterId());
          if (zone != null) {
              response.setZoneId(zone.getUuid());
              response.setZoneName(zone.getName());
          }
          if (network.getPhysicalNetworkId() != null) {
              PhysicalNetworkVO pnet = ApiDBUtils.findPhysicalNetworkById(network.getPhysicalNetworkId());
              response.setPhysicalNetworkId(pnet.getUuid());
          }
  
          // populate network offering information
          NetworkOffering networkOffering = ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId());
          if (networkOffering != null) {
              response.setNetworkOfferingId(networkOffering.getUuid());
              response.setNetworkOfferingName(networkOffering.getName());
              response.setNetworkOfferingDisplayText(networkOffering.getDisplayText());
              response.setNetworkOfferingConserveMode(networkOffering.isConserveMode());
              response.setIsSystem(networkOffering.isSystemOnly());
              response.setNetworkOfferingAvailability(networkOffering.getAvailability().toString());
              response.setIsPersistent(networkOffering.isPersistent());
              response.setSpecifyVlan(networkOffering.isSpecifyVlan());
              if (Network.GuestType.Isolated.equals(network.getGuestType()) && network.getVpcId() == null) {
                  response.setEgressDefaultPolicy(networkOffering.isEgressDefaultPolicy());
              }
              ASNumberVO asNumberVO = networkOffering.isForVpc() ?
                      asNumberDao.findByZoneAndVpcId(network.getDataCenterId(), network.getVpcId()) :
                      asNumberDao.findByZoneAndNetworkId(network.getDataCenterId(), network.getId());
              if (Objects.nonNull(asNumberVO)) {
                  response.setAsNumberId(asNumberVO.getUuid());
                  response.setAsNumber(asNumberVO.getAsNumber());
              }
          }
  
          if (network.getAclType() != null) {
              response.setAclType(network.getAclType().toString());
          }
          response.setDisplayNetwork(network.getDisplayNetwork());
          response.setState(network.getState().toString());
          response.setRestartRequired(network.isRestartRequired());
          NetworkVO nw = ApiDBUtils.findNetworkById(network.getRelated());
          if (nw != null) {
              response.setRelated(nw.getUuid());
          }
          response.setNetworkDomain(network.getNetworkDomain());
          response.setPublicMtu(network.getPublicMtu());
          response.setPrivateMtu(network.getPrivateMtu());
          response.setDns1(profile.getDns1());
          response.setDns2(profile.getDns2());
          response.setIpv6Dns1(profile.getIp6Dns1());
          response.setIpv6Dns2(profile.getIp6Dns2());
          // populate capability
          Map<Service, Map<Capability, String>> serviceCapabilitiesMap = ApiDBUtils.getNetworkCapabilities(network.getId(), network.getDataCenterId());
          Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listNetworkOfferingServices(network.getNetworkOfferingId());
          List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();
          if (serviceCapabilitiesMap != null) {
              for (Map.Entry<Service, Map<Capability, String>>entry : serviceCapabilitiesMap.entrySet()) {
                  Service service = entry.getKey();
                  ServiceResponse serviceResponse = new ServiceResponse();
                  // skip gateway service
                  if (service == Service.Gateway) {
                      continue;
                  }
                  serviceResponse.setName(service.getName());
  
                  // set list of capabilities for the service
                  List<CapabilityResponse> capabilityResponses = new ArrayList<>();
                  Map<Capability, String> serviceCapabilities = entry.getValue();
                  if (serviceCapabilities != null) {
                      for (Map.Entry<Capability,String> ser_cap_entries : serviceCapabilities.entrySet()) {
                          Capability capability = ser_cap_entries.getKey();
                          String capabilityValue = ser_cap_entries.getValue();
                          if (Service.Lb == service && capability.getName().equals(Capability.SupportedLBIsolation.getName())) {
                               capabilityValue = networkOffering.isDedicatedLB() ? "dedicated" : "shared";
                          }
  
                          Set<String> capabilitySet = new HashSet<>(Arrays.asList(Capability.SupportedLBIsolation.getName(),
                                  Capability.SupportedSourceNatTypes.getName(),
                                  Capability.RedundantRouter.getName()));
                          boolean canChoose = capabilitySet.contains(capability.getName());
  
                          createCapabilityResponse(capabilityResponses, capability.getName(),
                                  capabilityValue, canChoose, "capability");
                      }
                  }
  
                  if (Service.SourceNat == service) {
                      // overwrite
                      capabilityResponses = new ArrayList<>();
                      createCapabilityResponse(capabilityResponses, Capability.SupportedSourceNatTypes.getName(),
                              networkOffering.isSharedSourceNat() ? "perzone" : "peraccount", true);
  
                      createCapabilityResponse(capabilityResponses, Capability.RedundantRouter.getName(),
                              networkOffering.isRedundantRouter() ? "true" : "false", true);
                  } else if (service == Service.StaticNat) {
                      createCapabilityResponse(capabilityResponses, Capability.ElasticIp.getName(),
                              networkOffering.isElasticIp() ? "true" : "false", false);
  
                      createCapabilityResponse(capabilityResponses, Capability.AssociatePublicIP.getName(),
                              networkOffering.isAssociatePublicIP() ? "true" : "false", false);
                  } else if (Service.Lb == service) {
                      createCapabilityResponse(capabilityResponses, Capability.ElasticLb.getName(),
                              networkOffering.isElasticLb() ? "true" : "false", false);
  
                      createCapabilityResponse(capabilityResponses, Capability.InlineMode.getName(),
                              networkOffering.isInline() ? "true" : "false", false);
                  }
                  serviceResponse.setCapabilities(capabilityResponses);
  
                  List<ProviderResponse> providers = new ArrayList<>();
                  for (Provider provider : serviceProviderMap.get(service)) {
                      if (provider != null) {
                          ProviderResponse providerRsp = new ProviderResponse();
                          providerRsp.setName(provider.getName());
                          providers.add(providerRsp);
                      }
                  }
                  serviceResponse.setProviders(providers);
  
                  serviceResponse.setObjectName("service");
                  serviceResponses.add(serviceResponse);
              }
          }
          response.setServices(serviceResponses);
  
          if (network.getAclType() == null || network.getAclType() == ACLType.Account) {
              populateOwner(response, network);
          } else {
              // get domain from network_domain table
              Pair<Long, Boolean> domainNetworkDetails = ApiDBUtils.getDomainNetworkDetails(network.getId());
              if (domainNetworkDetails.first() != null) {
                  populateDomain(response, domainNetworkDetails.first());
              }
              response.setSubdomainAccess(domainNetworkDetails.second());
          }
  
          Long dedicatedDomainId = ApiDBUtils.getDedicatedNetworkDomain(network.getId());
          if (dedicatedDomainId != null) {
              populateDomain(response, dedicatedDomainId);
          }
  
          response.setSpecifyIpRanges(network.getSpecifyIpRanges());
  
          setVpcIdInResponse(network.getVpcId(), response::setVpcId, response::setVpcName);
  
          setResponseAssociatedNetworkInformation(response, network.getId());
  
          response.setCanUseForDeploy(ApiDBUtils.canUseForDeploy(network));
  
          // set tag information
          List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.Network, network.getId());
          List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
          for (ResourceTag tag : tags) {
              ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
              CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
          }
          response.setTags(tagResponses);
          response.setHasAnnotation(annotationDao.hasAnnotations(network.getUuid(), AnnotationService.EntityType.NETWORK.name(),
                  _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
  
          if (network.getNetworkACLId() != null) {
              NetworkACL acl = ApiDBUtils.findByNetworkACLId(network.getNetworkACLId());
              if (acl != null) {
                  response.setAclId(acl.getUuid());
                  response.setAclName(acl.getName());
              }
          }
  
          response.setStrechedL2Subnet(network.isStrechedL2Network());
          if (network.isStrechedL2Network()) {
              Set<String> networkSpannedZones = new  HashSet<String>();
              List<VMInstanceVO> vmInstances = new ArrayList<VMInstanceVO>();
              vmInstances.addAll(ApiDBUtils.listUserVMsByNetworkId(network.getId()));
              vmInstances.addAll(ApiDBUtils.listDomainRoutersByNetworkId(network.getId()));
              for (VirtualMachine vm : vmInstances) {
                  DataCenter vmZone = ApiDBUtils.findZoneById(vm.getDataCenterId());
                  networkSpannedZones.add(vmZone.getUuid());
              }
              response.setNetworkSpannedZones(networkSpannedZones);
          }
          response.setExternalId(network.getExternalId());
          response.setRedundantRouter(network.isRedundant());
          response.setCreated(network.getCreated());
          response.setSupportsVmAutoScaling(networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId()).isSupportsVmAutoScaling());
  
          Long bytesReceived = 0L;
          Long bytesSent = 0L;
          SearchBuilder<UserStatisticsVO> sb = userStatsDao.createSearchBuilder();
          sb.and("networkId", sb.entity().getNetworkId(), Op.EQ);
          SearchCriteria<UserStatisticsVO> sc = sb.create();
          sc.setParameters("networkId", network.getId());
          for (UserStatisticsVO stat: userStatsDao.search(sc, null)) {
              bytesReceived += stat.getNetBytesReceived() + stat.getCurrentBytesReceived();
              bytesSent += stat.getNetBytesSent() + stat.getCurrentBytesSent();
          }
          response.setBytesReceived(bytesReceived);
          response.setBytesSent(bytesSent);
  
          if (networkOfferingDao.isRoutedNetwork(network.getNetworkOfferingId())) {
              if (routedIpv4Manager.isDynamicRoutedNetwork(network)) {
                  response.setIpv4Routing(Network.Routing.Dynamic.name());
              } else {
                  response.setIpv4Routing(Network.Routing.Static.name());
              }
              response.setIpv4Routes(new LinkedHashSet<>());
              List<IPAddressVO> ips = network.getVpcId() != null ? userIpAddressDao.listByAssociatedVpc(network.getVpcId(), true):
                      userIpAddressDao.listByAssociatedNetwork(network.getId(), true);
              for (IpAddress ip : ips) {
                  Ipv4RouteResponse route = new Ipv4RouteResponse(network.getCidr(), ip.getAddress().addr());
                  response.addIpv4Route(route);
              }
  
              if (view == ResponseView.Full) {
                  List<BgpPeerVO> bgpPeerVOS = bgpPeerDao.listNonRevokeByNetworkId(network.getId());
                  for (BgpPeerVO bgpPeerVO : bgpPeerVOS) {
                      BgpPeerResponse bgpPeerResponse = routedIpv4Manager.createBgpPeerResponse(bgpPeerVO);
                      response.addBgpPeer(bgpPeerResponse);
                  }
              }
          }
  
          if (networkOfferingDao.isIpv6Supported(network.getNetworkOfferingId())) {
              response.setInternetProtocol(networkOfferingDao.getNetworkOfferingInternetProtocol(network.getNetworkOfferingId(), NetUtils.InternetProtocol.IPv4).toString());
              response.setIpv6Routing(Network.Routing.Static.toString());
              response.setIpv6Routes(new LinkedHashSet<>());
              if (Network.GuestType.Isolated.equals(networkOffering.getGuestType())) {
                  List<String> ipv6Addresses = ipv6Service.getPublicIpv6AddressesForNetwork(network);
                  for (String address : ipv6Addresses) {
                      Ipv6RouteResponse route = new Ipv6RouteResponse(network.getIp6Cidr(), address);
                      response.addIpv6Route(route);
                  }
              }
          }
  
          response.setObjectName("network");
          return response;
      }
  
      private void setResponseAssociatedNetworkInformation(BaseResponseWithAssociatedNetwork response, Long networkId) {
          final NetworkDetailVO detail = networkDetailsDao.findDetail(networkId, Network.AssociatedNetworkId);
          if (detail != null) {
              Long associatedNetworkId = Long.valueOf(detail.getValue());
              NetworkVO associatedNetwork = ApiDBUtils.findNetworkById(associatedNetworkId);
              if (associatedNetwork != null) {
                  response.setAssociatedNetworkId(associatedNetwork.getUuid());
                  response.setAssociatedNetworkName(associatedNetwork.getName());
              }
          }
      }
  
      @Override
      public Long getSecurityGroupId(String groupName, long accountId) {
          SecurityGroup sg = ApiDBUtils.getSecurityGroup(groupName, accountId);
          if (sg == null) {
              return null;
          } else {
              return sg.getId();
          }
      }
  
      @Override
      public ProjectResponse createProjectResponse(Project project) {
          List<ProjectJoinVO> viewPrjs = ApiDBUtils.newProjectView(project);
          List<ProjectResponse> listPrjs = ViewResponseHelper.createProjectResponse(EnumSet.of(DomainDetails.all), viewPrjs.toArray(new ProjectJoinVO[viewPrjs.size()]));
          assert listPrjs != null && listPrjs.size() == 1 : "There should be one project  returned";
          return listPrjs.get(0);
      }
  
      @Override
      public FirewallResponse createFirewallResponse(FirewallRule fwRule) {
          FirewallResponse response = new FirewallResponse();
  
          response.setId(fwRule.getUuid());
          response.setProtocol(fwRule.getProtocol());
          if (fwRule.getSourcePortStart() != null) {
              response.setStartPort(fwRule.getSourcePortStart());
          }
  
          if (fwRule.getSourcePortEnd() != null) {
              response.setEndPort(fwRule.getSourcePortEnd());
          }
  
          List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId());
          response.setCidrList(StringUtils.join(cidrs, ","));
  
          List<String> destCidrs = ApiDBUtils.findFirewallDestCidrs(fwRule.getId());
          response.setDestCidr(StringUtils.join(destCidrs,","));
  
          if (fwRule.getTrafficType() == FirewallRule.TrafficType.Ingress) {
              if (fwRule.getSourceIpAddressId() != null) {
                  IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
                  response.setPublicIpAddressId(ip.getUuid());
                  response.setPublicIpAddress(ip.getAddress().addr());
              }
          }
  
          Network network = ApiDBUtils.findNetworkById(fwRule.getNetworkId());
          response.setNetworkId(network.getUuid());
  
          FirewallRule.State state = fwRule.getState();
          String stateToSet = state.toString();
          if (state.equals(FirewallRule.State.Revoke)) {
              stateToSet = "Deleting";
          }
  
          response.setIcmpCode(fwRule.getIcmpCode());
          response.setIcmpType(fwRule.getIcmpType());
          response.setForDisplay(fwRule.isDisplay());
          response.setTrafficType(fwRule.getTrafficType().toString());
  
          // set tag information
          List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.FirewallRule, fwRule.getId());
          List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
          for (ResourceTag tag : tags) {
              ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
              CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
          }
          response.setTags(tagResponses);
  
          response.setState(stateToSet);
          response.setObjectName("firewallrule");
          return response;
      }
  
      @Override
      public NetworkACLItemResponse createNetworkACLItemResponse(NetworkACLItem aclItem) {
          NetworkACLItemResponse response = new NetworkACLItemResponse();
  
          response.setId(aclItem.getUuid());
          response.setProtocol(aclItem.getProtocol());
          if (aclItem.getSourcePortStart() != null) {
              response.setStartPort(Integer.toString(aclItem.getSourcePortStart()));
          }
  
          if (aclItem.getSourcePortEnd() != null) {
              response.setEndPort(Integer.toString(aclItem.getSourcePortEnd()));
          }
  
          response.setCidrList(StringUtils.join(aclItem.getSourceCidrList(), ","));
  
          response.setTrafficType(aclItem.getTrafficType().toString());
  
          NetworkACLItem.State state = aclItem.getState();
          String stateToSet = state.toString();
          if (state.equals(NetworkACLItem.State.Revoke)) {
              stateToSet = "Deleting";
          }
  
          response.setIcmpCode(aclItem.getIcmpCode());
          response.setIcmpType(aclItem.getIcmpType());
  
          response.setState(stateToSet);
          response.setNumber(aclItem.getNumber());
          response.setAction(aclItem.getAction().toString());
          response.setForDisplay(aclItem.isDisplay());
  
          NetworkACL acl = ApiDBUtils.findByNetworkACLId(aclItem.getAclId());
          if (acl != null) {
              response.setAclId(acl.getUuid());
              response.setAclName(acl.getName());
          }
  
          //set tag information
          List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.NetworkACL, aclItem.getId());
          List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
          for (ResourceTag tag : tags) {
              ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
              CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
          }
          response.setTags(tagResponses);
          response.setReason(aclItem.getReason());
          response.setObjectName("networkacl");
          return response;
      }
  
      @Override
      public HypervisorCapabilitiesResponse createHypervisorCapabilitiesResponse(HypervisorCapabilities hpvCapabilities) {
          HypervisorCapabilitiesResponse hpvCapabilitiesResponse = new HypervisorCapabilitiesResponse();
          hpvCapabilitiesResponse.setId(hpvCapabilities.getUuid());
          hpvCapabilitiesResponse.setHypervisor(hpvCapabilities.getHypervisorType().getHypervisorDisplayName());
          hpvCapabilitiesResponse.setHypervisorVersion(hpvCapabilities.getHypervisorVersion());
          hpvCapabilitiesResponse.setIsSecurityGroupEnabled(hpvCapabilities.isSecurityGroupEnabled());
          hpvCapabilitiesResponse.setMaxGuestsLimit(hpvCapabilities.getMaxGuestsLimit());
          hpvCapabilitiesResponse.setMaxDataVolumesLimit(hpvCapabilities.getMaxDataVolumesLimit());
          hpvCapabilitiesResponse.setMaxHostsPerCluster(hpvCapabilities.getMaxHostsPerCluster());
          hpvCapabilitiesResponse.setIsStorageMotionSupported(hpvCapabilities.isStorageMotionSupported());
          hpvCapabilitiesResponse.setVmSnapshotEnabled(hpvCapabilities.isVmSnapshotEnabled());
          return hpvCapabilitiesResponse;
      }
  
      // TODO: we may need to refactor once ControlledEntityResponse and
      // ControlledEntity id to uuid conversion are all done.
      // currently code is scattered in
      private void populateOwner(ControlledEntityResponse response, ControlledEntity object) {
          Account account = ApiDBUtils.findAccountById(object.getAccountId());
  
          if (account.getType() == Account.Type.PROJECT) {
              // find the project
              Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
              response.setProjectId(project.getUuid());
              response.setProjectName(project.getName());
          } else {
              response.setAccountName(account.getAccountName());
          }
          populateDomain(response, object.getDomainId());
      }
  
      public static void populateOwner(ControlledViewEntityResponse response, ControlledEntity object) {
          Account account = ApiDBUtils.findAccountById(object.getAccountId());
  
          if (account.getType() == Account.Type.PROJECT) {
              // find the project
              Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
              response.setProjectId(project.getUuid());
              response.setProjectName(project.getName());
          } else {
              response.setAccountName(account.getAccountName());
          }
  
          populateDomain(response, object.getDomainId());
      }
  
      public static void populateOwner(ControlledViewEntityResponse response, ControlledViewEntity object) {
  
          if (object.getAccountType() == Account.Type.PROJECT) {
              response.setProjectId(object.getProjectUuid());
              response.setProjectName(object.getProjectName());
          } else {
              response.setAccountName(object.getAccountName());
          }
  
          response.setDomainId(object.getDomainUuid());
          response.setDomainName(object.getDomainName());
          response.setDomainPath(getPrettyDomainPath(object.getDomainPath()));
      }
  
      private void populateAccount(ControlledEntityResponse response, long accountId) {
          Account account = ApiDBUtils.findAccountById(accountId);
          if (account == null) {
              logger.debug("Unable to find account with id: " + accountId);
          } else if (account.getType() == Account.Type.PROJECT) {
              // find the project
              Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
              if (project != null) {
                  response.setProjectId(project.getUuid());
                  response.setProjectName(project.getName());
                  response.setAccountName(account.getAccountName());
              } else {
                  logger.debug("Unable to find project with id: " + account.getId());
              }
          } else {
              response.setAccountName(account.getAccountName());
          }
      }
  
      private void populateDomain(ControlledEntityResponse response, long domainId) {
          Domain domain = ApiDBUtils.findDomainById(domainId);
          if (domain == null) {
              return;
          }
          response.setDomainId(domain.getUuid());
          response.setDomainName(domain.getName());
          response.setDomainPath(getPrettyDomainPath(domain.getPath()));
      }
  
      private static void populateDomain(ControlledViewEntityResponse response, long domainId) {
          Domain domain = ApiDBUtils.findDomainById(domainId);
          if (domain == null) {
              return;
          }
          response.setDomainId(domain.getUuid());
          response.setDomainName(domain.getName());
          response.setDomainPath(getPrettyDomainPath(domain.getPath()));
      }
  
      @Override
      public ProjectAccountResponse createProjectAccountResponse(ProjectAccount projectAccount) {
          ProjectAccountJoinVO vProj = ApiDBUtils.newProjectAccountView(projectAccount);
          List<ProjectAccountResponse> listProjs = ViewResponseHelper.createProjectAccountResponse(vProj);
          assert listProjs != null && listProjs.size() == 1 : "There should be one project account returned";
          return listProjs.get(0);
      }
  
      @Override
      public ProjectInvitationResponse createProjectInvitationResponse(ProjectInvitation invite) {
          ProjectInvitationJoinVO vInvite = ApiDBUtils.newProjectInvitationView(invite);
          return ApiDBUtils.newProjectInvitationResponse(vInvite);
      }
  
      @Override
      public SystemVmInstanceResponse createSystemVmInstanceResponse(VirtualMachine vm) {
          SystemVmInstanceResponse vmResponse = new SystemVmInstanceResponse();
          vmResponse.setId(vm.getUuid());
          vmResponse.setSystemVmType(vm.getType().toString().toLowerCase());
          vmResponse.setName(vm.getHostName());
          if (vm.getHostId() != null) {
              Host host = ApiDBUtils.findHostById(vm.getHostId());
              if (host != null) {
                  vmResponse.setHostId(host.getUuid());
              }
          }
          if (vm.getState() != null) {
              vmResponse.setState(vm.getState().toString());
          }
          if (vm.getType() == Type.DomainRouter) {
              VirtualRouter router = (VirtualRouter)vm;
              if (router.getRole() != null) {
                  vmResponse.setRole(router.getRole().toString());
              }
          }
          vmResponse.setObjectName("systemvminstance");
          return vmResponse;
      }
  
      @Override
      public PhysicalNetworkResponse createPhysicalNetworkResponse(PhysicalNetwork result) {
          PhysicalNetworkResponse response = new PhysicalNetworkResponse();
  
          DataCenter zone = ApiDBUtils.findZoneById(result.getDataCenterId());
          if (zone != null) {
              response.setZoneId(zone.getUuid());
              response.setZoneName(zone.getName());
          }
          response.setNetworkSpeed(result.getSpeed());
          response.setVlan(result.getVnetString());
          if (result.getDomainId() != null) {
              Domain domain = ApiDBUtils.findDomainById(result.getDomainId());
              if (domain != null) {
                  response.setDomainId(domain.getUuid());
              }
          }
          response.setId(result.getUuid());
          if (result.getBroadcastDomainRange() != null) {
              response.setBroadcastDomainRange(result.getBroadcastDomainRange().toString());
          }
          response.setIsolationMethods(result.getIsolationMethods());
          response.setTags(result.getTags());
          if (result.getState() != null) {
              response.setState(result.getState().toString());
          }
  
          response.setName(result.getName());
  
          response.setObjectName("physicalnetwork");
          return response;
      }
  
      @Override
      public GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlanRange vlan) {
          GuestVlanRangeResponse guestVlanRangeResponse = new GuestVlanRangeResponse();
  
          guestVlanRangeResponse.setId(vlan.getUuid());
          Long accountId = ApiDBUtils.getAccountIdForGuestVlan(vlan.getId());
          Account owner = ApiDBUtils.findAccountById(accountId);
          if (owner != null) {
              populateAccount(guestVlanRangeResponse, owner.getId());
              populateDomain(guestVlanRangeResponse, owner.getDomainId());
          }
          guestVlanRangeResponse.setGuestVlanRange(vlan.getGuestVlanRange());
          guestVlanRangeResponse.setPhysicalNetworkId(vlan.getPhysicalNetworkId());
          PhysicalNetworkVO physicalNetwork = ApiDBUtils.findPhysicalNetworkById(vlan.getPhysicalNetworkId());
          guestVlanRangeResponse.setZoneId(physicalNetwork.getDataCenterId());
  
          return guestVlanRangeResponse;
      }
  
      @Override
      public ServiceResponse createNetworkServiceResponse(Service service) {
          ServiceResponse response = new ServiceResponse();
          response.setName(service.getName());
  
          // set list of capabilities required for the service
          List<CapabilityResponse> capabilityResponses = new ArrayList<CapabilityResponse>();
          Capability[] capabilities = service.getCapabilities();
          for (Capability cap : capabilities) {
              CapabilityResponse capabilityResponse = new CapabilityResponse();
              capabilityResponse.setName(cap.getName());
              capabilityResponse.setObjectName("capability");
              if (cap.getName().equals(Capability.SupportedLBIsolation.getName()) || cap.getName().equals(Capability.SupportedSourceNatTypes.getName())
                      || cap.getName().equals(Capability.RedundantRouter.getName())) {
                  capabilityResponse.setCanChoose(true);
              } else {
                  capabilityResponse.setCanChoose(false);
              }
              capabilityResponses.add(capabilityResponse);
          }
          response.setCapabilities(capabilityResponses);
  
          // set list of providers providing this service
          List<? extends Network.Provider> serviceProviders = ApiDBUtils.getProvidersForService(service);
          List<ProviderResponse> serviceProvidersResponses = new ArrayList<ProviderResponse>();
          for (Network.Provider serviceProvider : serviceProviders) {
              ProviderResponse serviceProviderResponse = createServiceProviderResponse(serviceProvider);
              serviceProvidersResponses.add(serviceProviderResponse);
          }
          response.setProviders(serviceProvidersResponses);
  
          response.setObjectName("networkservice");
          return response;
  
      }
  
      private ProviderResponse createServiceProviderResponse(Provider serviceProvider) {
          ProviderResponse response = new ProviderResponse();
          response.setName(serviceProvider.getName());
          boolean canEnableIndividualServices = ApiDBUtils.canElementEnableIndividualServices(serviceProvider);
          response.setCanEnableIndividualServices(canEnableIndividualServices);
          return response;
      }
  
      @Override
      public ProviderResponse createNetworkServiceProviderResponse(PhysicalNetworkServiceProvider result) {
          ProviderResponse response = new ProviderResponse();
          response.setId(result.getUuid());
          response.setName(result.getProviderName());
          PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(result.getPhysicalNetworkId());
          if (pnw != null) {
              response.setPhysicalNetworkId(pnw.getUuid());
          }
          PhysicalNetwork dnw = ApiDBUtils.findPhysicalNetworkById(result.getDestinationPhysicalNetworkId());
          if (dnw != null) {
              response.setDestinationPhysicalNetworkId(dnw.getUuid());
          }
          response.setState(result.getState().toString());
  
          // set enabled services
          List<String> services = new ArrayList<String>();
          for (Service service : result.getEnabledServices()) {
              services.add(service.getName());
          }
          response.setServices(services);
  
          Provider serviceProvider = Provider.getProvider(result.getProviderName());
          boolean canEnableIndividualServices = ApiDBUtils.canElementEnableIndividualServices(serviceProvider);
          response.setCanEnableIndividualServices(canEnableIndividualServices);
  
          response.setObjectName("networkserviceprovider");
          return response;
      }
  
      @Override
      public TrafficTypeResponse createTrafficTypeResponse(PhysicalNetworkTrafficType result) {
          TrafficTypeResponse response = new TrafficTypeResponse();
          response.setId(result.getUuid());
          PhysicalNetwork pnet = ApiDBUtils.findPhysicalNetworkById(result.getPhysicalNetworkId());
          if (pnet != null) {
              response.setPhysicalNetworkId(pnet.getUuid());
          }
          if (result.getTrafficType() != null) {
              response.setTrafficType(result.getTrafficType().toString());
          }
  
          response.setXenLabel(result.getXenNetworkLabel());
          response.setKvmLabel(result.getKvmNetworkLabel());
          response.setVmwareLabel(result.getVmwareNetworkLabel());
          response.setHypervLabel(result.getHypervNetworkLabel());
          response.setOvm3Label(result.getOvm3NetworkLabel());
  
          response.setObjectName("traffictype");
          return response;
      }
  
      @Override
      public VirtualRouterProviderResponse createVirtualRouterProviderResponse(VirtualRouterProvider result) {
          //generate only response of the VR/VPCVR provider type
          if (!(result.getType() == VirtualRouterProvider.Type.VirtualRouter || result.getType() == VirtualRouterProvider.Type.VPCVirtualRouter)) {
              return null;
          }
          VirtualRouterProviderResponse response = new VirtualRouterProviderResponse();
          response.setId(result.getUuid());
          PhysicalNetworkServiceProvider nsp = ApiDBUtils.findPhysicalNetworkServiceProviderById(result.getNspId());
          if (nsp != null) {
              response.setNspId(nsp.getUuid());
          }
          response.setEnabled(result.isEnabled());
  
          response.setObjectName("virtualrouterelement");
          return response;
      }
  
      @Override
      public OvsProviderResponse createOvsProviderResponse(OvsProvider result) {
  
          OvsProviderResponse response = new OvsProviderResponse();
          response.setId(result.getUuid());
          PhysicalNetworkServiceProvider nsp = ApiDBUtils.findPhysicalNetworkServiceProviderById(result.getNspId());
          if (nsp != null) {
              response.setNspId(nsp.getUuid());
          }
          response.setEnabled(result.isEnabled());
  
          response.setObjectName("ovselement");
          return response;
      }
  
      @Override
      public LBStickinessResponse createLBStickinessPolicyResponse(StickinessPolicy stickinessPolicy, LoadBalancer lb) {
          LBStickinessResponse spResponse = new LBStickinessResponse();
  
          spResponse.setlbRuleId(lb.getUuid());
          Account accountTemp = ApiDBUtils.findAccountById(lb.getAccountId());
          if (accountTemp != null) {
              spResponse.setAccountName(accountTemp.getAccountName());
              Domain domain = ApiDBUtils.findDomainById(accountTemp.getDomainId());
              if (domain != null) {
                  spResponse.setDomainId(domain.getUuid());
                  spResponse.setDomainName(domain.getName());
              }
          }
  
          List<LBStickinessPolicyResponse> responses = new ArrayList<LBStickinessPolicyResponse>();
          LBStickinessPolicyResponse ruleResponse = new LBStickinessPolicyResponse(stickinessPolicy);
          responses.add(ruleResponse);
  
          spResponse.setRules(responses);
  
          spResponse.setObjectName("stickinesspolicies");
          return spResponse;
      }
  
      @Override
      public LBStickinessResponse createLBStickinessPolicyResponse(List<? extends StickinessPolicy> stickinessPolicies, LoadBalancer lb) {
          LBStickinessResponse spResponse = new LBStickinessResponse();
  
          if (lb == null) {
              return spResponse;
          }
          spResponse.setlbRuleId(lb.getUuid());
          Account account = ApiDBUtils.findAccountById(lb.getAccountId());
          if (account != null) {
              spResponse.setAccountName(account.getAccountName());
              Domain domain = ApiDBUtils.findDomainById(account.getDomainId());
              if (domain != null) {
                  spResponse.setDomainId(domain.getUuid());
                  spResponse.setDomainName(domain.getName());
              }
          }
  
          List<LBStickinessPolicyResponse> responses = new ArrayList<LBStickinessPolicyResponse>();
          for (StickinessPolicy stickinessPolicy : stickinessPolicies) {
              LBStickinessPolicyResponse ruleResponse = new LBStickinessPolicyResponse(stickinessPolicy);
              responses.add(ruleResponse);
          }
          spResponse.setRules(responses);
  
          spResponse.setObjectName("stickinesspolicies");
          return spResponse;
      }
  
      @Override
      public LBHealthCheckResponse createLBHealthCheckPolicyResponse(List<? extends HealthCheckPolicy> healthcheckPolicies, LoadBalancer lb) {
          LBHealthCheckResponse hcResponse = new LBHealthCheckResponse();
  
          if (lb == null) {
              return hcResponse;
          }
          hcResponse.setlbRuleId(lb.getUuid());
          Account account = ApiDBUtils.findAccountById(lb.getAccountId());
          if (account != null) {
              hcResponse.setAccountName(account.getAccountName());
              Domain domain = ApiDBUtils.findDomainById(account.getDomainId());
              if (domain != null) {
                  hcResponse.setDomainId(domain.getUuid());
                  hcResponse.setDomainName(domain.getName());
              }
          }
  
          List<LBHealthCheckPolicyResponse> responses = new ArrayList<LBHealthCheckPolicyResponse>();
          for (HealthCheckPolicy healthcheckPolicy : healthcheckPolicies) {
              LBHealthCheckPolicyResponse ruleResponse = new LBHealthCheckPolicyResponse(healthcheckPolicy);
              responses.add(ruleResponse);
          }
          hcResponse.setRules(responses);
  
          hcResponse.setObjectName("healthcheckpolicies");
          return hcResponse;
      }
  
      @Override
      public LBHealthCheckResponse createLBHealthCheckPolicyResponse(HealthCheckPolicy healthcheckPolicy, LoadBalancer lb) {
          LBHealthCheckResponse hcResponse = new LBHealthCheckResponse();
  
          hcResponse.setlbRuleId(lb.getUuid());
          Account accountTemp = ApiDBUtils.findAccountById(lb.getAccountId());
          if (accountTemp != null) {
              hcResponse.setAccountName(accountTemp.getAccountName());
              Domain domain = ApiDBUtils.findDomainById(accountTemp.getDomainId());
              if (domain != null) {
                  hcResponse.setDomainId(domain.getUuid());
                  hcResponse.setDomainName(domain.getName());
              }
          }
  
          List<LBHealthCheckPolicyResponse> responses = new ArrayList<LBHealthCheckPolicyResponse>();
          LBHealthCheckPolicyResponse ruleResponse = new LBHealthCheckPolicyResponse(healthcheckPolicy);
          responses.add(ruleResponse);
          hcResponse.setRules(responses);
          hcResponse.setObjectName("healthcheckpolicies");
          return hcResponse;
      }
  
      @Override
      public StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result) {
          StorageNetworkIpRangeResponse response = new StorageNetworkIpRangeResponse();
          response.setUuid(result.getUuid());
          response.setVlan(result.getVlan());
          response.setEndIp(result.getEndIp());
          response.setStartIp(result.getStartIp());
          response.setPodUuid(result.getPodUuid());
          response.setZoneUuid(result.getZoneUuid());
          response.setNetworkUuid(result.getNetworkUuid());
          response.setNetmask(result.getNetmask());
          response.setGateway(result.getGateway());
          response.setObjectName("storagenetworkiprange");
          return response;
      }
  
      @Override
      public RegionResponse createRegionResponse(Region region) {
          RegionResponse response = new RegionResponse();
          response.setId(region.getId());
          response.setName(region.getName());
          response.setEndPoint(region.getEndPoint());
          response.setObjectName("region");
          response.setGslbServiceEnabled(region.checkIfServiceEnabled(Region.Service.Gslb));
          response.setPortableipServiceEnabled(region.checkIfServiceEnabled(Region.Service.PortableIp));
          return response;
      }
  
      @Override
      public ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly) {
          ResourceTagJoinVO rto = ApiDBUtils.newResourceTagView(resourceTag);
          if(rto == null)
              return null;
          return ApiDBUtils.newResourceTagResponse(rto, keyValueOnly);
      }
  
      @Override
      public VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering) {
          if (!(offering instanceof VpcOfferingJoinVO)) {
              offering = ApiDBUtils.newVpcOfferingView(offering);
          }
          VpcOfferingResponse response = ApiDBUtils.newVpcOfferingResponse(offering);
          Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listVpcOffServices(offering.getId());
          List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();
          for (Map.Entry<Service, Set<Provider>> entry : serviceProviderMap.entrySet()) {
              Service service = entry.getKey();
              Set<Provider> srvc_providers = entry.getValue();
  
              ServiceResponse svcRsp = new ServiceResponse();
              // skip gateway service
              if (service == Service.Gateway) {
                  continue;
              }
              svcRsp.setName(service.getName());
              List<ProviderResponse> providers = new ArrayList<ProviderResponse>();
              for (Provider provider : srvc_providers) {
                  if (provider != null) {
                      ProviderResponse providerRsp = new ProviderResponse();
                      providerRsp.setName(provider.getName());
                      providers.add(providerRsp);
                  }
              }
              svcRsp.setProviders(providers);
  
              serviceResponses.add(svcRsp);
          }
          response.setServices(serviceResponses);
          return response;
      }
  
      @Override
      public VpcResponse createVpcResponse(ResponseView view, Vpc vpc) {
          VpcResponse response = new VpcResponse();
          response.setId(vpc.getUuid());
          response.setName(vpc.getName());
          response.setDisplayText(vpc.getDisplayText());
          response.setCreated(vpc.getCreated());
          response.setState(vpc.getState().name());
          VpcOffering voff = ApiDBUtils.findVpcOfferingById(vpc.getVpcOfferingId());
          if (voff != null) {
              response.setVpcOfferingId(voff.getUuid());
              response.setVpcOfferingName(voff.getName());
          }
          response.setCidr(vpc.getCidr());
          response.setRestartRequired(vpc.isRestartRequired());
          response.setNetworkDomain(vpc.getNetworkDomain());
          response.setForDisplay(vpc.isDisplay());
          response.setUsesDistributedRouter(vpc.usesDistributedRouter());
          response.setRedundantRouter(vpc.isRedundant());
          response.setRegionLevelVpc(vpc.isRegionLevelVpc());
          ASNumberVO asNumberVO = asNumberDao.findByZoneAndVpcId(vpc.getZoneId(), vpc.getId());
          if (Objects.nonNull(asNumberVO)) {
              response.setAsNumberId(asNumberVO.getUuid());
              response.setAsNumber(asNumberVO.getAsNumber());
          }
          Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listVpcOffServices(vpc.getVpcOfferingId());
          List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();
          for (Map.Entry<Service,Set<Provider>>entry : serviceProviderMap.entrySet()) {
              Service service = entry.getKey();
              Set<Provider> serviceProviders = entry.getValue();
              ServiceResponse svcRsp = new ServiceResponse();
              // skip gateway service
              if (service == Service.Gateway) {
                  continue;
              }
              svcRsp.setName(service.getName());
              List<ProviderResponse> providers = new ArrayList<ProviderResponse>();
              for (Provider provider : serviceProviders) {
                  if (provider != null) {
                      ProviderResponse providerRsp = new ProviderResponse();
                      providerRsp.setName(provider.getName());
                      providers.add(providerRsp);
                  }
              }
              svcRsp.setProviders(providers);
  
              serviceResponses.add(svcRsp);
          }
  
          List<NetworkResponse> networkResponses = new ArrayList<NetworkResponse>();
          List<? extends Network> networks = ApiDBUtils.listVpcNetworks(vpc.getId());
          for (Network network : networks) {
              NetworkResponse ntwkRsp = createNetworkResponse(view, network);
              networkResponses.add(ntwkRsp);
          }
  
          DataCenter zone = ApiDBUtils.findZoneById(vpc.getZoneId());
          if (zone != null) {
              response.setZoneId(zone.getUuid());
              response.setZoneName(zone.getName());
          }
  
          response.setNetworks(networkResponses);
          response.setServices(serviceResponses);
          response.setPublicMtu(vpc.getPublicMtu());
          populateOwner(response, vpc);
  
          // set tag information
          List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.Vpc, vpc.getId());
          List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
          for (ResourceTag tag : tags) {
              ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
              CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
          }
          response.setTags(tagResponses);
          response.setHasAnnotation(annotationDao.hasAnnotations(vpc.getUuid(), AnnotationService.EntityType.VPC.name(),
                  _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
          ipv6Service.updateIpv6RoutesForVpcResponse(vpc, response);
          response.setDns1(vpc.getIp4Dns1());
          response.setDns2(vpc.getIp4Dns2());
          response.setIpv6Dns1(vpc.getIp6Dns1());
          response.setIpv6Dns2(vpc.getIp6Dns2());
  
          // add IPv4 routes
          if (vpcOfferingDao.isRoutedVpc(vpc.getVpcOfferingId())) {
              if (Objects.nonNull(asNumberVO)) {
                  response.setIpv4Routing(Network.Routing.Dynamic.name());
              } else {
                  response.setIpv4Routing(Network.Routing.Static.name());
              }
              response.setIpv4Routes(new LinkedHashSet<>());
              List<IPAddressVO> ips = userIpAddressDao.listByAssociatedVpc(vpc.getId(), true);
              for (Network network : networkDao.listByVpc(vpc.getId())) {
                  for (IPAddressVO ip : ips) {
                      Ipv4RouteResponse route = new Ipv4RouteResponse(network.getCidr(), ip.getAddress().addr());
                      response.addIpv4Route(route);
                  }
              }
              if (view == ResponseView.Full) {
                  List<BgpPeerVO> bgpPeerVOS = bgpPeerDao.listNonRevokeByVpcId(vpc.getId());
                  for (BgpPeerVO bgpPeerVO : bgpPeerVOS) {
                      BgpPeerResponse bgpPeerResponse = routedIpv4Manager.createBgpPeerResponse(bgpPeerVO);
                      response.addBgpPeer(bgpPeerResponse);
                  }
              }
          }
  
          response.setObjectName("vpc");
          return response;
      }
  
      @Override
      public PrivateGatewayResponse createPrivateGatewayResponse(ResponseView view, PrivateGateway result) {
          PrivateGatewayResponse response = new PrivateGatewayResponse();
          response.setId(result.getUuid());
          if (view == ResponseView.Full) {
              response.setBroadcastUri(result.getBroadcastUri());
          }
          response.setGateway(result.getGateway());
          response.setNetmask(result.getNetmask());
          if (result.getVpcId() != null) {
              Vpc vpc = ApiDBUtils.findVpcById(result.getVpcId());
              response.setVpcId(vpc.getUuid());
              response.setVpcName(vpc.getName());
          }
  
          DataCenter zone = ApiDBUtils.findZoneById(result.getZoneId());
          if (zone != null) {
              response.setZoneId(zone.getUuid());
              response.setZoneName(zone.getName());
          }
          response.setAddress(result.getIp4Address());
          PhysicalNetwork pnet = ApiDBUtils.findPhysicalNetworkById(result.getPhysicalNetworkId());
          if (pnet != null) {
              response.setPhysicalNetworkId(pnet.getUuid());
          }
  
          populateAccount(response, result.getAccountId());
          populateDomain(response, result.getDomainId());
          response.setState(result.getState().toString());
          response.setSourceNat(result.getSourceNat());
  
          NetworkACL acl =  ApiDBUtils.findByNetworkACLId(result.getNetworkACLId());
          if (acl != null) {
              response.setAclId(acl.getUuid());
              response.setAclName(acl.getName());
          }
  
          setResponseAssociatedNetworkInformation(response, result.getNetworkId());
  
          response.setObjectName("privategateway");
  
          return response;
      }
  
      @Override
      public CounterResponse createCounterResponse(Counter counter) {
          CounterResponse response = new CounterResponse();
          response.setId(counter.getUuid());
          response.setSource(counter.getSource().toString());
          response.setName(counter.getName());
          response.setValue(counter.getValue());
          response.setProvider(counter.getProvider());
          response.setObjectName("counter");
          return response;
      }
  
      @Override
      public ConditionResponse createConditionResponse(Condition condition) {
          ConditionResponse response = new ConditionResponse();
          response.setId(condition.getUuid());
          Counter counter = ApiDBUtils.getCounter(condition.getCounterId());
          response.setCounterId(counter.getUuid());
          response.setCounterName(counter.getName());
          CounterResponse counterResponse = createCounterResponse(counter);
          response.setCounterResponse(counterResponse);
          response.setRelationalOperator(condition.getRelationalOperator().toString());
          response.setThreshold(condition.getThreshold());
          response.setObjectName("condition");
          populateOwner(response, condition);
          return response;
      }
  
      @Override
      public AutoScaleVmProfileResponse createAutoScaleVmProfileResponse(AutoScaleVmProfile profile) {
          AutoScaleVmProfileResponse response = new AutoScaleVmProfileResponse();
          response.setId(profile.getUuid());
          if (profile.getZoneId() != null) {
              DataCenter zone = ApiDBUtils.findZoneById(profile.getZoneId());
              if (zone != null) {
                  response.setZoneId(zone.getUuid());
              }
          }
          if (profile.getServiceOfferingId() != null) {
              ServiceOffering so = ApiDBUtils.findServiceOfferingById(profile.getServiceOfferingId());
              if (so != null) {
                  response.setServiceOfferingId(so.getUuid());
              }
          }
          if (profile.getTemplateId() != null) {
              VMTemplateVO template = ApiDBUtils.findTemplateById(profile.getTemplateId());
              if (template != null) {
                  response.setTemplateId(template.getUuid());
                  if (template.getUserDataOverridePolicy() != null) {
                      response.setUserDataPolicy(template.getUserDataOverridePolicy().toString());
                  }
              }
          }
          response.setUserData(profile.getUserData());
          if (profile.getUserDataId() != null) {
              UserData userData = userDataDao.findById(profile.getUserDataId());
              if (userData != null) {
                  response.setUserDataId(userData.getUuid());
                  response.setUserDataName(userData.getName());
              }
          }
          response.setUserDataDetails(profile.getUserDataDetails());
          response.setOtherDeployParams(profile.getOtherDeployParamsList());
          response.setCounterParams(profile.getCounterParams());
          response.setExpungeVmGracePeriod(profile.getExpungeVmGracePeriod());
          User user = ApiDBUtils.findUserById(profile.getAutoScaleUserId());
          if (user != null) {
              response.setAutoscaleUserId(user.getUuid());
          }
          response.setObjectName("autoscalevmprofile");
  
          // Populates the account information in the response
          populateOwner(response, profile);
          return response;
      }
  
      @Override
      public AutoScalePolicyResponse createAutoScalePolicyResponse(AutoScalePolicy policy) {
          AutoScalePolicyResponse response = new AutoScalePolicyResponse();
          response.setId(policy.getUuid());
          response.setName(policy.getName());
          response.setDuration(policy.getDuration());
          response.setQuietTime(policy.getQuietTime());
          response.setAction(policy.getAction().toString());
          List<ConditionVO> vos = ApiDBUtils.getAutoScalePolicyConditions(policy.getId());
          ArrayList<ConditionResponse> conditions = new ArrayList<ConditionResponse>(vos.size());
          for (ConditionVO vo : vos) {
              conditions.add(createConditionResponse(vo));
          }
          response.setConditions(conditions);
          response.setObjectName("autoscalepolicy");
  
          // Populates the account information in the response
          populateOwner(response, policy);
  
          return response;
      }
  
      @Override
      public AutoScaleVmGroupResponse createAutoScaleVmGroupResponse(AutoScaleVmGroup vmGroup) {
          AutoScaleVmGroupResponse response = new AutoScaleVmGroupResponse();
          response.setId(vmGroup.getUuid());
          response.setName(vmGroup.getName());
          response.setMinMembers(vmGroup.getMinMembers());
          response.setMaxMembers(vmGroup.getMaxMembers());
          response.setState(vmGroup.getState().toString());
          response.setInterval(vmGroup.getInterval());
          response.setForDisplay(vmGroup.isDisplay());
          response.setCreated(vmGroup.getCreated());
          AutoScaleVmProfileVO profile = ApiDBUtils.findAutoScaleVmProfileById(vmGroup.getProfileId());
          if (profile != null) {
              response.setProfileId(profile.getUuid());
          }
          response.setAvailableVirtualMachineCount(ApiDBUtils.countAvailableVmsByGroupId(vmGroup.getId()));
          LoadBalancerVO fw = ApiDBUtils.findLoadBalancerById(vmGroup.getLoadBalancerId());
          if (fw != null) {
              response.setLoadBalancerId(fw.getUuid());
  
              NetworkVO network = ApiDBUtils.findNetworkById(fw.getNetworkId());
  
              if (network != null) {
                  response.setNetworkName(network.getName());
                  response.setNetworkId(network.getUuid());
  
                  String provider = ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Lb);
                  if (provider != null) {
                      response.setLbProvider(provider);
                  } else {
                      response.setLbProvider(Network.Provider.None.toString());
                  }
              }
  
              IPAddressVO publicIp = ApiDBUtils.findIpAddressById(fw.getSourceIpAddressId());
              if (publicIp != null) {
                  response.setPublicIpId(publicIp.getUuid());
                  response.setPublicIp(publicIp.getAddress().addr());
                  response.setPublicPort(Integer.toString(fw.getSourcePortStart()));
                  response.setPrivatePort(Integer.toString(fw.getDefaultPortStart()));
              }
          }
  
          List<AutoScalePolicyResponse> scaleUpPoliciesResponse = new ArrayList<AutoScalePolicyResponse>();
          List<AutoScalePolicyResponse> scaleDownPoliciesResponse = new ArrayList<AutoScalePolicyResponse>();
          response.setScaleUpPolicies(scaleUpPoliciesResponse);
          response.setScaleDownPolicies(scaleDownPoliciesResponse);
          response.setObjectName("autoscalevmgroup");
  
          // Fetch policies for vmgroup
          List<AutoScalePolicy> scaleUpPolicies = new ArrayList<AutoScalePolicy>();
          List<AutoScalePolicy> scaleDownPolicies = new ArrayList<AutoScalePolicy>();
          ApiDBUtils.getAutoScaleVmGroupPolicies(vmGroup.getId(), scaleUpPolicies, scaleDownPolicies);
          // populate policies
          for (AutoScalePolicy autoScalePolicy : scaleUpPolicies) {
              scaleUpPoliciesResponse.add(createAutoScalePolicyResponse(autoScalePolicy));
          }
          for (AutoScalePolicy autoScalePolicy : scaleDownPolicies) {
              scaleDownPoliciesResponse.add(createAutoScalePolicyResponse(autoScalePolicy));
          }
  
          response.setHasAnnotation(annotationDao.hasAnnotations(vmGroup.getUuid(), AnnotationService.EntityType.AUTOSCALE_VM_GROUP.name(),
                  _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
  
          populateOwner(response, vmGroup);
          return response;
      }
  
      @Override
      public StaticRouteResponse createStaticRouteResponse(StaticRoute result) {
          StaticRouteResponse response = new StaticRouteResponse();
          response.setId(result.getUuid());
          if (result.getVpcId() != null) {
              Vpc vpc = ApiDBUtils.findVpcById(result.getVpcId());
              if (vpc != null) {
                  response.setVpcId(vpc.getUuid());
              }
          }
          if (result.getVpcGatewayId() != null) {
              VpcGateway vpcGateway = _entityMgr.findById(VpcGateway.class, result.getVpcGatewayId());
              if (vpcGateway != null) {
                  response.setVpcGatewayId(vpcGateway.getUuid());
                  response.setVpcGatewayIp(vpcGateway.getIp4Address());
              }
          }
          if (result.getNextHop() != null) {
              response.setNextHop(result.getNextHop());
          }
          response.setCidr(result.getCidr());
  
          StaticRoute.State state = result.getState();
          if (state.equals(StaticRoute.State.Revoke)) {
              state = StaticRoute.State.Deleting;
          }
          response.setState(state.toString());
          populateAccount(response, result.getAccountId());
          populateDomain(response, result.getDomainId());
  
          // set tag information
          List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.StaticRoute, result.getId());
          List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
          for (ResourceTag tag : tags) {
              ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
              CollectionUtils.addIgnoreNull(tagResponses,tagResponse);
          }
          response.setTags(tagResponses);
          response.setObjectName("staticroute");
  
          return response;
      }
  
      @Override
      public Site2SiteVpnGatewayResponse createSite2SiteVpnGatewayResponse(Site2SiteVpnGateway result) {
          Site2SiteVpnGatewayResponse response = new Site2SiteVpnGatewayResponse();
          response.setId(result.getUuid());
          response.setIp(ApiDBUtils.findIpAddressById(result.getAddrId()).getAddress().toString());
          Vpc vpc = ApiDBUtils.findVpcById(result.getVpcId());
          if (vpc != null) {
              response.setVpcId(vpc.getUuid());
              response.setVpcName(vpc.getName());
          }
          response.setRemoved(result.getRemoved());
          response.setForDisplay(result.isDisplay());
          response.setObjectName("vpngateway");
  
          populateAccount(response, result.getAccountId());
          populateDomain(response, result.getDomainId());
          return response;
      }
  
      @Override
      public Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(Site2SiteCustomerGateway result) {
          Site2SiteCustomerGatewayResponse response = new Site2SiteCustomerGatewayResponse();
          response.setId(result.getUuid());
          response.setName(result.getName());
          response.setGatewayIp(result.getGatewayIp());
          response.setGuestCidrList(result.getGuestCidrList());
          response.setIpsecPsk(result.getIpsecPsk());
          response.setIkePolicy(result.getIkePolicy());
          response.setEspPolicy(result.getEspPolicy());
          response.setIkeLifetime(result.getIkeLifetime());
          response.setEspLifetime(result.getEspLifetime());
          response.setDpd(result.getDpd());
          response.setEncap(result.getEncap());
          response.setRemoved(result.getRemoved());
          response.setIkeVersion(result.getIkeVersion());
          response.setSplitConnections(result.getSplitConnections());
          response.setObjectName("vpncustomergateway");
          response.setHasAnnotation(annotationDao.hasAnnotations(result.getUuid(), AnnotationService.EntityType.VPN_CUSTOMER_GATEWAY.name(),
                  _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
  
          populateAccount(response, result.getAccountId());
          populateDomain(response, result.getDomainId());
  
          return response;
      }
  
      @Override
      public Site2SiteVpnConnectionResponse createSite2SiteVpnConnectionResponse(Site2SiteVpnConnection result) {
          Site2SiteVpnConnectionResponse response = new Site2SiteVpnConnectionResponse();
          response.setId(result.getUuid());
          response.setPassive(result.isPassive());
  
          Long vpnGatewayId = result.getVpnGatewayId();
          if (vpnGatewayId != null) {
              Site2SiteVpnGateway vpnGateway = ApiDBUtils.findVpnGatewayById(vpnGatewayId);
              if (vpnGateway != null) {
                  response.setVpnGatewayId(vpnGateway.getUuid());
                  long ipId = vpnGateway.getAddrId();
                  IPAddressVO ipObj = ApiDBUtils.findIpAddressById(ipId);
                  response.setIp(ipObj.getAddress().addr());
              }
          }
  
          Long customerGatewayId = result.getCustomerGatewayId();
          if (customerGatewayId != null) {
              Site2SiteCustomerGateway customerGateway = ApiDBUtils.findCustomerGatewayById(customerGatewayId);
              if (customerGateway != null) {
                  response.setCustomerGatewayId(customerGateway.getUuid());
                  response.setGatewayIp(customerGateway.getGatewayIp());
                  response.setGuestCidrList(customerGateway.getGuestCidrList());
                  response.setIpsecPsk(customerGateway.getIpsecPsk());
                  response.setIkePolicy(customerGateway.getIkePolicy());
                  response.setEspPolicy(customerGateway.getEspPolicy());
                  response.setIkeLifetime(customerGateway.getIkeLifetime());
                  response.setEspLifetime(customerGateway.getEspLifetime());
                  response.setDpd(customerGateway.getDpd());
                  response.setEncap(customerGateway.getEncap());
                  response.setIkeVersion(customerGateway.getIkeVersion());
                  response.setSplitConnections(customerGateway.getSplitConnections());
              }
          }
  
          populateAccount(response, result.getAccountId());
          populateDomain(response, result.getDomainId());
  
          response.setState(result.getState().toString());
          response.setCreated(result.getCreated());
          response.setRemoved(result.getRemoved());
          response.setForDisplay(result.isDisplay());
          response.setObjectName("vpnconnection");
          return response;
      }
  
      @Override
      public GuestOSCategoryResponse createGuestOSCategoryResponse(GuestOsCategory guestOsCategory) {
          return createGuestOSCategoryResponse(guestOsCategory, true);
      }
  
      @Override
      public GuestOSCategoryResponse createGuestOSCategoryResponse(GuestOsCategory guestOsCategory, boolean showIcon) {
          GuestOSCategoryResponse categoryResponse = new GuestOSCategoryResponse();
          categoryResponse.setId(guestOsCategory.getUuid());
          categoryResponse.setName(guestOsCategory.getName());
          categoryResponse.setFeatured(guestOsCategory.isFeatured());
          categoryResponse.setCreated(guestOsCategory.getCreated());
          if (showIcon) {
              ResourceIconVO resourceIcon = ApiDBUtils.getResourceIconByResourceUUID(guestOsCategory.getUuid(),
                      ResourceObjectType.GuestOsCategory);
              if (resourceIcon != null) {
                  ResourceIconResponse iconResponse = ApiDBUtils.newResourceIconResponse(resourceIcon);
                  categoryResponse.setResourceIconResponse(iconResponse);
              }
          }
          categoryResponse.setObjectName("oscategory");
          return categoryResponse;
      }
  
      @Override
      public GuestOSResponse createGuestOSResponse(GuestOS guestOS) {
          GuestOSResponse response = new GuestOSResponse();
          response.setName(guestOS.getDisplayName());
          response.setDescription(guestOS.getDisplayName());
          response.setId(guestOS.getUuid());
          response.setIsUserDefined(guestOS.getIsUserDefined());
          response.setForDisplay(guestOS.getForDisplay());
          GuestOSCategoryVO category = ApiDBUtils.findGuestOsCategoryById(guestOS.getCategoryId());
          if (category != null) {
              response.setOsCategoryId(category.getUuid());
              response.setOsCategoryName(category.getName());
          }
  
          response.setObjectName("ostype");
          return response;
      }
  
      @Override
      public GuestOsMappingResponse createGuestOSMappingResponse(GuestOSHypervisor guestOSHypervisor) {
          GuestOsMappingResponse response = new GuestOsMappingResponse();
          response.setId(guestOSHypervisor.getUuid());
          response.setHypervisor(Hypervisor.HypervisorType.getType(guestOSHypervisor.getHypervisorType()).getHypervisorDisplayName());
          response.setHypervisorVersion(guestOSHypervisor.getHypervisorVersion());
          response.setOsNameForHypervisor((guestOSHypervisor.getGuestOsName()));
          response.setIsUserDefined(Boolean.valueOf(guestOSHypervisor.getIsUserDefined()).toString());
          GuestOS guestOs = ApiDBUtils.findGuestOSById(guestOSHypervisor.getGuestOsId());
          if (guestOs != null) {
              response.setOsStdName(guestOs.getDisplayName());
              response.setOsTypeId(guestOs.getUuid());
          }
  
          response.setObjectName("guestosmapping");
          return response;
      }
  
      @Override
      public HypervisorGuestOsNamesResponse createHypervisorGuestOSNamesResponse(List<Pair<String, String>> hypervisorGuestOsNames) {
          HypervisorGuestOsNamesResponse response = new HypervisorGuestOsNamesResponse();
          List<HypervisorGuestOsResponse> hypervisorGuestOsResponses = new ArrayList<>();
          for (Pair<String, String> hypervisorGuestOsName : hypervisorGuestOsNames) {
              HypervisorGuestOsResponse hypervisorGuestOsResponse = createHypervisorGuestOsResponse(hypervisorGuestOsName);
              hypervisorGuestOsResponses.add(hypervisorGuestOsResponse);
          }
          response.setGuestOSList(hypervisorGuestOsResponses);
          response.setGuestOSCount(hypervisorGuestOsResponses.size());
          response.setObjectName("hypervisorguestosnames");
          return response;
      }
  
      private HypervisorGuestOsResponse createHypervisorGuestOsResponse(Pair<String, String> hypervisorGuestOsName) {
          HypervisorGuestOsResponse hypervisorGuestOsResponse = new HypervisorGuestOsResponse();
          hypervisorGuestOsResponse.setOsStdName(hypervisorGuestOsName.first());
          hypervisorGuestOsResponse.setOsNameForHypervisor(hypervisorGuestOsName.second());
          hypervisorGuestOsResponse.setObjectName(ApiConstants.GUEST_OS_LIST);
          return hypervisorGuestOsResponse;
      }
  
      @Override
      public SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule snapshotSchedule) {
          SnapshotScheduleResponse response = new SnapshotScheduleResponse();
          response.setId(snapshotSchedule.getUuid());
          if (snapshotSchedule.getVolumeId() != null) {
              Volume vol = ApiDBUtils.findVolumeById(snapshotSchedule.getVolumeId());
              if (vol != null) {
                  response.setVolumeId(vol.getUuid());
              }
          }
          if (snapshotSchedule.getPolicyId() != null) {
              SnapshotPolicy policy = ApiDBUtils.findSnapshotPolicyById(snapshotSchedule.getPolicyId());
              if (policy != null) {
                  response.setSnapshotPolicyId(policy.getUuid());
              }
          }
          response.setScheduled(snapshotSchedule.getScheduledTimestamp());
  
          response.setObjectName("snapshot");
          return response;
      }
  
      @Override
      public Map<String, Set<ResourceTagResponse>> getUsageResourceTags()
      {
          try {
              return _resourceTagDao.listTags();
          } catch(Exception ex) {
              logger.warn("Failed to get resource details for Usage data due to exception : ", ex);
          }
          return null;
      }
  
      @Override
      public UsageRecordResponse createUsageResponse(Usage usageRecord) {
          return createUsageResponse(usageRecord, null, false);
      }
  
      @Override
      public UsageRecordResponse createUsageResponse(Usage usageRecord, Map<String, Set<ResourceTagResponse>> resourceTagResponseMap, boolean oldFormat) {
          UsageRecordResponse usageRecResponse = new UsageRecordResponse();
          Account account = ApiDBUtils.findAccountById(usageRecord.getAccountId());
          if (account.getType() == Account.Type.PROJECT) {
              //find the project
              Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getId());
              if (project != null) {
                  usageRecResponse.setProjectId(project.getUuid());
                  usageRecResponse.setProjectName(project.getName());
              }
          } else {
              usageRecResponse.setAccountId(account.getUuid());
              usageRecResponse.setAccountName(account.getAccountName());
          }
  
          populateDomain(usageRecResponse, account.getDomainId());
  
          if (usageRecord.getZoneId() != null) {
              DataCenter zone = ApiDBUtils.findZoneById(usageRecord.getZoneId());
              if (zone != null) {
                  usageRecResponse.setZoneId(zone.getUuid());
              }
          }
          usageRecResponse.setDescription(usageRecord.getDescription());
          usageRecResponse.setUsage(usageRecord.getUsageDisplay());
          usageRecResponse.setUsageType(usageRecord.getUsageType());
          VMInstanceVO vmInstance = null;
          if (usageRecord.getVmInstanceId() != null) {
              vmInstance = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId());
              if (vmInstance != null) {
                  usageRecResponse.setVirtualMachineId(vmInstance.getUuid());
              }
          }
          usageRecResponse.setResourceName(usageRecord.getVmName());
          VMTemplateVO template = null;
          if (usageRecord.getTemplateId() != null) {
              template = ApiDBUtils.findTemplateById(usageRecord.getTemplateId());
              if (template != null) {
                  usageRecResponse.setTemplateId(template.getUuid());
              }
          }
  
          ResourceTag.ResourceObjectType resourceType = null;
          Long resourceId = null;
          if (usageRecord.getUsageType() == UsageTypes.RUNNING_VM || usageRecord.getUsageType() == UsageTypes.ALLOCATED_VM) {
              ServiceOfferingVO svcOffering = _entityMgr.findByIdIncludingRemoved(ServiceOfferingVO.class, usageRecord.getOfferingId().toString());
              //Service Offering Id
              if(svcOffering != null) {
                  usageRecResponse.setOfferingId(svcOffering.getUuid());
              }
              //VM Instance ID
              VMInstanceVO vm = null;
              if (usageRecord.getUsageId() != null && usageRecord.getUsageId().equals(usageRecord.getVmInstanceId())) {
                  vm = vmInstance;
              } else {
                  vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString());
              }
              if (vm != null) {
                  resourceType = ResourceTag.ResourceObjectType.UserVm;
                  usageRecResponse.setUsageId(vm.getUuid());
                  resourceId = vm.getId();
                  final GuestOS guestOS = _guestOsDao.findById(vm.getGuestOSId());
                  if (guestOS != null) {
                      usageRecResponse.setOsTypeId(guestOS.getUuid());
                      usageRecResponse.setOsDisplayName(guestOS.getDisplayName());
                      final GuestOsCategory guestOsCategory = _guestOsCategoryDao.findById(guestOS.getCategoryId());
                      if (guestOsCategory != null) {
                          usageRecResponse.setOsCategoryId(guestOsCategory.getUuid());
                          usageRecResponse.setOsCategoryName(guestOsCategory.getName());
                      }
                  }
              }
              //Hypervisor Type
              usageRecResponse.setType(usageRecord.getType());
              //Dynamic compute offerings details
              if(usageRecord.getCpuCores() != null) {
                  usageRecResponse.setCpuNumber(usageRecord.getCpuCores());
              } else if (svcOffering.getCpu() != null){
                  usageRecResponse.setCpuNumber(svcOffering.getCpu().longValue());
              }
              if(usageRecord.getCpuSpeed() != null) {
                  usageRecResponse.setCpuSpeed(usageRecord.getCpuSpeed());
              } else if(svcOffering.getSpeed() != null){
                  usageRecResponse.setCpuSpeed(svcOffering.getSpeed().longValue());
              }
              if(usageRecord.getMemory() != null) {
                  usageRecResponse.setMemory(usageRecord.getMemory());
              } else if(svcOffering.getRamSize() != null) {
                  usageRecResponse.setMemory(svcOffering.getRamSize().longValue());
              }
              if (!oldFormat) {
                  final StringBuilder builder = new StringBuilder();
                  if (usageRecord.getUsageType() == UsageTypes.RUNNING_VM) {
                      builder.append("Running VM usage ");
                  } else if(usageRecord.getUsageType() == UsageTypes.ALLOCATED_VM) {
                      builder.append("Allocated VM usage ");
                  }
                  if (vm != null) {
                      builder.append("for ").append(vm.getHostName()).append(" (").append(vm.getInstanceName()).append(") (").append(vm.getUuid()).append(") ");
                  }
                  if (svcOffering != null) {
                      builder.append("using service offering ").append(svcOffering.getName()).append(" (").append(svcOffering.getUuid()).append(") ");
                  }
                  if (template != null) {
                      builder.append("and template ").append(template.getName()).append(" (").append(template.getUuid()).append(")");
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.IP_ADDRESS) {
              //IP Address ID
              IPAddressVO ip = _entityMgr.findByIdIncludingRemoved(IPAddressVO.class, usageRecord.getUsageId().toString());
              if (ip != null) {
                  Long networkId = ip.getAssociatedWithNetworkId();
                  if (networkId == null) {
                      networkId = ip.getSourceNetworkId();
                  }
                  resourceType = ResourceObjectType.PublicIpAddress;
                  resourceId = ip.getId();
                  usageRecResponse.setUsageId(ip.getUuid());
              }
              //isSourceNAT
              usageRecResponse.setSourceNat((usageRecord.getType().equals("SourceNat")) ? true : false);
              //isSystem
              usageRecResponse.setSystem((usageRecord.getSize() == 1) ? true : false);
          } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_SENT || usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_RECEIVED) {
              //Device Type
              resourceType = ResourceObjectType.UserVm;
              usageRecResponse.setType(usageRecord.getType());
              VMInstanceVO vm = null;
              HostVO host = null;
              if (usageRecord.getType().equals("DomainRouter") || usageRecord.getType().equals("UserVm")) {
                  //Domain Router Id
                  vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString());
                  if (vm != null) {
                      resourceId = vm.getId();
                      usageRecResponse.setUsageId(vm.getUuid());
                  }
              } else {
                  //External Device Host Id
                  host = _entityMgr.findByIdIncludingRemoved(HostVO.class, usageRecord.getUsageId().toString());
                  if (host != null) {
                      usageRecResponse.setUsageId(host.getUuid());
                  }
              }
              //Network ID
              NetworkVO network = null;
              if((usageRecord.getNetworkId() != null) && (usageRecord.getNetworkId() != 0)) {
                  network = _entityMgr.findByIdIncludingRemoved(NetworkVO.class, usageRecord.getNetworkId().toString());
                  if (network != null) {
                      resourceType = ResourceObjectType.Network;
                      if (network.getTrafficType() == TrafficType.Public) {
                          VirtualRouter router = ApiDBUtils.findDomainRouterById(usageRecord.getUsageId());
                          Vpc vpc = ApiDBUtils.findVpcByIdIncludingRemoved(router.getVpcId());
                          usageRecResponse.setVpcId(vpc.getUuid());
                          resourceId = vpc.getId();
                      } else {
                          usageRecResponse.setNetworkId(network.getUuid());
                          resourceId = network.getId();
                      }
                      usageRecResponse.setResourceName(network.getName());
                  }
              }
              if (!oldFormat) {
                  final StringBuilder builder = new StringBuilder();
                  if (usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_SENT) {
                      builder.append("Bytes sent by network ");
                  } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_RECEIVED) {
                      builder.append("Bytes received by network ");
                  }
                  if (network != null) {
                      if (network.getName() != null) {
                          builder.append(network.getName());
                      }
                      if (network.getUuid() != null){
                          builder.append(" (").append(network.getUuid()).append(") ");
                      }
                      builder.append(" " + toHumanReadableSize(usageRecord.getRawUsage().longValue())  + " ");
                  }
                  if (vm != null) {
                      builder.append("using router ").append(vm.getInstanceName()).append(" (").append(vm.getUuid()).append(")");
                  } else if (host != null) {
                      builder.append("using host ").append(host.getName()).append(" (").append(host.getUuid()).append(")");
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_READ || usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_WRITE
                  || usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_READ || usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_WRITE) {
              //Device Type
              usageRecResponse.setType(usageRecord.getType());
              resourceType = ResourceObjectType.Volume;
              //Volume ID
              VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString());
              if (volume != null) {
                  usageRecResponse.setUsageId(volume.getUuid());
                  resourceId = volume.getId();
              }
              if (!oldFormat) {
                  final StringBuilder builder = new StringBuilder();
                  if (usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_READ) {
                      builder.append("Disk I/O read requests");
                  } else if (usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_WRITE) {
                      builder.append("Disk I/O write requests");
                  } else if (usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_READ) {
                      builder.append("Disk I/O read bytes");
                  } else if (usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_WRITE) {
                      builder.append("Disk I/O write bytes");
                  }
                  if (vmInstance != null) {
                      builder.append(" for VM ").append(vmInstance.getHostName()).append(" (").append(vmInstance.getUuid()).append(")");
                  }
                  if (volume != null) {
                      builder.append(" and volume ").append(volume.getName()).append(" (").append(volume.getUuid()).append(")");
                  }
                  if (usageRecord.getRawUsage()!= null){
                      builder.append(" " + toHumanReadableSize(usageRecord.getRawUsage().longValue()));
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.VOLUME) {
              //Volume ID
              VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString());
              resourceType = ResourceObjectType.Volume;
              if (volume != null) {
                  usageRecResponse.setUsageId(volume.getUuid());
                  resourceId = volume.getId();
              }
              //Volume Size
              usageRecResponse.setSize(usageRecord.getSize());
              //Disk Offering Id
              DiskOfferingVO diskOff = null;
              if (usageRecord.getOfferingId() != null) {
                  diskOff = _entityMgr.findByIdIncludingRemoved(DiskOfferingVO.class, usageRecord.getOfferingId().toString());
                  usageRecResponse.setOfferingId(diskOff.getUuid());
              }
              if (!oldFormat) {
                  final StringBuilder builder = new StringBuilder();
                  builder.append("Volume usage ");
                  if (volume != null) {
                      builder.append("for ").append(volume.getName()).append(" (").append(volume.getUuid()).append(")");
                  }
                  if (diskOff != null) {
                      builder.append(" with disk offering ").append(diskOff.getName()).append(" (").append(diskOff.getUuid()).append(")");
                  }
                  if (template != null) {
                      builder.append(" and template ").append(template.getName()).append(" (").append(template.getUuid()).append(")");
                  }
                  if (usageRecord.getSize() != null) {
                      builder.append(" and size " + toHumanReadableSize(usageRecord.getSize()));
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.TEMPLATE || usageRecord.getUsageType() == UsageTypes.ISO) {
              //Template/ISO ID
              VMTemplateVO tmpl = _entityMgr.findByIdIncludingRemoved(VMTemplateVO.class, usageRecord.getUsageId().toString());
              if (tmpl != null) {
                  usageRecResponse.setUsageId(tmpl.getUuid());
                  resourceId = tmpl.getId();
              }
              //Template/ISO Size
              usageRecResponse.setSize(usageRecord.getSize());
              if (usageRecord.getUsageType() == UsageTypes.ISO) {
                  usageRecResponse.setVirtualSize(usageRecord.getSize());
                  resourceType = ResourceObjectType.ISO;
              } else {
                  usageRecResponse.setVirtualSize(usageRecord.getVirtualSize());
                  resourceType = ResourceObjectType.Template;
              }
              if (!oldFormat) {
                  final StringBuilder builder = new StringBuilder();
                  if (usageRecord.getUsageType() == UsageTypes.TEMPLATE) {
                      builder.append("Template usage");
                  } else if (usageRecord.getUsageType() == UsageTypes.ISO) {
                      builder.append("ISO usage");
                  }
                  if (tmpl != null) {
                      builder.append(" for ").append(tmpl.getName()).append(" (").append(tmpl.getUuid()).append(") ")
                              .append("with size ").append(toHumanReadableSize(usageRecord.getSize())).append(" and virtual size ").append(toHumanReadableSize(usageRecord.getVirtualSize()));
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.SNAPSHOT) {
              //Snapshot ID
              SnapshotVO snap = _entityMgr.findByIdIncludingRemoved(SnapshotVO.class, usageRecord.getUsageId().toString());
              resourceType = ResourceObjectType.Snapshot;
              if (snap != null) {
                  usageRecResponse.setUsageId(snap.getUuid());
                  resourceId = snap.getId();
              }
              //Snapshot Size
              usageRecResponse.setSize(usageRecord.getSize());
              if (!oldFormat) {
                  final StringBuilder builder = new StringBuilder();
                  builder.append("Snapshot usage ");
                  if (snap != null) {
                      builder.append("for ").append(snap.getName()).append(" (").append(snap.getUuid()).append(") ")
                              .append("with size ").append(toHumanReadableSize(usageRecord.getSize()));
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.LOAD_BALANCER_POLICY) {
              //Load Balancer Policy ID
              LoadBalancerVO lb = _entityMgr.findByIdIncludingRemoved(LoadBalancerVO.class, usageRecord.getUsageId().toString());
              resourceType = ResourceObjectType.LoadBalancer;
              if (lb != null) {
                  usageRecResponse.setUsageId(lb.getUuid());
                  resourceId = lb.getId();
              }
              if (!oldFormat) {
                  final StringBuilder builder = new StringBuilder();
                  builder.append("Loadbalancer policy usage ");
                  if (lb != null) {
                      builder.append(lb.getName()).append(" (").append(lb.getUuid()).append(")");
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.PORT_FORWARDING_RULE) {
              //Port Forwarding Rule ID
              PortForwardingRuleVO pf = _entityMgr.findByIdIncludingRemoved(PortForwardingRuleVO.class, usageRecord.getUsageId().toString());
              resourceType = ResourceObjectType.PortForwardingRule;
              if (pf != null) {
                  usageRecResponse.setUsageId(pf.getUuid());
                  resourceId = pf.getId();
              }
              if (!oldFormat) {
                  final StringBuilder builder = new StringBuilder();
                  builder.append("Port forwarding rule usage");
                  if (pf != null) {
                      builder.append(" (").append(pf.getUuid()).append(")");
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_OFFERING) {
              //Network Offering Id
              NetworkOfferingVO netOff = _entityMgr.findByIdIncludingRemoved(NetworkOfferingVO.class, usageRecord.getOfferingId().toString());
              usageRecResponse.setOfferingId(netOff.getUuid());
              //is Default
              usageRecResponse.setDefault(usageRecord.getUsageId() == 1);
              if (!oldFormat) {
                  final StringBuilder builder = new StringBuilder();
                  builder.append("Network offering ");
                  if (netOff != null) {
                      builder.append(netOff.getName()).append(" (").append(netOff.getUuid()).append(") usage ");
                  }
                  if (vmInstance != null) {
                      builder.append("for VM ").append(vmInstance.getHostName()).append(" (").append(vmInstance.getUuid()).append(") ");
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.VPN_USERS) {
              //VPN User ID
              VpnUserVO vpnUser = _entityMgr.findByIdIncludingRemoved(VpnUserVO.class, usageRecord.getUsageId().toString());
              if (vpnUser != null) {
                  usageRecResponse.setUsageId(vpnUser.getUuid());
              }
              if (!oldFormat) {
                  final StringBuilder builder = new StringBuilder();
                  builder.append("VPN usage ");
                  if (vpnUser != null) {
                      builder.append("for user ").append(vpnUser.getUsername()).append(" (").append(vpnUser.getUuid()).append(")");
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.SECURITY_GROUP) {
              //Security Group Id
              SecurityGroupVO sg = _entityMgr.findByIdIncludingRemoved(SecurityGroupVO.class, usageRecord.getUsageId().toString());
              resourceType = ResourceObjectType.SecurityGroup;
              if (sg != null) {
                  resourceId = sg.getId();
                  usageRecResponse.setUsageId(sg.getUuid());
              }
              if (!oldFormat) {
                  final StringBuilder builder = new StringBuilder();
                  builder.append("Security group");
                  if (sg != null) {
                      builder.append(" ").append(sg.getName()).append(" (").append(sg.getUuid()).append(") usage");
                  }
                  if (vmInstance != null) {
                      builder.append(" for VM ").append(vmInstance.getHostName()).append(" (").append(vmInstance.getUuid()).append(")");
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.BACKUP) {
              resourceType = ResourceObjectType.Backup;
              final StringBuilder builder = new StringBuilder();
              builder.append("Backup usage of size ").append(usageRecord.getUsageDisplay());
              if (vmInstance != null) {
                  resourceId = vmInstance.getId();
                  usageRecResponse.setResourceName(vmInstance.getInstanceName());
                  usageRecResponse.setUsageId(vmInstance.getUuid());
                  builder.append(" for VM ").append(vmInstance.getHostName())
                          .append(" (").append(vmInstance.getUuid()).append(")");
                  final BackupOffering backupOffering = backupOfferingDao.findByIdIncludingRemoved(usageRecord.getOfferingId());
                  if (backupOffering != null) {
                      builder.append(" and backup offering ").append(backupOffering.getName())
                              .append(" (").append(backupOffering.getUuid()).append(", user ad-hoc/scheduled backup allowed: ")
                              .append(backupOffering.isUserDrivenBackupAllowed()).append(")");
                  }
  
              }
              usageRecResponse.setDescription(builder.toString());
          } else if (usageRecord.getUsageType() == UsageTypes.VM_SNAPSHOT) {
              resourceType = ResourceObjectType.VMSnapshot;
              VMSnapshotVO vmSnapshotVO = null;
              if (usageRecord.getUsageId() != null) {
                  vmSnapshotVO = vmSnapshotDao.findByIdIncludingRemoved(usageRecord.getUsageId());
                  if (vmSnapshotVO != null) {
                      resourceId = vmSnapshotVO.getId();
                      usageRecResponse.setResourceName(vmSnapshotVO.getDisplayName());
                      usageRecResponse.setUsageId(vmSnapshotVO.getUuid());
                  }
              }
              usageRecResponse.setSize(usageRecord.getSize());
              if (usageRecord.getVirtualSize() != null) {
                  usageRecResponse.setVirtualSize(usageRecord.getVirtualSize());
              }
              if (usageRecord.getOfferingId() != null) {
                  usageRecResponse.setOfferingId(usageRecord.getOfferingId().toString());
              }
              if (!oldFormat) {
                  VolumeVO volume = null;
                  if (vmSnapshotVO == null && usageRecord.getUsageId() != null) {
                       volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString());
                  }
  
                  DiskOfferingVO diskOff = null;
                  if (usageRecord.getOfferingId() != null) {
                      diskOff = _entityMgr.findByIdIncludingRemoved(DiskOfferingVO.class, usageRecord.getOfferingId());
                  }
                  final StringBuilder builder = new StringBuilder();
                  builder.append("VMSnapshot usage");
                  if (vmSnapshotVO != null) {
                      builder.append(" Id: ").append(vmSnapshotVO.getUuid());
                  }
                  if (vmInstance != null) {
                      builder.append(" for VM ").append(vmInstance.getHostName()).append(" (").append(vmInstance.getUuid()).append(")");
                  }
                  if (volume != null) {
                      builder.append(" with volume ").append(volume.getName()).append(" (").append(volume.getUuid()).append(")");
                  }
                  if (diskOff != null) {
                      builder.append(" using disk offering ").append(diskOff.getName()).append(" (").append(diskOff.getUuid()).append(")");
                  }
                  if (usageRecord.getSize() != null){
                      builder.append(" and size " + toHumanReadableSize(usageRecord.getSize()));
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.VOLUME_SECONDARY) {
              VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString());
              if (!oldFormat) {
                  final StringBuilder builder = new StringBuilder();
                  builder.append("Volume on secondary storage usage");
                  if (volume != null) {
                      builder.append(" for ").append(volume.getName()).append(" (").append(volume.getUuid()).append(") ")
                              .append("with size ").append(toHumanReadableSize(usageRecord.getSize()));
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.VM_SNAPSHOT_ON_PRIMARY) {
              resourceType = ResourceObjectType.VMSnapshot;
              VMSnapshotVO vmSnapshotVO = null;
              if (usageRecord.getUsageId() != null) {
                  vmSnapshotVO = vmSnapshotDao.findByIdIncludingRemoved(usageRecord.getUsageId());
                  if (vmSnapshotVO != null) {
                      resourceId = vmSnapshotVO.getId();
                      usageRecResponse.setResourceName(vmSnapshotVO.getDisplayName());
                      usageRecResponse.setUsageId(vmSnapshotVO.getUuid());
                  }
              }
              usageRecResponse.setSize(usageRecord.getVirtualSize());
              if (!oldFormat) {
                  final StringBuilder builder = new StringBuilder();
                  builder.append("VMSnapshot on primary storage usage");
                  if (vmSnapshotVO != null) {
                      builder.append(" Id: ").append(vmSnapshotVO.getUuid());
                  }
                  if (vmInstance != null) {
                      builder.append(" for VM ").append(vmInstance.getHostName()).append(" (").append(vmInstance.getUuid()).append(") ")
                              .append("with size ").append(toHumanReadableSize(usageRecord.getVirtualSize()));
                  }
                  usageRecResponse.setDescription(builder.toString());
              }
          } else if (usageRecord.getUsageType() == UsageTypes.BUCKET) {
              BucketVO bucket = _entityMgr.findByIdIncludingRemoved(BucketVO.class, usageRecord.getUsageId().toString());
              usageRecResponse.setUsageId(bucket.getUuid());
              usageRecResponse.setResourceName(bucket.getName());
          }
          if(resourceTagResponseMap != null && resourceTagResponseMap.get(resourceId + ":" + resourceType) != null) {
               usageRecResponse.setTags(resourceTagResponseMap.get(resourceId + ":" + resourceType));
          }
  
          if (usageRecord.getRawUsage() != null) {
              DecimalFormat decimalFormat = new DecimalFormat("###########.######");
              usageRecResponse.setRawUsage(decimalFormat.format(usageRecord.getRawUsage()));
          }
  
          if (usageRecord.getStartDate() != null) {
              usageRecResponse.setStartDate(usageRecord.getStartDate());
          }
          if (usageRecord.getEndDate() != null) {
              usageRecResponse.setEndDate(usageRecord.getEndDate());
          }
  
          return usageRecResponse;
      }
  
      public String getDateStringInternal(Date inputDate) {
          if (inputDate == null) {
              return null;
          }
  
          TimeZone tz = _usageSvc.getUsageTimezone();
          Calendar cal = Calendar.getInstance(tz);
          cal.setTime(inputDate);
  
          StringBuilder sb = new StringBuilder(32);
          sb.append(cal.get(Calendar.YEAR)).append('-');
  
          int month = cal.get(Calendar.MONTH) + 1;
          if (month < 10) {
              sb.append('0');
          }
          sb.append(month).append('-');
  
          int day = cal.get(Calendar.DAY_OF_MONTH);
          if (day < 10) {
              sb.append('0');
          }
          sb.append(day);
  
          sb.append("'T'");
  
          int hour = cal.get(Calendar.HOUR_OF_DAY);
          if (hour < 10) {
              sb.append('0');
          }
          sb.append(hour).append(':');
  
          int minute = cal.get(Calendar.MINUTE);
          if (minute < 10) {
              sb.append('0');
          }
          sb.append(minute).append(':');
  
          int seconds = cal.get(Calendar.SECOND);
          if (seconds < 10) {
              sb.append('0');
          }
          sb.append(seconds);
  
          double offset = cal.get(Calendar.ZONE_OFFSET);
          if (tz.inDaylightTime(inputDate)) {
              offset += (1.0 * tz.getDSTSavings()); // add the timezone's DST
              // value (typically 1 hour
              // expressed in milliseconds)
          }
  
          offset = offset / (1000d * 60d * 60d);
          int hourOffset = (int)offset;
          double decimalVal = Math.abs(offset) - Math.abs(hourOffset);
          int minuteOffset = (int)(decimalVal * 60);
  
          if (hourOffset < 0) {
              if (hourOffset > -10) {
                  sb.append("-0");
              } else {
                  sb.append('-');
              }
              sb.append(Math.abs(hourOffset));
          } else {
              if (hourOffset < 10) {
                  sb.append("+0");
              } else {
                  sb.append("+");
              }
              sb.append(hourOffset);
          }
  
          sb.append(':');
  
          if (minuteOffset == 0) {
              sb.append("00");
          } else if (minuteOffset < 10) {
              sb.append('0').append(minuteOffset);
          } else {
              sb.append(minuteOffset);
          }
  
          return sb.toString();
      }
  
      @Override
      public TrafficMonitorResponse createTrafficMonitorResponse(Host trafficMonitor) {
          Map<String, String> tmDetails = ApiDBUtils.findHostDetailsById(trafficMonitor.getId());
          TrafficMonitorResponse response = new TrafficMonitorResponse();
          response.setId(trafficMonitor.getUuid());
          response.setIpAddress(trafficMonitor.getPrivateIpAddress());
          response.setNumRetries(tmDetails.get("numRetries"));
          response.setTimeout(tmDetails.get("timeout"));
          return response;
      }
  
      @Override
      public NicSecondaryIpResponse createSecondaryIPToNicResponse(NicSecondaryIp result) {
          NicSecondaryIpResponse response = new NicSecondaryIpResponse();
          NicVO nic = _entityMgr.findById(NicVO.class, result.getNicId());
          NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId());
          response.setId(result.getUuid());
          setResponseIpAddress(result, response);
          response.setNicId(nic.getUuid());
          response.setNwId(network.getUuid());
          response.setObjectName("nicsecondaryip");
          return response;
      }
  
      /**
       * Set the NicSecondaryIpResponse object with the IP address that is not null (IPv4 or IPv6)
       */
      public static void setResponseIpAddress(NicSecondaryIp result, NicSecondaryIpResponse response) {
          if (result.getIp4Address() != null) {
              response.setIpAddr(result.getIp4Address());
          } else if (result.getIp6Address() != null) {
              response.setIpAddr(result.getIp6Address());
          }
      }
  
      /**
       * The resulting Response attempts to be in line with what is returned from
       * @see com.cloud.api.query.dao.UserVmJoinDaoImpl#setUserVmResponse(ResponseView, UserVmResponse, UserVmJoinVO)
       */
      @Override
      public NicResponse createNicResponse(Nic result) {
          NicResponse response = new NicResponse();
          NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId());
          VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, result.getInstanceId());
          List<NicExtraDhcpOptionVO> nicExtraDhcpOptionVOs = _nicExtraDhcpOptionDao.listByNicId(result.getId());
  
          // The numbered comments are to keep track of the data returned from here and UserVmJoinDaoImpl.setUserVmResponse()
          // the data can't be identical but some tidying up/unifying might be possible
          /*1: nicUuid*/
          response.setId(result.getUuid());
          /*2: networkUuid*/
          response.setNetworkid(network.getUuid());
          /*3: vmId*/
          if (vm != null) {
              response.setVmId(vm.getUuid());
          }
  
          if (network.getTrafficType() != null) {
              /*4: trafficType*/
              response.setTrafficType(network.getTrafficType().toString());
          }
          if (network.getGuestType() != null) {
              /*5: guestType*/
              response.setType(network.getGuestType().toString());
          }
          /*6: ipAddress*/
          response.setIpaddress(result.getIPv4Address());
          /*7: gateway*/
          response.setGateway(result.getIPv4Gateway());
          /*8: netmask*/
          response.setNetmask(result.getIPv4Netmask());
          /*9: networkName*/
          response.setNetworkName(network.getName());
          /*10: macAddress*/
          response.setMacAddress(result.getMacAddress());
          /*11: IPv6Address*/
          if (result.getIPv6Address() != null) {
              response.setIp6Address(result.getIPv6Address());
          }
          /*12: IPv6Gateway*/
          if (result.getIPv6Gateway() != null) {
              response.setIp6Gateway(result.getIPv6Gateway());
          }
          /*13: IPv6Cidr*/
          if (result.getIPv6Cidr() != null) {
              response.setIp6Cidr(result.getIPv6Cidr());
          }
          /*14: deviceId*/
          response.setDeviceId(String.valueOf(result.getDeviceId()));
          /*15: broadcastURI*/
          if (result.getBroadcastUri() != null) {
              response.setBroadcastUri(result.getBroadcastUri().toString());
          }
          /*16: isolationURI*/
          if (result.getIsolationUri() != null) {
              response.setIsolationUri(result.getIsolationUri().toString());
          }
          /*17: default*/
          response.setIsDefault(result.isDefaultNic());
          if (result.getSecondaryIp()) {
              List<NicSecondaryIpVO> secondaryIps = ApiDBUtils.findNicSecondaryIps(result.getId());
              if (secondaryIps != null) {
                  List<NicSecondaryIpResponse> ipList = new ArrayList<NicSecondaryIpResponse>();
                  for (NicSecondaryIpVO ip : secondaryIps) {
                      NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse();
                      ipRes.setId(ip.getUuid());
                      setResponseIpAddress(ip, ipRes);
                      ipList.add(ipRes);
                  }
                  response.setSecondaryIps(ipList);
              }
          }
          /*18: extra dhcp options */
          List<NicExtraDhcpOptionResponse> nicExtraDhcpOptionResponses = nicExtraDhcpOptionVOs
                  .stream()
                  .map(vo -> new NicExtraDhcpOptionResponse(Dhcp.DhcpOptionCode.valueOfInt(vo.getCode()).getName(), vo.getCode(), vo.getValue()))
                  .collect(Collectors.toList());
  
          response.setExtraDhcpOptions(nicExtraDhcpOptionResponses);
  
          if (result instanceof NicVO){
              if (((NicVO)result).getNsxLogicalSwitchUuid() != null){
                  response.setNsxLogicalSwitch(((NicVO)result).getNsxLogicalSwitchUuid());
              }
              if (((NicVO)result).getNsxLogicalSwitchPortUuid() != null){
                  response.setNsxLogicalSwitchPort(((NicVO)result).getNsxLogicalSwitchPortUuid());
              }
          }
  
          UserVmJoinVO userVm =  userVmJoinDao.findById(vm.getId());
          if (userVm != null && userVm.getVpcUuid() != null) {
              response.setVpcId(userVm.getVpcUuid());
              VpcVO vpc = _entityMgr.findByUuidIncludingRemoved(VpcVO.class, userVm.getVpcUuid());
              response.setVpcName(vpc.getName());
          }
          return response;
      }
  
      @Override
      public ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb, Map<Ip, UserVm> lbInstances) {
  
          ApplicationLoadBalancerResponse lbResponse = new ApplicationLoadBalancerResponse();
          lbResponse.setId(lb.getUuid());
          lbResponse.setName(lb.getName());
          lbResponse.setDescription(lb.getDescription());
          lbResponse.setAlgorithm(lb.getAlgorithm());
          lbResponse.setForDisplay(lb.isDisplay());
          Network nw = ApiDBUtils.findNetworkById(lb.getNetworkId());
          lbResponse.setNetworkId(nw.getUuid());
          populateOwner(lbResponse, lb);
  
          if (lb.getScheme() == Scheme.Internal) {
              lbResponse.setSourceIp(lb.getSourceIp().addr());
              //TODO - create the view for the load balancer rule to reflect the network uuid
              Network network = ApiDBUtils.findNetworkById(lb.getNetworkId());
              lbResponse.setSourceIpNetworkId(network.getUuid());
          } else {
              //for public, populate the ip information from the ip address
              IpAddress publicIp = ApiDBUtils.findIpAddressById(lb.getSourceIpAddressId());
              lbResponse.setSourceIp(publicIp.getAddress().addr());
              Network ntwk = ApiDBUtils.findNetworkById(publicIp.getNetworkId());
              lbResponse.setSourceIpNetworkId(ntwk.getUuid());
          }
  
          //set load balancer rules information (only one rule per load balancer in this release)
          List<ApplicationLoadBalancerRuleResponse> ruleResponses = new ArrayList<ApplicationLoadBalancerRuleResponse>();
          ApplicationLoadBalancerRuleResponse ruleResponse = new ApplicationLoadBalancerRuleResponse();
          ruleResponse.setInstancePort(lb.getDefaultPortStart());
          ruleResponse.setSourcePort(lb.getSourcePortStart());
          FirewallRule.State stateToSet = lb.getState();
          if (stateToSet.equals(FirewallRule.State.Revoke)) {
              stateToSet = FirewallRule.State.Deleting;
          }
          ruleResponse.setState(stateToSet.toString());
          ruleResponse.setObjectName("loadbalancerrule");
          ruleResponses.add(ruleResponse);
          lbResponse.setLbRules(ruleResponses);
  
          //set Lb instances information
          List<ApplicationLoadBalancerInstanceResponse> instanceResponses = new ArrayList<ApplicationLoadBalancerInstanceResponse>();
          for (Map.Entry<Ip,UserVm> entry : lbInstances.entrySet()) {
              Ip ip = entry.getKey();
              UserVm vm = entry.getValue();
              ApplicationLoadBalancerInstanceResponse instanceResponse = new ApplicationLoadBalancerInstanceResponse();
              instanceResponse.setIpAddress(ip.addr());
              instanceResponse.setId(vm.getUuid());
              instanceResponse.setName(vm.getInstanceName());
              instanceResponse.setObjectName("loadbalancerinstance");
              instanceResponses.add(instanceResponse);
          }
  
          lbResponse.setLbInstances(instanceResponses);
  
          //set tag information
          List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.LoadBalancer, lb.getId());
          List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
          for (ResourceTag tag : tags) {
              ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
              CollectionUtils.addIgnoreNull(tagResponses,tagResponse);
          }
          lbResponse.setTags(tagResponses);
  
          lbResponse.setObjectName("loadbalancer");
          return lbResponse;
      }
  
      @Override
      public AffinityGroupResponse createAffinityGroupResponse(AffinityGroup group) {
  
          AffinityGroupResponse response = new AffinityGroupResponse();
  
          response.setId(group.getUuid());
          response.setName(group.getName());
          response.setType(group.getType());
          response.setDescription(group.getDescription());
          populateOwner(response, group);
  
          response.setObjectName("affinitygroup");
          return response;
      }
  
      @Override
      public Long getAffinityGroupId(String groupName, long accountId) {
          AffinityGroup ag = ApiDBUtils.getAffinityGroup(groupName, accountId);
          if (ag == null) {
              return null;
          } else {
              return ag.getId();
          }
      }
  
  
      @Override
      public PortableIpRangeResponse createPortableIPRangeResponse(PortableIpRange ipRange) {
          PortableIpRangeResponse response = new PortableIpRangeResponse();
          response.setId(ipRange.getUuid());
          String ipRangeStr = ipRange.getIpRange();
          if (ipRangeStr != null) {
              String[] range = ipRangeStr.split("-");
              response.setStartIp(range[0]);
              response.setEndIp(range[1]);
          }
          response.setVlan(ipRange.getVlanTag());
          response.setGateway(ipRange.getGateway());
          response.setNetmask(ipRange.getNetmask());
          response.setRegionId(ipRange.getRegionId());
          response.setObjectName("portableiprange");
          return response;
      }
  
      @Override
      public PortableIpResponse createPortableIPResponse(PortableIp portableIp) {
          PortableIpResponse response = new PortableIpResponse();
          response.setAddress(portableIp.getAddress());
          Long accountId =  portableIp.getAllocatedInDomainId();
          if (accountId != null) {
              Account account = ApiDBUtils.findAccountById(accountId);
              response.setAllocatedToAccountId(account.getAccountName());
              Domain domain = ApiDBUtils.findDomainById(account.getDomainId());
              response.setAllocatedInDomainId(domain.getUuid());
          }
  
          response.setAllocatedTime(portableIp.getAllocatedTime());
  
          if (portableIp.getAssociatedDataCenterId() != null) {
              DataCenter zone = ApiDBUtils.findZoneById(portableIp.getAssociatedDataCenterId());
              if (zone != null) {
                  response.setAssociatedDataCenterId(zone.getUuid());
              }
          }
  
          if (portableIp.getPhysicalNetworkId() != null) {
              PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(portableIp.getPhysicalNetworkId());
              if (pnw != null) {
                  response.setPhysicalNetworkId(pnw.getUuid());
              }
          }
  
          if (portableIp.getAssociatedWithNetworkId() != null) {
              Network ntwk = ApiDBUtils.findNetworkById(portableIp.getAssociatedWithNetworkId());
              if (ntwk != null) {
                  response.setAssociatedWithNetworkId(ntwk.getUuid());
              }
          }
  
          if (portableIp.getAssociatedWithVpcId() != null) {
              Vpc vpc = ApiDBUtils.findVpcById(portableIp.getAssociatedWithVpcId());
              if (vpc != null) {
                  response.setAssociatedWithVpcId(vpc.getUuid());
              }
          }
  
          response.setState(portableIp.getState().name());
          response.setObjectName("portableip");
          return response;
      }
  
      @Override
      public InternalLoadBalancerElementResponse createInternalLbElementResponse(VirtualRouterProvider result) {
          if (result.getType() != VirtualRouterProvider.Type.InternalLbVm) {
              return null;
          }
          InternalLoadBalancerElementResponse response = new InternalLoadBalancerElementResponse();
          response.setId(result.getUuid());
          PhysicalNetworkServiceProvider nsp = ApiDBUtils.findPhysicalNetworkServiceProviderById(result.getNspId());
          if (nsp != null) {
              response.setNspId(nsp.getUuid());
          }
          response.setEnabled(result.isEnabled());
  
          response.setObjectName("internalloadbalancerelement");
          return response;
      }
  
      @Override
      public IsolationMethodResponse createIsolationMethodResponse(IsolationType method) {
          IsolationMethodResponse response = new IsolationMethodResponse();
          response.setIsolationMethodName(method.toString());
          response.setObjectName("isolationmethod");
          return response;
      }
  
      @Override
      public NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL) {
          NetworkACLResponse response = new NetworkACLResponse();
          response.setId(networkACL.getUuid());
          response.setName(networkACL.getName());
          response.setDescription(networkACL.getDescription());
          response.setForDisplay(networkACL.isDisplay());
          Vpc vpc = ApiDBUtils.findVpcById(networkACL.getVpcId());
          if (vpc != null) {
              response.setVpcId(vpc.getUuid());
              response.setVpcName(vpc.getName());
          }
          response.setObjectName("networkacllist");
          return response;
      }
  
      @Override
      public ListResponse<UpgradeRouterTemplateResponse> createUpgradeRouterTemplateResponse(List<Long> jobIds) {
          ListResponse<UpgradeRouterTemplateResponse> response = new ListResponse<UpgradeRouterTemplateResponse>();
          List<UpgradeRouterTemplateResponse> responses = new ArrayList<UpgradeRouterTemplateResponse>();
          for (Long jobId : jobIds) {
              UpgradeRouterTemplateResponse routerResponse = new UpgradeRouterTemplateResponse();
              AsyncJob job = _entityMgr.findById(AsyncJob.class, jobId);
              routerResponse.setAsyncJobId((job.getUuid()));
              routerResponse.setObjectName("asyncjobs");
              responses.add(routerResponse);
          }
          response.setResponses(responses);
          return response;
      }
  
      @Override
      public SSHKeyPairResponse createSSHKeyPairResponse(SSHKeyPair sshkeyPair, boolean privatekey) {
          SSHKeyPairResponse response = new SSHKeyPairResponse(sshkeyPair.getUuid(), sshkeyPair.getName(), sshkeyPair.getFingerprint());
          if (privatekey) {
              response = new CreateSSHKeyPairResponse(sshkeyPair.getUuid(), sshkeyPair.getName(),
                      sshkeyPair.getFingerprint(), sshkeyPair.getPrivateKey());
          }
          Account account = ApiDBUtils.findAccountById(sshkeyPair.getAccountId());
          if (account.getType() == Account.Type.PROJECT) {
              Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getAccountId());
              response.setProjectId(project.getUuid());
              response.setProjectName(project.getName());
          } else {
              response.setAccountName(account.getAccountName());
          }
          Domain domain = ApiDBUtils.findDomainById(sshkeyPair.getDomainId());
          response.setDomainId(domain.getUuid());
          response.setDomainName(domain.getName());
          response.setHasAnnotation(annotationDao.hasAnnotations(sshkeyPair.getUuid(), AnnotationService.EntityType.SSH_KEYPAIR.name(),
                  _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
          return response;
      }
  
      @Override
      public UserDataResponse createUserDataResponse(UserData userData) {
          UserDataResponse response = new UserDataResponse(userData.getUuid(), userData.getName(), userData.getUserData(), userData.getParams());
          populateOwner(response, userData);
          response.setHasAnnotation(annotationDao.hasAnnotations(userData.getUuid(), AnnotationService.EntityType.USER_DATA.name(),
                  _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
          return response;
      }
  
      @Override
      public BackupScheduleResponse createBackupScheduleResponse(BackupSchedule schedule) {
          return ApiDBUtils.newBackupScheduleResponse(schedule);
      }
  
      @Override
      public BackupOfferingResponse createBackupOfferingResponse(BackupOffering policy) {
          return ApiDBUtils.newBackupOfferingResponse(policy);
      }
  
      public ManagementServerResponse createManagementResponse(ManagementServerHost mgmt) {
          ManagementServerResponse response = new ManagementServerResponse();
          response.setId(mgmt.getUuid());
          response.setName(mgmt.getName());
          response.setVersion(mgmt.getVersion());
          response.setState(mgmt.getState());
          return response;
      }
  
      @Override
      public List<RouterHealthCheckResultResponse> createHealthCheckResponse(VirtualMachine router, List<RouterHealthCheckResult> healthCheckResults) {
          List<RouterHealthCheckResultResponse> responses = new ArrayList<>(healthCheckResults.size());
          for (RouterHealthCheckResult hcResult : healthCheckResults) {
              RouterHealthCheckResultResponse healthCheckResponse = new RouterHealthCheckResultResponse();
              healthCheckResponse.setObjectName("routerhealthchecks");
              healthCheckResponse.setCheckName(hcResult.getCheckName());
              healthCheckResponse.setCheckType(hcResult.getCheckType());
              switch (hcResult.getCheckResult()) {
                  case SUCCESS:
                      healthCheckResponse.setResult(true);
                      break;
                  case FAILED:
                      healthCheckResponse.setResult(false);
                      break;
                  default:
                      // no result if not definite
              }
              healthCheckResponse.setState(hcResult.getCheckResult());
              healthCheckResponse.setLastUpdated(hcResult.getLastUpdateTime());
              healthCheckResponse.setDetails(hcResult.getParsedCheckDetails());
              responses.add(healthCheckResponse);
          }
          return responses;
      }
  
      @Override
      public RollingMaintenanceResponse createRollingMaintenanceResponse(Boolean success, String details, List<RollingMaintenanceManager.HostUpdated> hostsUpdated, List<RollingMaintenanceManager.HostSkipped> hostsSkipped) {
          RollingMaintenanceResponse response = new RollingMaintenanceResponse(success, details);
          List<RollingMaintenanceHostUpdatedResponse> updated = new ArrayList<>();
          for (RollingMaintenanceManager.HostUpdated h : hostsUpdated) {
              RollingMaintenanceHostUpdatedResponse r = new RollingMaintenanceHostUpdatedResponse();
              r.setHostId(h.getHost().getUuid());
              r.setHostName(h.getHost().getName());
              r.setStartDate(getDateStringInternal(h.getStart()));
              r.setEndDate(getDateStringInternal(h.getEnd()));
              r.setOutput(h.getOutputMsg());
              updated.add(r);
          }
          List<RollingMaintenanceHostSkippedResponse> skipped = new ArrayList<>();
          for (RollingMaintenanceManager.HostSkipped h : hostsSkipped) {
              RollingMaintenanceHostSkippedResponse r = new RollingMaintenanceHostSkippedResponse();
              r.setHostId(h.getHost().getUuid());
              r.setHostName(h.getHost().getName());
              r.setReason(h.getReason());
              skipped.add(r);
          }
          response.setUpdatedHosts(updated);
          response.setSkippedHosts(skipped);
          response.setObjectName("rollingmaintenance");
          return response;
      }
  
      @Override
      public ResourceIconResponse createResourceIconResponse(ResourceIcon resourceIcon) {
          return  ApiDBUtils.newResourceIconResponse(resourceIcon);
      }
  
      @Override
      public GuestVlanResponse createGuestVlanResponse(GuestVlan guestVlan) {
          GuestVlanResponse guestVlanResponse = new GuestVlanResponse();
  
          Account owner = null;
          if (guestVlan.getAccountId() != null) {
              owner = ApiDBUtils.findAccountById(guestVlan.getAccountId());
          } else if (guestVlan.getAccountGuestVlanMapId() != null) {
              Long accountId = ApiDBUtils.getAccountIdForGuestVlan(guestVlan.getAccountGuestVlanMapId());
              owner = ApiDBUtils.findAccountById(accountId);
          }
          if (owner != null) {
              populateAccount(guestVlanResponse, owner.getId());
              populateDomain(guestVlanResponse, owner.getDomainId());
          }
          guestVlanResponse.setId(guestVlan.getId());
          guestVlanResponse.setGuestVlan(guestVlan.getVnet());
          DataCenterVO zone = ApiDBUtils.findZoneById(guestVlan.getDataCenterId());
          if (zone != null) {
              guestVlanResponse.setZoneId(zone.getUuid());
              guestVlanResponse.setZoneName(zone.getName());
          }
          PhysicalNetworkVO pnw = ApiDBUtils.findPhysicalNetworkById(guestVlan.getPhysicalNetworkId());
          if (pnw != null) {
              guestVlanResponse.setPhysicalNetworkId(pnw.getUuid());
              guestVlanResponse.setPhysicalNetworkName(pnw.getName());
          }
          if (guestVlan.getAccountGuestVlanMapId() != null) {
              guestVlanResponse.setDedicated(true);
          } else {
              guestVlanResponse.setDedicated(false);
          }
          if (guestVlan.getTakenAt() != null) {
              guestVlanResponse.setAllocationState("Allocated");
              guestVlanResponse.setTaken(guestVlan.getTakenAt());
          } else {
              guestVlanResponse.setAllocationState("Free");
          }
  
          List<NetworkVO> networks = networkDao.listByZoneAndUriAndGuestType(guestVlan.getDataCenterId(), guestVlan.getVnet(), null);
          List<NetworkResponse> networkResponses = new ArrayList<NetworkResponse>();
          for (Network network : networks) {
              NetworkResponse ntwkRsp = createNetworkResponse(ResponseView.Full, network);
              networkResponses.add(ntwkRsp);
          }
          guestVlanResponse.setNetworks(networkResponses);
  
          return guestVlanResponse;
      }
  
      @Override
      public NetworkPermissionsResponse createNetworkPermissionsResponse(NetworkPermission permission) {
          Long networkOwnerDomain = null;
          Network network = ApiDBUtils.findNetworkById(permission.getNetworkId());
  
          NetworkPermissionsResponse response = new NetworkPermissionsResponse();
          response.setNetworkId(network.getUuid());
  
          Account networkOwner = ApiDBUtils.findAccountById(network.getAccountId());
          if (networkOwner != null) {
              networkOwnerDomain = networkOwner.getDomainId();
              if (networkOwnerDomain != null) {
                  Domain domain = ApiDBUtils.findDomainById(networkOwnerDomain);
                  if (domain != null) {
                      response.setDomainId(domain.getUuid());
                      response.setDomainName(domain.getName());
                  }
              }
          }
  
          Account account = ApiDBUtils.findAccountById(permission.getAccountId());
          response.setAccountName(account.getName());
          response.setAccountId(account.getUuid());
          if (account.getType() == Account.Type.PROJECT) {
              // convert account to projectIds
              Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
  
              if (project.getUuid() != null && !project.getUuid().isEmpty()) {
                  response.setProjectId(project.getUuid());
              } else {
                  response.setProjectId(String.valueOf(project.getId()));
              }
              response.setProjectName(project.getName());
          }
  
          response.setObjectName("networkpermission");
          return response;
      }
  
      protected void handleCertificateResponse(String certStr, DirectDownloadCertificateResponse response) {
          try {
              Certificate cert = CertificateHelper.buildCertificate(certStr);
              if (cert instanceof X509CertImpl) {
                  X509CertImpl certificate = (X509CertImpl) cert;
                  response.setVersion(String.valueOf(certificate.getVersion()));
                  response.setSubject(certificate.getSubjectDN().toString());
                  response.setIssuer(certificate.getIssuerDN().toString());
                  response.setSerialNum(certificate.getSerialNumberObject().toString());
                  response.setValidity(String.format("From: [%s] - To: [%s]", certificate.getNotBefore(), certificate.getNotAfter()));
              }
          } catch (CertificateException e) {
              logger.error("Error parsing direct download certificate: " + certStr, e);
          }
      }
  
      @Override
      public DirectDownloadCertificateResponse createDirectDownloadCertificateResponse(DirectDownloadCertificate certificate) {
          DirectDownloadCertificateResponse response = new DirectDownloadCertificateResponse();
          DataCenterVO datacenter = ApiDBUtils.findZoneById(certificate.getZoneId());
          if (datacenter != null) {
              response.setZoneId(datacenter.getUuid());
              response.setZoneName(datacenter.getName());
          }
          response.setId(certificate.getUuid());
          response.setAlias(certificate.getAlias());
          handleCertificateResponse(certificate.getCertificate(), response);
          response.setHypervisor(certificate.getHypervisorType().getHypervisorDisplayName());
          response.setObjectName("directdownloadcertificate");
          return response;
      }
  
      @Override
      public List<DirectDownloadCertificateHostStatusResponse> createDirectDownloadCertificateHostMapResponse(List<DirectDownloadCertificateHostMap> hostMappings) {
          if (CollectionUtils.isEmpty(hostMappings)) {
              return new ArrayList<>();
          }
          List<DirectDownloadCertificateHostStatusResponse> responses = new ArrayList<>(hostMappings.size());
          for (DirectDownloadCertificateHostMap map : hostMappings) {
              DirectDownloadCertificateHostStatusResponse response = new DirectDownloadCertificateHostStatusResponse();
              HostVO host = ApiDBUtils.findHostById(map.getHostId());
              if (host != null) {
                  response.setHostId(host.getUuid());
                  response.setHostName(host.getName());
              }
              response.setStatus(map.isRevoked() ? CertificateStatus.REVOKED.name() : CertificateStatus.UPLOADED.name());
              response.setObjectName("directdownloadcertificatehoststatus");
              responses.add(response);
          }
          return responses;
      }
  
      private DirectDownloadCertificateHostStatusResponse getDirectDownloadHostStatusResponseInternal(Host host, CertificateStatus status, String details) {
          DirectDownloadCertificateHostStatusResponse response = new DirectDownloadCertificateHostStatusResponse();
          if (host != null) {
              response.setHostId(host.getUuid());
              response.setHostName(host.getName());
          }
          response.setStatus(status.name());
          response.setDetails(details);
          response.setObjectName("directdownloadcertificatehoststatus");
          return response;
      }
  
      @Override
      public DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateHostStatusResponse(DirectDownloadManager.HostCertificateStatus hostStatus) {
          Host host = hostStatus.getHost();
          CertificateStatus status = hostStatus.getStatus();
          return getDirectDownloadHostStatusResponseInternal(host, status, hostStatus.getDetails());
      }
  
      @Override
      public DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateProvisionResponse(Long certificateId, Long hostId, Pair<Boolean, String> result) {
          HostVO host = ApiDBUtils.findHostById(hostId);
          CertificateStatus status = result != null && result.first() ? CertificateStatus.UPLOADED : CertificateStatus.FAILED;
          return getDirectDownloadHostStatusResponseInternal(host, status, result != null ? result.second() : "provision certificate failure");
      }
  
      @Override
      public FirewallResponse createIpv6FirewallRuleResponse(FirewallRule fwRule) {
          FirewallResponse response = new FirewallResponse();
  
          response.setId(fwRule.getUuid());
          response.setProtocol(fwRule.getProtocol());
          List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId());
          response.setCidrList(StringUtils.join(cidrs, ","));
          List<String> destinationCidrs = ApiDBUtils.findFirewallDestCidrs(fwRule.getId());
          response.setDestCidr(StringUtils.join(destinationCidrs, ","));
          response.setTrafficType(fwRule.getTrafficType().toString());
          response.setProtocol(fwRule.getProtocol());
          response.setStartPort(fwRule.getSourcePortStart());
          response.setEndPort(fwRule.getSourcePortEnd());
          response.setIcmpCode(fwRule.getIcmpCode());
          response.setIcmpType(fwRule.getIcmpType());
  
          Network network = ApiDBUtils.findNetworkById(fwRule.getNetworkId());
          response.setNetworkId(network.getUuid());
  
          FirewallRule.State state = fwRule.getState();
          String stateToSet = state.toString();
          if (state.equals(FirewallRule.State.Revoke)) {
              stateToSet = "Deleting";
          }
  
          response.setForDisplay(fwRule.isDisplay());
  
          // set tag information
          List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.FirewallRule, fwRule.getId());
          List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
          for (ResourceTag tag : tags) {
              ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
              CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
          }
          response.setTags(tagResponses);
  
          response.setState(stateToSet);
          response.setObjectName("firewallrule");
          return response;
      }
  
      @Override
      public UnmanagedInstanceResponse createUnmanagedInstanceResponse(UnmanagedInstanceTO instance, Cluster cluster, Host host) {
          UnmanagedInstanceResponse response = new UnmanagedInstanceResponse();
          response.setName(instance.getName());
          if (cluster != null) {
              response.setClusterId(cluster.getUuid());
              response.setClusterName(cluster.getName());
          } else if (instance.getClusterName() != null) {
              response.setClusterName(instance.getClusterName());
          }
          if (host != null) {
              response.setHostId(host.getUuid());
              response.setHostName(host.getName());
          } else if (instance.getHostName() != null) {
              response.setHostName(instance.getHostName());
          }
          response.setPowerState((instance.getPowerState() != null)? instance.getPowerState().toString() : UnmanagedInstanceTO.PowerState.PowerUnknown.toString());
          response.setCpuCores(instance.getCpuCores());
          response.setCpuSpeed(instance.getCpuSpeed());
          response.setCpuCoresPerSocket(instance.getCpuCoresPerSocket());
          response.setMemory(instance.getMemory());
          response.setOperatingSystemId(instance.getOperatingSystemId());
          response.setOperatingSystem(instance.getOperatingSystem());
          response.setBootMode(instance.getBootMode());
          response.setBootType(instance.getBootType());
          response.setObjectName("unmanagedinstance");
  
          if (instance.getDisks() != null) {
              for (UnmanagedInstanceTO.Disk disk : instance.getDisks()) {
                  UnmanagedInstanceDiskResponse diskResponse = new UnmanagedInstanceDiskResponse();
                  diskResponse.setDiskId(disk.getDiskId());
                  if (StringUtils.isNotEmpty(disk.getLabel())) {
                      diskResponse.setLabel(disk.getLabel());
                  }
                  diskResponse.setCapacity(disk.getCapacity());
                  diskResponse.setController(disk.getController());
                  diskResponse.setControllerUnit(disk.getControllerUnit());
                  diskResponse.setPosition(disk.getPosition());
                  diskResponse.setImagePath(disk.getImagePath());
                  diskResponse.setDatastoreName(disk.getDatastoreName());
                  diskResponse.setDatastoreHost(disk.getDatastoreHost());
                  diskResponse.setDatastorePath(disk.getDatastorePath());
                  diskResponse.setDatastoreType(disk.getDatastoreType());
                  response.addDisk(diskResponse);
              }
          }
  
          if (instance.getNics() != null) {
              for (UnmanagedInstanceTO.Nic nic : instance.getNics()) {
                  NicResponse nicResponse = new NicResponse();
                  nicResponse.setId(nic.getNicId());
                  nicResponse.setNetworkName(nic.getNetwork());
                  nicResponse.setMacAddress(nic.getMacAddress());
                  if (StringUtils.isNotEmpty(nic.getAdapterType())) {
                      nicResponse.setAdapterType(nic.getAdapterType());
                  }
                  if (!CollectionUtils.isEmpty(nic.getIpAddress())) {
                      nicResponse.setIpAddresses(nic.getIpAddress());
                  }
                  nicResponse.setVlanId(nic.getVlan());
                  nicResponse.setIsolatedPvlanId(nic.getPvlan());
                  nicResponse.setIsolatedPvlanType(nic.getPvlanType());
                  response.addNic(nicResponse);
              }
          }
          return response;
      }
  
      @Override
      public SecondaryStorageHeuristicsResponse createSecondaryStorageSelectorResponse(Heuristic heuristic) {
          String zoneUuid = ApiDBUtils.findZoneById(heuristic.getZoneId()).getUuid();
          SecondaryStorageHeuristicsResponse secondaryStorageHeuristicsResponse = new SecondaryStorageHeuristicsResponse(heuristic.getUuid(), heuristic.getName(),
                  heuristic.getDescription(), zoneUuid, heuristic.getType(), heuristic.getHeuristicRule(), heuristic.getCreated(), heuristic.getRemoved());
          secondaryStorageHeuristicsResponse.setResponseName("secondarystorageheuristics");
  
          return secondaryStorageHeuristicsResponse;
      }
  
      @Override
      public IpQuarantineResponse createQuarantinedIpsResponse(PublicIpQuarantine quarantinedIp) {
          IpQuarantineResponse quarantinedIpsResponse = new IpQuarantineResponse();
          String ipAddress = userIpAddressDao.findById(quarantinedIp.getPublicIpAddressId()).getAddress().toString();
          Account previousOwner = _accountMgr.getAccount(quarantinedIp.getPreviousOwnerId());
  
          quarantinedIpsResponse.setId(quarantinedIp.getUuid());
          quarantinedIpsResponse.setPublicIpAddress(ipAddress);
          quarantinedIpsResponse.setPreviousOwnerId(previousOwner.getUuid());
          quarantinedIpsResponse.setPreviousOwnerName(previousOwner.getName());
          quarantinedIpsResponse.setCreated(quarantinedIp.getCreated());
          quarantinedIpsResponse.setRemoved(quarantinedIp.getRemoved());
          quarantinedIpsResponse.setEndDate(quarantinedIp.getEndDate());
          quarantinedIpsResponse.setRemovalReason(quarantinedIp.getRemovalReason());
          if (quarantinedIp.getRemoverAccountId() != null) {
              Account removerAccount = _accountMgr.getAccount(quarantinedIp.getRemoverAccountId());
              quarantinedIpsResponse.setRemoverAccountId(removerAccount.getUuid());
          }
          quarantinedIpsResponse.setResponseName("quarantinedip");
  
          return quarantinedIpsResponse;
      }
  
      public ObjectStoreResponse createObjectStoreResponse(ObjectStore os) {
          ObjectStoreResponse objectStoreResponse = new ObjectStoreResponse();
          objectStoreResponse.setId(os.getUuid());
          objectStoreResponse.setName(os.getName());
          objectStoreResponse.setProviderName(os.getProviderName());
          objectStoreResponse.setObjectName("objectstore");
          return objectStoreResponse;
      }
  
      @Override
      public BucketResponse createBucketResponse(Bucket bucket) {
          BucketResponse bucketResponse = new BucketResponse();
          bucketResponse.setName(bucket.getName());
          bucketResponse.setId(bucket.getUuid());
          bucketResponse.setCreated(bucket.getCreated());
          bucketResponse.setState(bucket.getState());
          bucketResponse.setSize(bucket.getSize());
          if(bucket.getQuota() != null) {
              bucketResponse.setQuota(bucket.getQuota());
          }
          bucketResponse.setVersioning(bucket.isVersioning());
          bucketResponse.setEncryption(bucket.isEncryption());
          bucketResponse.setObjectLock(bucket.isObjectLock());
          bucketResponse.setPolicy(bucket.getPolicy());
          bucketResponse.setBucketURL(bucket.getBucketURL());
          bucketResponse.setAccessKey(bucket.getAccessKey());
          bucketResponse.setSecretKey(bucket.getSecretKey());
          ObjectStoreVO objectStoreVO = _objectStoreDao.findById(bucket.getObjectStoreId());
          bucketResponse.setObjectStoragePoolId(objectStoreVO.getUuid());
          bucketResponse.setObjectStoragePool(objectStoreVO.getName());
          bucketResponse.setObjectName("bucket");
          bucketResponse.setProvider(objectStoreVO.getProviderName());
          populateAccount(bucketResponse, bucket.getAccountId());
          return bucketResponse;
      }
  
      @Override
      public ASNRangeResponse createASNumberRangeResponse(ASNumberRange asnRange) {
          ASNRangeResponse response = new ASNRangeResponse();
          response.setId(asnRange.getUuid());
          DataCenterVO zone = ApiDBUtils.findZoneById(asnRange.getDataCenterId());
          if (zone != null) {
              response.setZoneId(zone.getUuid());
          }
          response.setStartASNumber(asnRange.getStartASNumber());
          response.setEndASNumber(asnRange.getEndASNumber());
          response.setCreated(asnRange.getCreated());
          response.setObjectName("asnumberrange");
          return response;
      }
  
      @Override
      public ASNumberResponse createASNumberResponse(ASNumber asn) {
          ASNumberResponse response = new ASNumberResponse();
          response.setId(asn.getUuid());
          if (asn.getAccountId() != null) {
              Account account = ApiDBUtils.findAccountById(asn.getAccountId());
              response.setAccountId(account.getUuid());
              response.setAccountName(account.getAccountName());
          }
          if (asn.getDomainId() != null) {
              DomainVO domain = ApiDBUtils.findDomainById(asn.getDomainId());
              response.setDomainId(domain.getUuid());
              response.setDomainName(domain.getName());
          }
          DataCenterVO zone = ApiDBUtils.findZoneById(asn.getDataCenterId());
          response.setZoneId(zone.getUuid());
          response.setZoneName(zone.getName());
          response.setAsNumber(asn.getAsNumber());
          ASNumberRangeVO range = asNumberRangeDao.findById(asn.getAsNumberRangeId());
          if (Objects.nonNull(range)) {
              response.setAsNumberRangeId(range.getUuid());
              String rangeText = String.format("%s-%s", range.getStartASNumber(), range.getEndASNumber());
              response.setAsNumberRange(rangeText);
          } else {
              logger.info("Range is null for AS number: "+ asn.getAsNumber());
          }
          response.setAllocated(asn.getAllocatedTime());
          response.setAllocationState(asn.isAllocated() ? "Allocated" : "Free");
          if (asn.getVpcId() != null) {
              VpcVO vpc = ApiDBUtils.findVpcById(asn.getVpcId());
              response.setVpcId(vpc.getUuid());
              response.setVpcName(vpc.getName());
          } else if (asn.getNetworkId() != null) {
              NetworkVO network = ApiDBUtils.findNetworkById(asn.getNetworkId());
              response.setAssociatedNetworkId(network.getUuid());
              response.setAssociatedNetworkName(network.getName());
          }
          response.setCreated(asn.getCreated());
          response.setObjectName("asnumber");
          return response;
      }
  
      @Override
      public BackupRepositoryResponse createBackupRepositoryResponse(BackupRepository backupRepository) {
          BackupRepositoryResponse response = new BackupRepositoryResponse();
          response.setName(backupRepository.getName());
          response.setId(backupRepository.getUuid());
          response.setCreated(backupRepository.getCreated());
          response.setAddress(backupRepository.getAddress());
          response.setProviderName(backupRepository.getProvider());
          response.setType(backupRepository.getType());
          response.setCapacityBytes(backupRepository.getCapacityBytes());
          response.setCrossZoneInstanceCreation(backupRepository.crossZoneInstanceCreationEnabled());
          response.setObjectName("backuprepository");
          DataCenter zone = ApiDBUtils.findZoneById(backupRepository.getZoneId());
          if (zone != null) {
              response.setZoneId(zone.getUuid());
              response.setZoneName(zone.getName());
          }
          return response;
      }
  
      @Override
      public SharedFSResponse createSharedFSResponse(ResponseView view, SharedFS sharedFS) {
          SharedFSJoinVO sharedFSView = ApiDBUtils.newSharedFSView(sharedFS);
          return ApiDBUtils.newSharedFSResponse(view, sharedFSView);
      }
  protected Map<String, ResourceIcon> getResourceIconsUsingOsCategory(List<TemplateResponse> responses) {
          Set<Long> guestOsCategoryIds = responses.stream().map(TemplateResponse::getOsTypeCategoryId).collect(Collectors.toSet());
          Map<Long, ResourceIcon> guestOsCategoryIcons =
                  resourceIconManager.getByResourceTypeAndIds(ResourceTag.ResourceObjectType.GuestOsCategory,
                          guestOsCategoryIds);
          Map<String, ResourceIcon> vmIcons = new HashMap<>();
          for (TemplateResponse response : responses) {
              vmIcons.put(response.getId(), guestOsCategoryIcons.get(response.getOsTypeCategoryId()));
          }
          return vmIcons;
      }
  
      @Override
      public void updateTemplateIsoResponsesForIcons(List<TemplateResponse> responses,
                     ResourceTag.ResourceObjectType type) {
          if (CollectionUtils.isEmpty(responses)) {
              return;
          }
          Set<String> uuids = responses.stream().map(TemplateResponse::getId).collect(Collectors.toSet());
          Map<String, ResourceIcon> templateIcons = resourceIconManager.getByResourceTypeAndUuids(type, uuids);
          List<TemplateResponse> noTemplateIconResponses = responses
                  .stream()
                  .filter(r -> !templateIcons.containsKey(r.getId()))
                  .collect(Collectors.toList());
          templateIcons.putAll(getResourceIconsUsingOsCategory(noTemplateIconResponses));
          for (TemplateResponse response : responses) {
              ResourceIcon icon = templateIcons.get(response.getId());
              if (icon == null) {
                  continue;
              }
              ResourceIconResponse iconResponse = createResourceIconResponse(icon);
              response.setResourceIconResponse(iconResponse);
          }
      }
      @Override
      public GuiThemeResponse createGuiThemeResponse(GuiThemeJoin guiThemeJoin) {
          GuiThemeResponse guiThemeResponse = new GuiThemeResponse();
  
          Long callerId = CallContext.current().getCallingAccount().getAccountId();
          if (callerId != Account.ACCOUNT_ID_SYSTEM && _accountMgr.isRootAdmin(callerId)) {
              guiThemeResponse.setId(guiThemeJoin.getUuid());
              guiThemeResponse.setName(guiThemeJoin.getName());
              guiThemeResponse.setDescription(guiThemeJoin.getDescription());
              guiThemeResponse.setCommonNames(guiThemeJoin.getCommonNames());
              guiThemeResponse.setDomainIds(guiThemeJoin.getDomains());
              guiThemeResponse.setRecursiveDomains(guiThemeJoin.isRecursiveDomains());
              guiThemeResponse.setAccountIds(guiThemeJoin.getAccounts());
              guiThemeResponse.setPublic(guiThemeJoin.getIsPublic());
              guiThemeResponse.setCreated(guiThemeJoin.getCreated());
              guiThemeResponse.setRemoved(guiThemeJoin.getRemoved());
          }
  
          guiThemeResponse.setJsonConfiguration(guiThemeJoin.getJsonConfiguration());
          guiThemeResponse.setCss(guiThemeJoin.getCss());
          guiThemeResponse.setResponseName("guithemes");
  
          return guiThemeResponse;
      }
  
      private void populateDomainFieldsOnConsoleSessionResponse(ConsoleSession consoleSession, ConsoleSessionResponse consoleSessionResponse) {
          Domain domain = ApiDBUtils.findDomainById(consoleSession.getDomainId());
          if (domain != null) {
              consoleSessionResponse.setDomain(domain.getName());
              consoleSessionResponse.setDomainPath(domain.getPath());
              consoleSessionResponse.setDomainId(domain.getUuid());
          }
      }
  
      private void populateUserFieldsOnConsoleSessionResponse(ConsoleSession consoleSession, ConsoleSessionResponse consoleSessionResponse) {
          User user = findUserById(consoleSession.getUserId());
          if (user != null) {
              consoleSessionResponse.setUser(user.getUsername());
              consoleSessionResponse.setUserId(user.getUuid());
          }
      }
  
      private void populateAccountFieldsOnConsoleSessionResponse(ConsoleSession consoleSession, ConsoleSessionResponse consoleSessionResponse) {
          Account account = ApiDBUtils.findAccountById(consoleSession.getAccountId());
          if (account != null) {
              consoleSessionResponse.setAccount(account.getAccountName());
              consoleSessionResponse.setAccountId(account.getUuid());
          }
      }
  
      private void populateHostFieldsOnConsoleSessionResponse(ConsoleSession consoleSession, ConsoleSessionResponse consoleSessionResponse) {
          Host host = findHostById(consoleSession.getHostId());
          if (host != null) {
              consoleSessionResponse.setHostId(host.getUuid());
              consoleSessionResponse.setHostName(host.getName());
          }
      }
  
      private void populateInstanceFieldsOnConsoleSessionResponse(ConsoleSession consoleSession, ConsoleSessionResponse consoleSessionResponse) {
          VMInstanceVO instance = ApiDBUtils.findVMInstanceById(consoleSession.getInstanceId());
          if (instance != null) {
              consoleSessionResponse.setVmId(instance.getUuid());
              consoleSessionResponse.setVmName(instance.getInstanceName());
          }
      }
  
      @Override
      public ConsoleSessionResponse createConsoleSessionResponse(ConsoleSession consoleSession, ResponseView responseView) {
          ConsoleSessionResponse consoleSessionResponse = new ConsoleSessionResponse();
          if (consoleSession == null) {
              return consoleSessionResponse;
          }
  
          consoleSessionResponse.setId(consoleSession.getUuid());
          consoleSessionResponse.setCreated(consoleSession.getCreated());
          consoleSessionResponse.setAcquired(consoleSession.getAcquired());
          consoleSessionResponse.setRemoved(consoleSession.getRemoved());
          consoleSessionResponse.setConsoleEndpointCreatorAddress(consoleSession.getConsoleEndpointCreatorAddress());
          consoleSessionResponse.setClientAddress(consoleSession.getClientAddress());
  
          populateDomainFieldsOnConsoleSessionResponse(consoleSession, consoleSessionResponse);
          populateUserFieldsOnConsoleSessionResponse(consoleSession, consoleSessionResponse);
          populateAccountFieldsOnConsoleSessionResponse(consoleSession, consoleSessionResponse);
          populateInstanceFieldsOnConsoleSessionResponse(consoleSession, consoleSessionResponse);
          if (responseView == ResponseView.Full) {
              populateHostFieldsOnConsoleSessionResponse(consoleSession, consoleSessionResponse);
          }
  
          consoleSessionResponse.setObjectName("consolesession");
          return consoleSessionResponse;
      }
  }
  