package org.ovirt.engine.api.restapi.types; import static org.ovirt.engine.api.restapi.utils.VersionUtils.greaterOrEqual; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.ovirt.engine.api.model.Cluster.RequiredRngSourcesList; import org.ovirt.engine.api.model.Cpu; import org.ovirt.engine.api.model.DataCenter; import org.ovirt.engine.api.model.Display; import org.ovirt.engine.api.model.ErrorHandling; import org.ovirt.engine.api.model.Ksm; import org.ovirt.engine.api.model.MacPool; import org.ovirt.engine.api.model.MemoryOverCommit; import org.ovirt.engine.api.model.MemoryPolicy; import org.ovirt.engine.api.model.MigrateOnError; import org.ovirt.engine.api.model.SchedulingPolicy; import org.ovirt.engine.api.model.TransparentHugePages; import org.ovirt.engine.api.restapi.utils.CustomPropertiesParser; import org.ovirt.engine.api.restapi.utils.GuidUtils; import org.ovirt.engine.core.common.businessentities.Cluster; import org.ovirt.engine.core.common.businessentities.MigrateOnErrorOptions; import org.ovirt.engine.core.common.businessentities.StoragePool; import org.ovirt.engine.core.common.businessentities.VmRngDevice; import org.ovirt.engine.core.compat.Guid; public class ClusterMapper { static final org.ovirt.engine.core.compat.Version min_thp_version = new org.ovirt.engine.core.compat.Version(3, 0); @Mapping(from = org.ovirt.engine.api.model.Cluster.class, to = Cluster.class) public static Cluster map(org.ovirt.engine.api.model.Cluster model, Cluster template) { Cluster entity = template != null ? template : new Cluster(); if (model.isSetSwitchType()) { entity.setRequiredSwitchTypeForCluster(SwitchTypeMapper.mapFromModel(model.getSwitchType())); } if (model.isSetId()) { entity.setId(GuidUtils.asGuid(model.getId())); } if (model.isSetName()) { entity.setName(model.getName()); } if (model.isSetDescription()) { entity.setDescription(model.getDescription()); } if (model.isSetComment()) { entity.setComment(model.getComment()); } if (model.isSetCpu() && model.getCpu().isSetType()) { entity.setCpuName(model.getCpu().getType()); } if (model.isSetCpu() && model.getCpu().isSetArchitecture()) { entity.setArchitecture(CPUMapper.map(model.getCpu().getArchitecture(), null)); } if (model.isSetDataCenter() && model.getDataCenter().isSetId()) { entity.setStoragePoolId(GuidUtils.asGuid(model.getDataCenter().getId())); } if (model.isSetVersion() && model.getVersion().getMajor() != null && model.getVersion().getMinor() != null) { entity.setCompatibilityVersion(VersionMapper.map(model.getVersion())); } if (model.isSetMemoryPolicy()) { entity = map(model.getMemoryPolicy(), entity); } else if (model.isSetVersion() && model.getVersion().getMajor() != null && model.getVersion().getMinor() != null && greaterOrEqual(model.getVersion(), min_thp_version)) { entity.setTransparentHugepages(true); } SchedulingPolicy schedulingPolicy = model.getSchedulingPolicy(); if (schedulingPolicy != null) { if (schedulingPolicy.isSetName()) { entity.setClusterPolicyName(schedulingPolicy.getName()); } if (schedulingPolicy.isSetId()) { entity.setClusterPolicyId(GuidUtils.asGuid(schedulingPolicy.getId())); } } if (model.isSetErrorHandling() && model.getErrorHandling().isSetOnError()) { entity.setMigrateOnError(map(model.getErrorHandling().getOnError(), null)); } if(model.isSetVirtService()) { entity.setVirtService(model.isVirtService()); } if(model.isSetGlusterService()) { entity.setGlusterService(model.isGlusterService()); } if (model.isSetThreadsAsCores()) { entity.setCountThreadsAsCores(model.isThreadsAsCores()); } if (model.isSetTunnelMigration()) { entity.setTunnelMigration(model.isTunnelMigration()); } if (model.isSetTrustedService()){ entity.setTrustedService(model.isTrustedService()); } if (model.isSetHaReservation()) { entity.setHaReservation(model.isHaReservation()); } if (model.isSetOptionalReason()) { entity.setOptionalReasonRequired(model.isOptionalReason()); } if (model.isSetMaintenanceReasonRequired()) { entity.setMaintenanceReasonRequired(model.isMaintenanceReasonRequired()); } if (model.isSetBallooningEnabled()) { entity.setEnableBallooning(model.isBallooningEnabled()); } if (model.isSetKsm()) { if (model.getKsm().isSetEnabled()) { entity.setEnableKsm(model.getKsm().isEnabled()); } if (model.getKsm().isSetMergeAcrossNodes()) { entity.setKsmMergeAcrossNumaNodes(model.getKsm().isMergeAcrossNodes()); } } if (model.isSetDisplay() && model.getDisplay().isSetProxy()) { entity.setSpiceProxy("".equals(model.getDisplay().getProxy()) ? null : model.getDisplay().getProxy()); } if (model.isSetSerialNumber()) { SerialNumberMapper.copySerialNumber(model.getSerialNumber(), entity); } /* * For backward compatibility additional rng sources are presented in <required_rng_sources> together with * implicit /dev/urandom or /dev/random source. <required_rng_sources> should be changed to * <additional_rng_sources> during next api change. */ if (model.isSetRequiredRngSources()) { entity.getAdditionalRngSources().clear(); entity.getAdditionalRngSources().addAll(RngDeviceMapper.mapRngSources(model.getRequiredRngSources().getRequiredRngSources())); entity.getAdditionalRngSources().remove(VmRngDevice.Source.RANDOM); entity.getAdditionalRngSources().remove(VmRngDevice.Source.URANDOM); } if (model.isSetFencingPolicy()) { entity.setFencingPolicy(FencingPolicyMapper.map(model.getFencingPolicy(), null)); } if (model.isSetMigration()) { ClusterMigrationOptionsMapper.copyMigrationOptions(model.getMigration(), entity); } if (model.isSetMacPool() && model.getMacPool().isSetId()) { entity.setMacPoolId(GuidUtils.asGuid(model.getMacPool().getId())); } // properties will override thresholds if (model.isSetCustomSchedulingPolicyProperties()) { Map<String, String> properties = entity.getClusterPolicyProperties(); if (properties == null) { properties = new HashMap<>(); entity.setClusterPolicyProperties(properties); } Map<String, String> customProperties = CustomPropertiesParser.toMap(model.getCustomSchedulingPolicyProperties()); properties.putAll(customProperties); } if (model.isSetGlusterTunedProfile()) { entity.setGlusterTunedProfile(model.getGlusterTunedProfile()); } return entity; } @Mapping(from = Cluster.class, to = org.ovirt.engine.api.model.Cluster.class) public static org.ovirt.engine.api.model.Cluster map(Cluster entity, org.ovirt.engine.api.model.Cluster template) { org.ovirt.engine.api.model.Cluster model = template != null ? template : new org.ovirt.engine.api.model.Cluster(); model.setId(entity.getId().toString()); model.setName(entity.getName()); model.setDescription(entity.getDescription()); model.setComment(entity.getComment()); model.setSwitchType(SwitchTypeMapper.mapToModel(entity.getRequiredSwitchTypeForCluster())); if (entity.getCpuName() != null) { Cpu cpu = new Cpu(); cpu.setType(entity.getCpuName()); cpu.setArchitecture(CPUMapper.map(entity.getArchitecture(), null)); model.setCpu(cpu); } if (entity.getStoragePoolId() != null) { DataCenter dataCenter = new DataCenter(); dataCenter.setId(entity.getStoragePoolId().toString()); model.setDataCenter(dataCenter); } if (entity.getCompatibilityVersion() != null) { model.setVersion(VersionMapper.map(entity.getCompatibilityVersion())); } model.setMemoryPolicy(map(entity, (MemoryPolicy)null)); Guid clusterPolicyId = entity.getClusterPolicyId(); if (clusterPolicyId != null) { SchedulingPolicy schedulingPolicy = model.getSchedulingPolicy(); if (schedulingPolicy == null) { schedulingPolicy = new SchedulingPolicy(); model.setSchedulingPolicy(schedulingPolicy); } schedulingPolicy.setId(clusterPolicyId.toString()); } model.setErrorHandling(map(entity.getMigrateOnError(), (ErrorHandling)null)); model.setVirtService(entity.supportsVirtService()); model.setGlusterService(entity.supportsGlusterService()); model.setThreadsAsCores(entity.getCountThreadsAsCores()); model.setTunnelMigration(entity.isTunnelMigration()); model.setTrustedService(entity.supportsTrustedService()); model.setHaReservation(entity.supportsHaReservation()); model.setOptionalReason(entity.isOptionalReasonRequired()); model.setMaintenanceReasonRequired(entity.isMaintenanceReasonRequired()); model.setBallooningEnabled(entity.isEnableBallooning()); Ksm ksm = model.getKsm(); if (ksm == null) { ksm = new Ksm(); model.setKsm(ksm); } ksm.setEnabled(entity.isEnableKsm()); ksm.setMergeAcrossNodes(entity.isKsmMergeAcrossNumaNodes()); if (StringUtils.isNotBlank(entity.getSpiceProxy())) { Display display = new Display(); display.setProxy(entity.getSpiceProxy()); model.setDisplay(display); } if (entity.getSerialNumberPolicy() != null) { model.setSerialNumber(SerialNumberMapper.map(entity, null)); } if (entity.getRequiredRngSources() != null) { model.setRequiredRngSources(new RequiredRngSourcesList()); model.getRequiredRngSources().getRequiredRngSources().addAll(RngDeviceMapper.mapRngSources(entity.getRequiredRngSources())); } model.setMigration(ClusterMigrationOptionsMapper.map(entity, null)); if (entity.getFencingPolicy() != null) { model.setFencingPolicy(FencingPolicyMapper.map(entity.getFencingPolicy(), null)); } if (entity.getMacPoolId() != null) { MacPool macPool = model.getMacPool(); if (macPool == null) { macPool = new MacPool(); model.setMacPool(macPool); } macPool.setId(entity.getMacPoolId().toString()); } if (entity.getClusterPolicyProperties() != null && !entity.getClusterPolicyProperties().isEmpty()) { model.setCustomSchedulingPolicyProperties(CustomPropertiesParser.fromMap(entity .getClusterPolicyProperties())); } if (entity.getGlusterTunedProfile() != null && !entity.getGlusterTunedProfile().isEmpty()) { model.setGlusterTunedProfile(entity.getGlusterTunedProfile()); } return model; } @Mapping(from = MemoryPolicy.class, to = Cluster.class) public static Cluster map(MemoryPolicy model, Cluster template) { Cluster entity = template != null ? template : new Cluster(); if (model.isSetOverCommit() && model.getOverCommit().getPercent()!=null) { entity.setMaxVdsMemoryOverCommit(model.getOverCommit().getPercent()); } if (model.isSetTransparentHugepages() && model.getTransparentHugepages().isSetEnabled()) { entity.setTransparentHugepages(model.getTransparentHugepages().isEnabled()); } else if (template != null && greaterOrEqual(template.getCompatibilityVersion(), min_thp_version)){ entity.setTransparentHugepages(true); } return entity; } @Mapping(from = Cluster.class, to = MemoryPolicy.class) public static MemoryPolicy map(Cluster entity, MemoryPolicy template) { MemoryPolicy model = template != null ? template : new MemoryPolicy(); model.setOverCommit(new MemoryOverCommit()); model.getOverCommit().setPercent(entity.getMaxVdsMemoryOverCommit()); model.setTransparentHugepages(new TransparentHugePages()); model.getTransparentHugepages().setEnabled(entity.getTransparentHugepages()); return model; } @Mapping(from = StoragePool.class, to = Cluster.class) public static Cluster map(StoragePool pool, Cluster template) { Cluster entity = template != null ? template : new Cluster(); if (pool.getCompatibilityVersion() != null) { entity.setCompatibilityVersion(pool.getCompatibilityVersion()); } return entity; } @Mapping(from = MigrateOnError.class, to = MigrateOnErrorOptions.class) public static MigrateOnErrorOptions map(MigrateOnError model, MigrateOnErrorOptions template) { if (model==null) { return null; } switch (model) { case MIGRATE: return MigrateOnErrorOptions.YES; case DO_NOT_MIGRATE: return MigrateOnErrorOptions.NO; case MIGRATE_HIGHLY_AVAILABLE: return MigrateOnErrorOptions.HA_ONLY; default: assert false : "unknown migrate-on-error value: " + model.toString(); return null; } } @Mapping(from = MigrateOnErrorOptions.class, to = MigrateOnError.class) public static MigrateOnError map(MigrateOnErrorOptions model, MigrateOnError template) { if (model==null) { return null; } switch (model) { case YES: return MigrateOnError.MIGRATE; case NO: return MigrateOnError.DO_NOT_MIGRATE; case HA_ONLY: return MigrateOnError.MIGRATE_HIGHLY_AVAILABLE; default: assert false : "unknown migrate-on-error value: " + model.toString(); return null; } } @Mapping(from = MigrateOnErrorOptions.class, to = ErrorHandling.class) private static ErrorHandling map(MigrateOnErrorOptions migrateOnError, ErrorHandling template) { MigrateOnError value = map(migrateOnError, (MigrateOnError)null); if (value==null) { return null; } else { template = template==null ? new ErrorHandling() : template; template.setOnError(value); return template; } } }