package org.ovirt.engine.ui.uicommonweb.models.clusters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.ovirt.engine.core.common.action.ClusterParametersBase;
import org.ovirt.engine.core.common.action.ManagementNetworkOnClusterOperationParameters;
import org.ovirt.engine.core.common.action.VdcActionParametersBase;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.action.VdcReturnValueBase;
import org.ovirt.engine.core.common.action.hostdeploy.AddVdsActionParameters;
import org.ovirt.engine.core.common.businessentities.AdditionalFeature;
import org.ovirt.engine.core.common.businessentities.Cluster;
import org.ovirt.engine.core.common.businessentities.MacPool;
import org.ovirt.engine.core.common.businessentities.MigrationBandwidthLimitType;
import org.ovirt.engine.core.common.businessentities.StoragePool;
import org.ovirt.engine.core.common.businessentities.SupportedAdditionalClusterFeature;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.VDSStatus;
import org.ovirt.engine.core.common.businessentities.VmRngDevice;
import org.ovirt.engine.core.common.businessentities.network.Network;
import org.ovirt.engine.core.common.interfaces.SearchType;
import org.ovirt.engine.core.common.queries.IdQueryParameters;
import org.ovirt.engine.core.common.queries.SearchParameters;
import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import org.ovirt.engine.core.common.scheduling.OptimizationType;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.Version;
import org.ovirt.engine.core.searchbackend.SearchObjects;
import org.ovirt.engine.ui.frontend.AsyncCallback;
import org.ovirt.engine.ui.frontend.Frontend;
import org.ovirt.engine.ui.uicommonweb.Cloner;
import org.ovirt.engine.ui.uicommonweb.Linq;
import org.ovirt.engine.ui.uicommonweb.UICommand;
import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
import org.ovirt.engine.ui.uicommonweb.help.HelpTag;
import org.ovirt.engine.ui.uicommonweb.models.ConfirmationModel;
import org.ovirt.engine.ui.uicommonweb.models.EntityModel;
import org.ovirt.engine.ui.uicommonweb.models.HasEntity;
import org.ovirt.engine.ui.uicommonweb.models.ISupportSystemTreeContext;
import org.ovirt.engine.ui.uicommonweb.models.ListWithSimpleDetailsModel;
import org.ovirt.engine.ui.uicommonweb.models.SystemTreeItemModel;
import org.ovirt.engine.ui.uicommonweb.models.SystemTreeItemType;
import org.ovirt.engine.ui.uicommonweb.models.configure.PermissionListModel;
import org.ovirt.engine.ui.uicommonweb.models.configure.scheduling.affinity_groups.list.ClusterAffinityGroupListModel;
import org.ovirt.engine.ui.uicommonweb.models.hosts.HostDetailModel;
import org.ovirt.engine.ui.uicommonweb.models.hosts.MultipleHostsModel;
import org.ovirt.engine.ui.uicommonweb.models.macpool.NewSharedMacPoolModel;
import org.ovirt.engine.ui.uicommonweb.models.macpool.SharedMacPoolModel;
import org.ovirt.engine.ui.uicommonweb.models.profiles.CpuProfileListModel;
import org.ovirt.engine.ui.uicommonweb.models.vms.key_value.KeyValueModel;
import org.ovirt.engine.ui.uicommonweb.place.WebAdminApplicationPlaces;
import org.ovirt.engine.ui.uicompat.ConstantsManager;
import org.ovirt.engine.ui.uicompat.NotifyCollectionChangedEventArgs;
import org.ovirt.engine.ui.uicompat.UIConstants;
import org.ovirt.engine.ui.uicompat.UIMessages;
import com.google.inject.Inject;
public class ClusterListModel<E> extends ListWithSimpleDetailsModel<E, Cluster> implements ISupportSystemTreeContext {
private final UIConstants constants = ConstantsManager.getInstance().getConstants();
private final UIMessages messages = ConstantsManager.getInstance().getMessages();
private UICommand privateNewCommand;
public UICommand getNewCommand() {
return privateNewCommand;
}
private void setNewCommand(UICommand value) {
privateNewCommand = value;
}
private UICommand privateEditCommand;
@Override
public UICommand getEditCommand() {
return privateEditCommand;
}
private void setEditCommand(UICommand value) {
privateEditCommand = value;
}
private UICommand privateRemoveCommand;
public UICommand getRemoveCommand() {
return privateRemoveCommand;
}
private void setRemoveCommand(UICommand value) {
privateRemoveCommand = value;
}
private UICommand privateGuideCommand;
public UICommand getGuideCommand() {
return privateGuideCommand;
}
private void setGuideCommand(UICommand value) {
privateGuideCommand = value;
}
private UICommand resetEmulatedMachineCommand;
public UICommand getResetEmulatedMachineCommand() {
return resetEmulatedMachineCommand;
}
private void setResetEmulatedMachineCommand(UICommand value) {
resetEmulatedMachineCommand = value;
}
private UICommand privateAddMultipleHostsCommand;
public UICommand getAddMultipleHostsCommand() {
return privateAddMultipleHostsCommand;
}
private void setAddMultipleHostsCommand(UICommand value) {
privateAddMultipleHostsCommand = value;
}
private UICommand addMacPoolCommand;
public UICommand getAddMacPoolCommand() {
return addMacPoolCommand;
}
private void setAddMacPoolCommand(UICommand addMacPoolCommand) {
this.addMacPoolCommand = addMacPoolCommand;
}
private Object privateGuideContext;
public Object getGuideContext() {
return privateGuideContext;
}
public void setGuideContext(Object value) {
privateGuideContext = value;
}
private final ClusterServiceModel clusterServiceModel;
public ClusterServiceModel getClusterServiceModel() {
return clusterServiceModel;
}
private final ClusterVmListModel clusterVmListModel;
public ClusterVmListModel getClusterVmListModel() {
return clusterVmListModel;
}
private final ClusterGlusterHookListModel clusterGlusterHookListModel;
public ClusterGlusterHookListModel getClusterGlusterHookListModel() {
return clusterGlusterHookListModel;
}
private final ClusterAffinityGroupListModel affinityGroupListModel;
public ClusterAffinityGroupListModel getAffinityGroupListModel() {
return affinityGroupListModel;
}
private final CpuProfileListModel cpuProfileListModel;
public CpuProfileListModel getCpuProfileListModel() {
return cpuProfileListModel;
}
@Inject
public ClusterListModel(final ClusterVmListModel clusterVmListModel, final ClusterServiceModel clusterServiceModel,
final ClusterGlusterHookListModel clusterGlusterHookListModel,
final ClusterAffinityGroupListModel clusterAffinityGroupListModel,
final CpuProfileListModel cpuProfileListModel, final ClusterGeneralModel clusterGeneralModel,
final ClusterNetworkListModel clusterNetworkListModel, final ClusterHostListModel clusterHostListModel,
final PermissionListModel<Cluster> permissionListModel) {
this.clusterVmListModel = clusterVmListModel;
this.clusterServiceModel = clusterServiceModel;
this.clusterGlusterHookListModel = clusterGlusterHookListModel;
this.affinityGroupListModel = clusterAffinityGroupListModel;
this.cpuProfileListModel = cpuProfileListModel;
setDetailList(clusterGeneralModel, clusterNetworkListModel, clusterHostListModel, permissionListModel);
setTitle(ConstantsManager.getInstance().getConstants().clustersTitle());
setHelpTag(HelpTag.clusters);
setApplicationPlace(WebAdminApplicationPlaces.clusterMainTabPlace);
setHashName("clusters"); //$NON-NLS-1$
setDefaultSearchString("Cluster:"); //$NON-NLS-1$
setSearchString(getDefaultSearchString());
setSearchObjects(new String[] { SearchObjects.VDC_CLUSTER_OBJ_NAME, SearchObjects.VDC_CLUSTER_PLU_OBJ_NAME });
setNewCommand(new UICommand("New", this)); //$NON-NLS-1$
setEditCommand(new UICommand("Edit", this)); //$NON-NLS-1$
setRemoveCommand(new UICommand("Remove", this)); //$NON-NLS-1$
setAddMacPoolCommand(new UICommand("AddMacPool", this)); //$NON-NLS-1$
getAddMacPoolCommand().setTitle(ConstantsManager.getInstance().getConstants().addMacPoolButton());
setGuideCommand(new UICommand("Guide", this)); //$NON-NLS-1$
setResetEmulatedMachineCommand(new UICommand("ResetEmulatedMachine", this)); //$NON-NLS-1$
setAddMultipleHostsCommand(new UICommand("AddHosts", this)); //$NON-NLS-1$
updateActionAvailability();
getSearchNextPageCommand().setIsAvailable(true);
getSearchPreviousPageCommand().setIsAvailable(true);
}
public void guide() {
ClusterGuideModel model = new ClusterGuideModel();
setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().newClusterGuideMeTitle());
model.setHelpTag(HelpTag.new_cluster___guide_me);
model.setHashName("new_cluster_-_guide_me"); //$NON-NLS-1$
if (getGuideContext() == null) {
Cluster cluster = getSelectedItem();
setGuideContext(cluster.getId());
}
AsyncDataProvider.getInstance().getClusterById(new AsyncQuery<>(
returnValue -> {
ClusterGuideModel clusterGuideModel = (ClusterGuideModel) getWindow();
clusterGuideModel.setEntity(returnValue);
UICommand tempVar = new UICommand("Cancel", ClusterListModel.this); //$NON-NLS-1$
tempVar.setTitle(ConstantsManager.getInstance().getConstants().configureLaterTitle());
tempVar.setIsDefault(true);
tempVar.setIsCancel(true);
clusterGuideModel.getCommands().add(tempVar);
}), (Guid) getGuideContext());
}
private void setDetailList(final ClusterGeneralModel clusterGeneralModel,
final ClusterNetworkListModel clusterNetworkListModel, final ClusterHostListModel clusterHostListModel,
final PermissionListModel<Cluster> permissionListModel) {
List<HasEntity<Cluster>> list = new ArrayList<>();
list.add(clusterGeneralModel);
list.add(clusterNetworkListModel);
list.add(clusterHostListModel);
list.add(clusterVmListModel);
list.add(clusterServiceModel);
list.add(clusterGlusterHookListModel);
list.add(cpuProfileListModel);
list.add(permissionListModel);
list.add(affinityGroupListModel);
setDetailModels(list);
}
@Override
protected void updateDetailsAvailability() {
super.updateDetailsAvailability();
Cluster cluster = getSelectedItem();
getClusterVmListModel().setIsAvailable(cluster != null && cluster.supportsVirtService());
getClusterServiceModel().setIsAvailable(cluster != null && cluster.supportsGlusterService());
getClusterGlusterHookListModel().setIsAvailable(cluster != null && cluster.supportsGlusterService());
getAffinityGroupListModel().setIsAvailable(cluster != null && cluster.supportsVirtService());
getCpuProfileListModel().setIsAvailable(cluster != null && cluster.supportsVirtService());
}
@Override
public boolean isSearchStringMatch(String searchString) {
return searchString.trim().toLowerCase().startsWith("cluster"); //$NON-NLS-1$
}
@Override
protected void syncSearch() {
SearchParameters tempVar = new SearchParameters(applySortOptions(getSearchString()), SearchType.Cluster,
isCaseSensitiveSearch());
tempVar.setMaxCount(getSearchPageSize());
super.syncSearch(VdcQueryType.Search, tempVar);
}
@Override
public boolean supportsServerSideSorting() {
return true;
}
public void newEntity() {
if (getWindow() != null) {
return;
}
ClusterModel clusterModel = new ClusterModel();
clusterModel.setAddMacPoolCommand(addMacPoolCommand);
clusterModel.init(false);
setWindow(clusterModel);
clusterModel.setTitle(ConstantsManager.getInstance().getConstants().newClusterTitle());
clusterModel.setHelpTag(HelpTag.new_cluster);
clusterModel.setHashName("new_cluster"); //$NON-NLS-1$
clusterModel.setIsNew(true);
clusterModel.getMigrationBandwidthLimitType().setItems(Arrays.asList(MigrationBandwidthLimitType.values()));
clusterModel.getMigrationBandwidthLimitType().setSelectedItem(MigrationBandwidthLimitType.DEFAULT);
AsyncDataProvider.getInstance().getDataCenterList(new AsyncQuery<>(dataCenters -> {
ClusterModel cModel = (ClusterModel) getWindow();
// Be aware of system tree selection.
// Strict data center as neccessary.
if (getSystemTreeSelectedItem() != null
&& getSystemTreeSelectedItem().getType() != SystemTreeItemType.System) {
SystemTreeItemModel treeSelectedItem = getSystemTreeSelectedItem();
SystemTreeItemModel treeSelectedDc = SystemTreeItemModel.findAncestor(SystemTreeItemType.DataCenter, treeSelectedItem);
StoragePool selectDataCenter = (StoragePool) treeSelectedDc.getEntity();
final StoragePool selectedDataCenter = Linq.firstOrNull(dataCenters,
new Linq.IdPredicate<>(selectDataCenter.getId()));
cModel.getDataCenter().setItems(dataCenters, selectedDataCenter);
cModel.getDataCenter().setIsChangeable(false);
}
else {
cModel.getDataCenter().setItems(dataCenters, Linq.firstOrNull(dataCenters));
}
UICommand tempVar = UICommand.createDefaultOkUiCommand("OnSave", ClusterListModel.this); //$NON-NLS-1$
cModel.getCommands().add(tempVar);
UICommand tempVar2 = UICommand.createCancelUiCommand("Cancel", ClusterListModel.this); //$NON-NLS-1$
cModel.getCommands().add(tempVar2);
}));
clusterModel.refreshMigrationPolicies();
}
public void edit() {
final Cluster cluster = getSelectedItem();
if (getWindow() != null) {
return;
}
final UIConstants constants = ConstantsManager.getInstance().getConstants();
final ClusterModel clusterModel = new ClusterModel();
clusterModel.setAddMacPoolCommand(addMacPoolCommand);
clusterModel.setEntity(cluster);
clusterModel.init(true);
clusterModel.getEnableTrustedService().setEntity(cluster.supportsTrustedService());
clusterModel.getEnableHaReservation().setEntity(cluster.supportsHaReservation());
clusterModel.getEnableOptionalReason().setEntity(cluster.isOptionalReasonRequired());
clusterModel.getEnableHostMaintenanceReason().setEntity(cluster.isMaintenanceReasonRequired());
setWindow(clusterModel);
clusterModel.setTitle(ConstantsManager.getInstance().getConstants().editClusterTitle());
clusterModel.setHelpTag(HelpTag.edit_cluster);
clusterModel.setHashName("edit_cluster"); //$NON-NLS-1$
clusterModel.setOriginalName(cluster.getName());
clusterModel.getName().setEntity(cluster.getName());
clusterModel.getSwitchType().setSelectedItem(cluster.getRequiredSwitchTypeForCluster());
clusterModel.getEnableOvirtService().setEntity(cluster.supportsVirtService());
clusterModel.getEnableOvirtService().setIsChangeable(true);
clusterModel.getEnableGlusterService().setEntity(cluster.supportsGlusterService());
clusterModel.getEnableGlusterService().setIsChangeable(true);
clusterModel.getEnableKsm().setEntity(cluster.isEnableKsm());
clusterModel.setKsmPolicyForNuma(cluster.isKsmMergeAcrossNumaNodes());
clusterModel.getEnableBallooning().setEntity(cluster.isEnableBallooning());
clusterModel.getArchitecture().setSelectedItem(cluster.getArchitecture());
clusterModel.getSerialNumberPolicy().setSelectedSerialNumberPolicy(cluster.getSerialNumberPolicy());
clusterModel.getSerialNumberPolicy().getCustomSerialNumber().setEntity(cluster.getCustomSerialNumber());
clusterModel.getAutoConverge().setSelectedItem(cluster.getAutoConverge());
clusterModel.getMigrateCompressed().setSelectedItem(cluster.getMigrateCompressed());
clusterModel.getGlusterTunedProfile().setSelectedItem(cluster.getGlusterTunedProfile());
clusterModel.getGlusterTunedProfile().setIsChangeable(cluster.getClusterHostsAndVms().getHosts() == 0);
clusterModel.getMigrationBandwidthLimitType().setItems(Arrays.asList(MigrationBandwidthLimitType.values()));
clusterModel.getMigrationBandwidthLimitType().setSelectedItem(cluster.getMigrationBandwidthLimitType() != null
? cluster.getMigrationBandwidthLimitType()
: MigrationBandwidthLimitType.DEFAULT);
clusterModel.getCustomMigrationNetworkBandwidth().setEntity(cluster.getCustomMigrationNetworkBandwidth());
if (cluster.supportsTrustedService()) {
clusterModel.getEnableGlusterService().setIsChangeable(false);
}
if (cluster.supportsVirtService()&& !cluster.supportsGlusterService()) {
clusterModel.getEnableTrustedService().setIsChangeable(true);
}
else {
clusterModel.getEnableTrustedService().setIsChangeable(false);
}
clusterModel.getOptimizeForSpeed()
.setEntity(OptimizationType.OPTIMIZE_FOR_SPEED == cluster.getOptimizationType());
clusterModel.getAllowOverbooking()
.setEntity(OptimizationType.ALLOW_OVERBOOKING == cluster.getOptimizationType());
AsyncDataProvider.getInstance().getAllowClusterWithVirtGlusterEnabled(new AsyncQuery<>(isVirtGlusterAllowed -> {
AsyncDataProvider.getInstance().getVolumeList(clusterModel.asyncQuery(volumes -> {
if (volumes.size() > 0) {
clusterModel.getEnableGlusterService().setIsChangeable(false);
if (!isVirtGlusterAllowed) {
clusterModel.getEnableOvirtService().setIsChangeable(false);
}
}
}), cluster.getName());
if (cluster.getClusterHostsAndVms().getVms() > 0) {
clusterModel.getEnableOvirtService().setIsChangeable(false);
if (!isVirtGlusterAllowed) {
clusterModel.getEnableGlusterService().setIsChangeable(false);
}
}
if (cluster.getClusterHostsAndVms().getHosts() > 0) {
clusterModel.getEnableTrustedService().setIsChangeable(false);
clusterModel.getEnableTrustedService().setChangeProhibitionReason(
ConstantsManager.getInstance()
.getConstants()
.trustedServiceDisabled());
}
}));
clusterModel.refreshMigrationPolicies();
if (getSystemTreeSelectedItem() != null && (getSystemTreeSelectedItem().getType() == SystemTreeItemType.Cluster ||
getSystemTreeSelectedItem().getType() == SystemTreeItemType.Cluster_Gluster)) {
clusterModel.getName().setIsChangeable(false);
clusterModel.getName().setChangeProhibitionReason(constants.cannotEditNameInTreeContext());
}
UICommand tempVar = UICommand.createDefaultOkUiCommand("OnSave", this); //$NON-NLS-1$
clusterModel.getCommands().add(tempVar);
UICommand tempVar2 = UICommand.createCancelUiCommand("Cancel", this); //$NON-NLS-1$
clusterModel.getCommands().add(tempVar2);
}
private void addMacPool(final ClusterModel clusterModel) {
SharedMacPoolModel macPoolModel = new NewSharedMacPoolModel.ClosingWithSetConfirmWindow(this) {
@Override
protected void onActionSucceeded(Guid macPoolId) {
MacPool macPool = getEntity();
macPool.setId(macPoolId);
Collection<MacPool> macPools = new ArrayList<>(clusterModel.getMacPoolListModel().getItems());
macPools.add(macPool);
clusterModel.getMacPoolListModel().setItems(macPools);
clusterModel.getMacPoolListModel().setSelectedItem(macPool);
ClusterListModel.this.setConfirmWindow(null);
}
};
macPoolModel.setEntity(new MacPool());
setConfirmWindow(macPoolModel);
}
public void remove() {
if (getWindow() != null) {
return;
}
ConfirmationModel model = new ConfirmationModel();
setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().removeClusterTitle());
model.setHelpTag(HelpTag.remove_cluster);
model.setHashName("remove_cluster"); //$NON-NLS-1$
ArrayList<String> list = new ArrayList<>();
for (Cluster a : getSelectedItems()) {
list.add(a.getName());
}
model.setItems(list);
UICommand tempVar = UICommand.createDefaultOkUiCommand("OnRemove", this); //$NON-NLS-1$
model.getCommands().add(tempVar);
UICommand tempVar2 = UICommand.createCancelUiCommand("Cancel", this); //$NON-NLS-1$
model.getCommands().add(tempVar2);
}
public void resetEmulatedMachine() {
if (getWindow() != null) {
return;
}
ConfirmationModel model = new ConfirmationModel();
setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().resetClusterEmulatedMachineTitle());
model.setMessage(ConstantsManager.getInstance().getConstants().resetClusterEmulatedMachineMessage());
model.setHelpTag(HelpTag.reset_emulated_machine_cluster);
model.setHashName("reset_cluster_emulated_machine"); //$NON-NLS-1$
ArrayList<String> list = new ArrayList<>();
for (Cluster cluster : getSelectedItems()) {
list.add(cluster.getName());
}
model.setItems(list);
model.getCommands().add(UICommand.createDefaultOkUiCommand("OnResetClusterEmulatedMachine", this)); //$NON-NLS-1$
model.getCommands().add(UICommand.createCancelUiCommand("Cancel", this)); //$NON-NLS-1$
}
public void onResetClusterEmulatedMachine() {
final ConfirmationModel model = (ConfirmationModel) getWindow();
if (model.getProgress() != null) {
return;
}
ArrayList<VdcActionParametersBase> prms = new ArrayList<>();
for (Cluster cluster : getSelectedItems()) {
ManagementNetworkOnClusterOperationParameters currentParam = new ManagementNetworkOnClusterOperationParameters(cluster);
currentParam.setForceResetEmulatedMachine(true);
prms.add(currentParam);
}
model.startProgress();
Frontend.getInstance().runMultipleAction(VdcActionType.UpdateCluster, prms,
result -> {
model.stopProgress();
cancel();
});
}
public void onRemove() {
ConfirmationModel model = (ConfirmationModel) getWindow();
if (model.getProgress() != null) {
return;
}
ArrayList<VdcActionParametersBase> prms = new ArrayList<>();
for (Object a : getSelectedItems()) {
prms.add(new ClusterParametersBase(((Cluster) a).getId()));
}
model.startProgress();
Frontend.getInstance().runMultipleAction(VdcActionType.RemoveCluster, prms,
result -> {
ConfirmationModel localModel = (ConfirmationModel) result.getState();
localModel.stopProgress();
cancel();
}, model);
}
public void onSave() {
ClusterModel model = (ClusterModel) getWindow();
boolean validateCpu =
(model.getIsNew() && model.getEnableOvirtService().getEntity())
|| (model.getIsEdit() && getSelectedItem().getCpuName() != null);
if (!model.validate(validateCpu)) {
return;
}
else if (model.getIsNew()) {
onPreSaveInternal(model);
}
else {
onSaveConfirmCV(model);
}
}
private void onSaveConfirmCV(ClusterModel model) {
if (!model.getVersion().getSelectedItem().equals(getSelectedItem().getCompatibilityVersion())) {
final ConfirmationModel confirmModel = new ConfirmationModel();
setConfirmWindow(confirmModel);
confirmModel.setTitle(constants.changeClusterCompatibilityVersionTitle());
confirmModel.setHelpTag(HelpTag.change_cluster_compatibility_version);
confirmModel.setHashName("change_cluster_compatibility_version"); //$NON-NLS-1$
UICommand tempVar = UICommand.createDefaultOkUiCommand("OnSaveConfirmCpuThreads", this); //$NON-NLS-1$
getConfirmWindow().getCommands().add(tempVar);
UICommand tempVar2 = UICommand.createCancelUiCommand("CancelConfirmation", this); //$NON-NLS-1$
getConfirmWindow().getCommands().add(tempVar2);
checkForActiveVms(model, confirmModel);
} else {
onSaveConfirmCpuThreads();
}
}
private void checkForActiveVms(ClusterModel model, final ConfirmationModel confirmModel) {
Guid clusterId = model.getEntity().getId();
Frontend.getInstance().runQuery(VdcQueryType.GetNumberOfActiveVmsInClusterByClusterId,
new IdQueryParameters(clusterId), new AsyncQuery<>((AsyncCallback<VdcQueryReturnValue>) returnValue -> {
Integer numOfActiveVms = returnValue.getReturnValue();
if (numOfActiveVms != 0) {
confirmModel.setMessage(messages.thereAreActiveVMsRequiringRestart(numOfActiveVms));
}
checkForNonResponsiveHosts(confirmModel);
}));
}
private void onSaveConfirmCpuThreads() {
ClusterModel model = (ClusterModel) getWindow();
// cancel confirm window if there is one
cancelConfirmation();
// CPU thread support is being turned off either explicitly or via version change
if (!model.getVersionSupportsCpuThreads().getEntity() && model.getCountThreadsAsCores().getEntity()
&& getSelectedItem().getCountThreadsAsCores()) {
ConfirmationModel confirmModel = new ConfirmationModel();
setConfirmWindow(confirmModel);
confirmModel.setTitle(ConstantsManager.getInstance()
.getConstants()
.disableClusterCpuThreadSupportTitle());
confirmModel.setHelpTag(HelpTag.disable_cpu_thread_support);
confirmModel.setHashName("disable_cpu_thread_support"); //$NON-NLS-1$
confirmModel.setMessage(ConstantsManager.getInstance()
.getConstants()
.youAreAboutChangeClusterCpuThreadSupportMsg());
UICommand tempVar = UICommand.createDefaultOkUiCommand("OnSaveConfirmGenericWarnings", this); //$NON-NLS-1$
getConfirmWindow().getCommands().add(tempVar);
UICommand tempVar2 = UICommand.createCancelUiCommand("CancelConfirmation", this); //$NON-NLS-1$
getConfirmWindow().getCommands().add(tempVar2);
} else {
onSaveConfirmGenericWarnings();
}
}
private void onSaveConfirmGenericWarnings() {
ClusterModel model = (ClusterModel) getWindow();
cancelConfirmation();
Cluster cluster = buildCluster(model);
AsyncDataProvider.getInstance().getClusterEditWarnings(new AsyncQuery<>(warnings -> {
if (!warnings.isEmpty()) {
ClusterWarningsModel confirmWindow = new ClusterWarningsModel();
confirmWindow.init(warnings);
confirmWindow.getCommands().add(UICommand.createDefaultOkUiCommand("OnSaveInternal", ClusterListModel.this)); //$NON-NLS-1$
confirmWindow.getCommands().add(UICommand.createCancelUiCommand("CancelConfirmation", ClusterListModel.this)); //$NON-NLS-1$
setConfirmWindow(confirmWindow);
} else {
onSaveInternal();
}
}), model.getClusterId(), cluster);
}
public void onPreSaveInternal(ClusterModel model) {
if (model.getIsImportGlusterConfiguration().getEntity()) {
fetchAndImportClusterHosts(model);
}
else {
onSaveInternal();
}
}
public void onSaveInternal() {
ClusterModel model = (ClusterModel) getWindow();
if (model.getProgress() != null) {
return;
}
// cancel confirm window if there is
cancelConfirmation();
onSaveInternalWithModel(model);
}
private Cluster buildCluster(ClusterModel model) {
Cluster cluster = model.getIsNew() ? new Cluster() : (Cluster) Cloner.clone(getSelectedItem());
Version version = model.getVersion().getSelectedItem();
cluster.setName(model.getName().getEntity());
cluster.setDescription(model.getDescription().getEntity());
cluster.setComment(model.getComment().getEntity());
cluster.setStoragePoolId(model.getDataCenter().getSelectedItem().getId());
if (model.getCPU().getSelectedItem() != null) {
cluster.setCpuName(model.getCPU().getSelectedItem().getCpuName());
}
cluster.setMaxVdsMemoryOverCommit(model.getMemoryOverCommit());
cluster.setCountThreadsAsCores(Boolean.TRUE.equals(model.getVersionSupportsCpuThreads().getEntity())
&& Boolean.TRUE.equals(model.getCountThreadsAsCores().getEntity()));
cluster.setEnableKsm(Boolean.TRUE.equals(model.getEnableKsm().getEntity()));
cluster.setKsmMergeAcrossNumaNodes(model.getKsmPolicyForNuma());
cluster.setEnableBallooning(Boolean.TRUE.equals(model.getEnableBallooning().getEntity()));
cluster.setTransparentHugepages(true); //$NON-NLS-1$
cluster.setCompatibilityVersion(version);
cluster.setRequiredSwitchTypeForCluster(model.getSwitchType().getSelectedItem());
cluster.setMigrateOnError(model.getMigrateOnErrorOption());
cluster.setVirtService(model.getEnableOvirtService().getEntity());
cluster.setGlusterService(model.getEnableGlusterService().getEntity());
for (AdditionalFeature feature : model.getAdditionalClusterFeatures().getSelectedItem()) {
cluster.getAddtionalFeaturesSupported().add(new SupportedAdditionalClusterFeature(cluster.getId(),
true,
feature));
}
cluster.setTrustedService(model.getEnableTrustedService().getEntity());
cluster.setHaReservation(model.getEnableHaReservation().getEntity());
cluster.setOptionalReasonRequired(model.getEnableOptionalReason().getEntity());
cluster.setMaintenanceReasonRequired(model.getEnableHostMaintenanceReason().getEntity());
cluster.setClusterPolicyId(model.getClusterPolicy().getSelectedItem().getId());
cluster.setClusterPolicyProperties(KeyValueModel.convertProperties(model.getCustomPropertySheet().serialize()));
if (model.getOptimizeForSpeed().getEntity()) {
cluster.setOptimizationType(OptimizationType.OPTIMIZE_FOR_SPEED);
} else if (model.getAllowOverbooking().getEntity()) {
cluster.setOptimizationType(OptimizationType.ALLOW_OVERBOOKING);
} else {
cluster.setOptimizationType(OptimizationType.NONE);
}
if (model.getCPU().getSelectedItem() == null) {
cluster.setArchitecture(model.getArchitecture().getSelectedItem());
} else {
cluster.setArchitecture(null);
}
if (model.getSpiceProxyEnabled().getEntity()) {
cluster.setSpiceProxy(model.getSpiceProxy().getEntity());
}
if (model.getMigrationPolicies().getSelectedItem() != null) {
cluster.setMigrationPolicyId(model.getMigrationPolicies().getSelectedItem().getId());
}
cluster.getFencingPolicy().setFencingEnabled(model.getFencingEnabledModel().getEntity());
cluster.getFencingPolicy().setSkipFencingIfSDActive(model.getSkipFencingIfSDActiveEnabled().getEntity());
cluster.getFencingPolicy().setSkipFencingIfConnectivityBroken(model.getSkipFencingIfConnectivityBrokenEnabled().getEntity());
cluster.getFencingPolicy().setHostsWithBrokenConnectivityThreshold(model.getHostsWithBrokenConnectivityThreshold().getSelectedItem().intValue());
cluster.getFencingPolicy().setSkipFencingIfGlusterBricksUp(model.getSkipFencingIfGlusterBricksUp().getEntity());
cluster.getFencingPolicy().setSkipFencingIfGlusterQuorumNotMet(model.getSkipFencingIfGlusterQuorumNotMet().getEntity());
cluster.setSerialNumberPolicy(model.getSerialNumberPolicy().getSelectedSerialNumberPolicy());
cluster.setCustomSerialNumber(model.getSerialNumberPolicy().getCustomSerialNumber().getEntity());
cluster.setAutoConverge(model.getAutoConverge().getSelectedItem());
cluster.setMigrateCompressed(model.getMigrateCompressed().getSelectedItem());
if (model.getEnableGlusterService().getEntity()) {
cluster.setGlusterTunedProfile(model.getGlusterTunedProfile().getSelectedItem());
}
cluster.getAdditionalRngSources().clear();
if (Boolean.TRUE.equals(model.getRngHwrngSourceRequired().getEntity())) {
cluster.getAdditionalRngSources().add(VmRngDevice.Source.HWRNG);
}
cluster.setMigrationBandwidthLimitType(model.getMigrationBandwidthLimitType().getSelectedItem());
cluster.setCustomMigrationNetworkBandwidth(
MigrationBandwidthLimitType.CUSTOM.equals(model.getMigrationBandwidthLimitType().getSelectedItem())
? model.getCustomMigrationNetworkBandwidth().getEntity()
: null);
cluster.setMacPoolId(model.getMacPoolListModel().getSelectedItem().getId());
return cluster;
}
private void onSaveInternalWithModel(final ClusterModel model) {
Cluster cluster = buildCluster(model);
model.startProgress();
final Network managementNetwork = model.getManagementNetwork().getSelectedItem();
final ManagementNetworkOnClusterOperationParameters clusterOperationParameters =
new ManagementNetworkOnClusterOperationParameters(cluster, managementNetwork.getId());
final VdcActionType actionType = model.getIsNew() ? VdcActionType.AddCluster : VdcActionType.UpdateCluster;
Frontend.getInstance().runAction(
actionType,
clusterOperationParameters,
result -> {
ClusterListModel<Void> localModel = (ClusterListModel<Void>) result.getState();
if (model.getIsImportGlusterConfiguration().getEntity()) {
localModel.postOnSaveInternalWithImport(result.getReturnValue());
} else {
localModel.postOnSaveInternal(result.getReturnValue());
}
},
this);
}
private void fetchAndImportClusterHosts(final ClusterModel clusterModel) {
getWindow().startProgress();
AsyncQuery<VdcQueryReturnValue> aQuery = new AsyncQuery<>(result -> {
getWindow().stopProgress();
VdcQueryReturnValue returnValue = result;
if (returnValue == null) {
onEmptyGlusterHosts(clusterModel);
return;
}
else if (!returnValue.getSucceeded()) {
clusterModel.setMessage(Frontend.getInstance().getAppErrorsTranslator()
.translateErrorTextSingle(returnValue.getExceptionString()));
return;
}
Map<String, String> hostMap = returnValue.getReturnValue();
if (hostMap == null) {
onEmptyGlusterHosts(clusterModel);
return;
}
if (hostMap.containsValue(null) || hostMap.containsValue("")){ //$NON-NLS-1$
onGlusterHostsWithoutFingerprint(hostMap, clusterModel);
return;
}
ArrayList<EntityModel<HostDetailModel>> list = new ArrayList<>();
for (Map.Entry<String, String> host : hostMap.entrySet()) {
HostDetailModel hostModel = new HostDetailModel(host.getKey(), host.getValue());
hostModel.setName(host.getKey());
hostModel.setPassword("");//$NON-NLS-1$
EntityModel<HostDetailModel> entityModel = new EntityModel<>(hostModel);
list.add(entityModel);
}
importClusterHosts(clusterModel, list);
});
aQuery.setHandleFailure(true);
AsyncDataProvider.getInstance().getGlusterHosts(aQuery,
clusterModel.getGlusterHostAddress().getEntity(),
clusterModel.getGlusterHostPassword().getEntity(),
clusterModel.getGlusterHostFingerprint().getEntity());
}
private void onEmptyGlusterHosts(ClusterModel clusterModel) {
clusterModel.setMessage(ConstantsManager.getInstance().getConstants().emptyGlusterHosts());
}
private void onGlusterHostsWithoutFingerprint(Map<String, String> hostMap, ClusterModel clusterModel) {
ArrayList<String> problematicHosts = new ArrayList<>();
for (Map.Entry<String, String> host : hostMap.entrySet()) {
if (host.getValue() == null || host.getValue().equals("")) { //$NON-NLS-1$
problematicHosts.add(host.getKey());
}
}
clusterModel.setMessage(ConstantsManager.getInstance().getMessages().unreachableGlusterHosts(problematicHosts));
}
private void importClusterHosts(ClusterModel clusterModel, ArrayList<EntityModel<HostDetailModel>> hostList) {
setWindow(null);
getAddMultipleHostsCommand().execute();
final MultipleHostsModel hostsModel = new MultipleHostsModel();
setWindow(hostsModel);
hostsModel.setTitle(ConstantsManager.getInstance().getConstants().addMultipleHostsTitle());
hostsModel.setHelpTag(HelpTag.add_hosts);
hostsModel.setHashName("add_hosts"); //$NON-NLS-1$
hostsModel.setClusterModel(clusterModel);
hostsModel.getHosts().setItems(hostList);
UICommand command = UICommand.createOkUiCommand("OnSaveHosts", this); //$NON-NLS-1$
hostsModel.getCommands().add(command);
hostsModel.getCommands().add(UICommand.createCancelUiCommand("Cancel", this)); //$NON-NLS-1$
}
private void onSaveHosts() {
MultipleHostsModel hostsModel = (MultipleHostsModel) getWindow();
if(hostsModel == null) {
return;
}
if (!hostsModel.validate()) {
return;
}
if (hostsModel.getClusterModel().getClusterId() != null) {
addHosts(hostsModel);
}
else {
onSaveInternalWithModel(hostsModel.getClusterModel());
}
}
public void postOnSaveInternal(VdcReturnValueBase returnValue) {
ClusterModel model = (ClusterModel) getWindow();
model.stopProgress();
if (returnValue != null && returnValue.getSucceeded()) {
cancel();
if (model.getIsNew()) {
setGuideContext(returnValue.getActionReturnValue());
updateActionAvailability();
getGuideCommand().execute();
}
}
}
public void postOnSaveInternalWithImport(VdcReturnValueBase returnValue) {
MultipleHostsModel hostsModel = (MultipleHostsModel) getWindow();
if (returnValue != null && returnValue.getSucceeded()) {
hostsModel.getClusterModel().setClusterId((Guid) returnValue.getActionReturnValue());
addHosts(hostsModel);
}
}
private void addHosts(final MultipleHostsModel hostsModel) {
hostsModel.startProgress();
ArrayList<VdcActionParametersBase> parametersList = new ArrayList<>();
for (Object object : hostsModel.getHosts().getItems()) {
HostDetailModel hostDetailModel = (HostDetailModel) ((EntityModel) object).getEntity();
VDS host = new VDS();
host.setVdsName(hostDetailModel.getName());
host.setHostName(hostDetailModel.getAddress());
host.setSshKeyFingerprint(hostDetailModel.getFingerprint());
host.setPort(54321);
host.setSshPort(22); // TODO: get from UI, till then using defaults.
host.setSshUsername("root"); //$NON-NLS-1$
host.setClusterId(hostsModel.getClusterModel().getClusterId());
host.setPmEnabled(false);
AddVdsActionParameters parameters = new AddVdsActionParameters();
parameters.setVdsId(host.getId());
parameters.setvds(host);
parameters.setPassword(hostDetailModel.getPassword());
parameters.setOverrideFirewall(hostsModel.isConfigureFirewall());
parametersList.add(parameters);
}
// Todo: calling the runMultipleAction() with isRunOnlyIfAllValidationPass=false
// becuase this flag is now supported.
// should check what is the required behaviour and return to true if required.
Frontend.getInstance().runMultipleAction(VdcActionType.AddVds,
parametersList,
false,
result -> {
hostsModel.stopProgress();
boolean isAllValidatePassed = true;
for (VdcReturnValueBase returnValueBase : result.getReturnValue()) {
isAllValidatePassed = returnValueBase.isValid();
if (!isAllValidatePassed) {
break;
}
}
if (isAllValidatePassed) {
cancel();
}
}, null);
}
public void cancel() {
cancelConfirmation();
setGuideContext(null);
setWindow(null);
updateActionAvailability();
}
public void cancelConfirmation() {
setConfirmWindow(null);
}
@Override
protected void onSelectedItemChanged() {
super.onSelectedItemChanged();
updateActionAvailability();
}
@Override
protected void selectedItemsChanged() {
super.selectedItemsChanged();
updateActionAvailability();
}
@Override
protected void itemsCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) {
super.itemsCollectionChanged(sender, e);
// Try to select an item corresponding to the system tree selection.
if (getSystemTreeSelectedItem() != null && getSystemTreeSelectedItem().getType() == SystemTreeItemType.Cluster) {
Cluster cluster = (Cluster) getSystemTreeSelectedItem().getEntity();
setSelectedItem(Linq.firstOrNull(getItems(), new Linq.IdPredicate<>(cluster.getId())));
}
}
private void updateActionAvailability() {
getEditCommand().setIsExecutionAllowed(getSelectedItem() != null && getSelectedItems() != null
&& getSelectedItems().size() == 1);
getGuideCommand().setIsExecutionAllowed(getGuideContext() != null
|| (getSelectedItem() != null && getSelectedItems() != null && getSelectedItems().size() == 1));
getRemoveCommand().setIsExecutionAllowed(getSelectedItems() != null && getSelectedItems().size() > 0);
getResetEmulatedMachineCommand().setIsExecutionAllowed(
getSelectedItems() != null && getSelectedItems().size() > 0);
// System tree dependent actions.
boolean isAvailable =
!(getSystemTreeSelectedItem() != null &&
(getSystemTreeSelectedItem().getType() == SystemTreeItemType.Cluster || getSystemTreeSelectedItem().getType() == SystemTreeItemType.Cluster_Gluster));
getNewCommand().setIsAvailable(isAvailable);
getRemoveCommand().setIsAvailable(isAvailable);
}
@Override
public void executeCommand(UICommand command, Object... parameters) {
if (command == getEditCommand() && parameters.length > 0 && Boolean.TRUE.equals(parameters[0])) {
super.executeCommand(command, parameters);
} else if (command == getAddMacPoolCommand()) {
super.executeCommand(command, parameters);
addMacPool((ClusterModel) parameters[0]);
}
}
@Override
public void executeCommand(UICommand command) {
super.executeCommand(command);
if (command == getNewCommand()) {
newEntity();
}
else if (command == getEditCommand()) {
edit();
}
else if (command == getRemoveCommand()) {
remove();
}
else if (command == getGuideCommand()) {
guide();
}
else if (command == getResetEmulatedMachineCommand()) {
resetEmulatedMachine();
}
else if ("OnResetClusterEmulatedMachine".equals(command.getName())) { //$NON-NLS-1$
onResetClusterEmulatedMachine();
}
else if ("OnSave".equals(command.getName())) { //$NON-NLS-1$
onSave();
}
else if ("Cancel".equals(command.getName())) { //$NON-NLS-1$
cancel();
}
else if ("OnRemove".equals(command.getName())) { //$NON-NLS-1$
onRemove();
}
else if ("OnSaveConfirmCpuThreads".equals(command.getName())) { //$NON-NLS-1$
onSaveConfirmCpuThreads();
}
else if ("OnSaveConfirmGenericWarnings".equals(command.getName())) { //$NON-NLS-1$
onSaveConfirmGenericWarnings();
}
else if ("OnSaveInternal".equals(command.getName())) { //$NON-NLS-1$
onSaveInternal();
}
else if ("CancelConfirmation".equals(command.getName())) { //$NON-NLS-1$
cancelConfirmation();
}
else if ("OnSaveHosts".equals(command.getName())) { //$NON-NLS-1$
onSaveHosts();
}
}
private SystemTreeItemModel systemTreeSelectedItem;
@Override
public SystemTreeItemModel getSystemTreeSelectedItem() {
return systemTreeSelectedItem;
}
@Override
public void setSystemTreeSelectedItem(SystemTreeItemModel value) {
if (systemTreeSelectedItem != value) {
systemTreeSelectedItem = value;
onSystemTreeSelectedItemChanged();
}
}
private void onSystemTreeSelectedItemChanged() {
updateActionAvailability();
}
@Override
protected String getListName() {
return "ClusterListModel"; //$NON-NLS-1$
}
/**
* Checks if in selected cluster are some non responsive hosts. If so, it adds warning about upgrading cluster level
* when some hosts are non responsive
*/
@SuppressWarnings("unchecked")
private void checkForNonResponsiveHosts(final ConfirmationModel confirmModel) {
startProgress();
Frontend.getInstance().runQuery(VdcQueryType.GetHostsByClusterId,
new IdQueryParameters(getSelectedItem().getId()),
new AsyncQuery<>(returnValue -> {
List<VDS> hosts = null;
if (returnValue instanceof List) {
hosts = (List<VDS>) returnValue;
} else if (returnValue instanceof VdcQueryReturnValue
&& ((VdcQueryReturnValue) returnValue).getReturnValue() instanceof List) {
hosts = ((VdcQueryReturnValue) returnValue).getReturnValue();
}
boolean foundNRHosts = false;
if (hosts != null) {
for (VDS host : hosts) {
if (VDSStatus.NonResponsive == host.getStatus()) {
foundNRHosts = true;
break;
}
}
}
String existingMsg = confirmModel.getMessage() == null ? "" : confirmModel.getMessage();
if (foundNRHosts) {
confirmModel.setMessage(existingMsg +
constants.youAreAboutChangeClusterCompatibilityVersionNonResponsiveHostsMsg());
} else {
confirmModel.setMessage(existingMsg +
constants.youAreAboutChangeClusterCompatibilityVersionMsg());
}
stopProgress();
}));
}
}