package org.ovirt.engine.ui.uicommonweb.models.clusters;
import java.util.ArrayList;
import java.util.List;
import org.ovirt.engine.core.common.action.ChangeVDSClusterParameters;
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.VdsActionParameters;
import org.ovirt.engine.core.common.action.hostdeploy.AddVdsActionParameters;
import org.ovirt.engine.core.common.action.hostdeploy.ApproveVdsParameters;
import org.ovirt.engine.core.common.businessentities.Cluster;
import org.ovirt.engine.core.common.businessentities.StoragePool;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.VDSStatus;
import org.ovirt.engine.core.common.mode.ApplicationMode;
import org.ovirt.engine.ui.frontend.Frontend;
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.ApplicationModeHelper;
import org.ovirt.engine.ui.uicommonweb.models.ConfirmationModel;
import org.ovirt.engine.ui.uicommonweb.models.EntityModel;
import org.ovirt.engine.ui.uicommonweb.models.GuideModel;
import org.ovirt.engine.ui.uicommonweb.models.ListModel;
import org.ovirt.engine.ui.uicommonweb.models.hosts.HostModel;
import org.ovirt.engine.ui.uicommonweb.models.hosts.MoveHost;
import org.ovirt.engine.ui.uicommonweb.models.hosts.MoveHostData;
import org.ovirt.engine.ui.uicommonweb.models.hosts.NewHostModel;
import org.ovirt.engine.ui.uicompat.ConstantsManager;
import com.google.gwt.user.client.Timer;
public class ClusterGuideModel extends GuideModel<Cluster> {
//Action command names
private static final String ADD_DATA_CENTER = "AddDataCenter"; //$NON-NLS-1$
private static final String CANCEL_CONFIRM_WITH_FOCUS = "CancelConfirmWithFocus"; //$NON-NLS-1$
private static final String CANCEL_CONFIRM = "CancelConfirm"; //$NON-NLS-1$
private static final String CANCEL = "Cancel"; //$NON-NLS-1$
private static final String ON_SELECT_HOST = "OnSelectHost"; //$NON-NLS-1$
private static final String SELECT_HOST = "SelectHost"; //$NON-NLS-1$
private static final String ON_ADD_HOST = "OnAddHost"; //$NON-NLS-1$
private static final String ON_CONFIRM_PM_HOST = "OnConfirmPMHost"; //$NON-NLS-1$
private static final String ADD_HOST = "AddHost"; //$NON-NLS-1$
private static final String ON_ADD_DATACENTER = "OnAddDataCenter"; //$NON-NLS-1$
//Pop-up and button titles.
private final String clusterConfigureHostsActionTitle =
ConstantsManager.getInstance().getConstants().configureHostClusterGuide();
private final String clusterAddAnotherHostActionTitle =
ConstantsManager.getInstance().getConstants().addAnotherHostClusterGuide();
private final String selectHostsActionTitle =
ConstantsManager.getInstance().getConstants().selectHostsClusterGuide();
private final String addDataCenterTitle = ConstantsManager.getInstance().getConstants().addDataCenter();
private final String noAvailableActions = ConstantsManager.getInstance().getConstants().guidePopupNoActionsLabel();
@Override
protected void onEntityChanged() {
super.onEntityChanged();
updateOptions();
}
private List<VDS> hosts;
private List<VDS> allHosts;
private Boolean isAnyHostUpInCluster;
private VDS localStorageHost;
private StoragePool dataCenter;
private void updateOptionsNonLocalFSData() {
AsyncDataProvider.getInstance().getHostListByCluster(new AsyncQuery<>(
returnValue -> {
hosts = returnValue;
updateOptionsNonLocalFS();
}), getEntity().getName());
AsyncDataProvider.getInstance().getHostList(new AsyncQuery<>(returnValue -> {
allHosts = returnValue;
updateOptionsNonLocalFS();
}
));
if (getEntity().supportsGlusterService()) {
AsyncDataProvider.getInstance().isAnyHostUpInCluster(new AsyncQuery<>(
returnValue -> {
isAnyHostUpInCluster = returnValue;
updateOptionsNonLocalFS();
}), getEntity().getName());
}
}
private void updateOptionsLocalFSData() {
AsyncDataProvider.getInstance().getLocalStorageHost(new AsyncQuery<>(
returnValue -> {
localStorageHost = returnValue;
updateOptionsLocalFS();
}), dataCenter.getName());
}
private void updateOptionsNonLocalFS() {
if (hosts == null || allHosts == null || !isUpHostCheckCompleted()) {
return;
}
if (getEntity() == null) {
stopProgress();
setWindow(null);
return;
}
// Add host action.
UICommand addHostAction = new UICommand(ADD_HOST, this);
if (hosts.size() > 1) {
hosts.remove(0);
}
if (hosts.isEmpty()) {
addHostAction.setTitle(clusterConfigureHostsActionTitle);
getCompulsoryActions().add(addHostAction);
} else if (isAnyUpHostInCluster()) {
addHostAction.setTitle(clusterAddAnotherHostActionTitle);
getOptionalActions().add(addHostAction);
}
if (getEntity().getStoragePoolId() == null) {
addHostAction.getExecuteProhibitionReasons().add(ConstantsManager.getInstance()
.getConstants()
.theClusterIsntAttachedToADcClusterGuide());
addHostAction.setIsExecutionAllowed(false);
return;
}
ArrayList<VDS> availableHosts = new ArrayList<>();
for (VDS vds : allHosts) {
if (!getEntity().getId().equals(vds.getClusterId())
&& (vds.getStatus() == VDSStatus.Maintenance || vds.getStatus() == VDSStatus.PendingApproval)
&& vds.getSupportedClusterVersionsSet() != null
&& vds.getSupportedClusterVersionsSet().contains(getEntity().getCompatibilityVersion())) {
availableHosts.add(vds);
}
}
// Select host action.
UICommand selectHostAction = new UICommand(SELECT_HOST, this);
if (availableHosts.size() > 0) {
if (hosts.isEmpty()) {
selectHostAction.setTitle(selectHostsActionTitle);
getCompulsoryActions().add(selectHostAction);
} else if (isAnyUpHostInCluster()) {
selectHostAction.setTitle(selectHostsActionTitle);
getOptionalActions().add(selectHostAction);
}
}
stopProgress();
}
private void updateOptionsLocalFS() {
UICommand addHostAction = new UICommand(ADD_HOST, this);
addHostAction.setTitle(clusterAddAnotherHostActionTitle);
UICommand selectHost = new UICommand(SELECT_HOST, this);
selectHost.setTitle(selectHostsActionTitle);
if (localStorageHost != null) {
String hasHostReason =
ConstantsManager.getInstance()
.getConstants()
.thisClusterBelongsToALocalDcWhichAlreadyContainHostClusterGuide();
addHostAction.getExecuteProhibitionReasons().add(hasHostReason);
addHostAction.setIsExecutionAllowed(false);
selectHost.getExecuteProhibitionReasons().add(hasHostReason);
selectHost.setIsExecutionAllowed(false);
getNote().setIsAvailable(true);
getNote().setEntity(ConstantsManager.getInstance().getConstants().attachLocalStorageDomainToFullyConfigure());
}
getCompulsoryActions().add(addHostAction);
getOptionalActions().add(selectHost);
stopProgress();
}
private void updateOptions() {
getCompulsoryActions().clear();
getOptionalActions().clear();
if (getEntity() == null) {
return;
}
startProgress();
if (getEntity().getStoragePoolId() != null) {
//Datacenter associated with this cluster.
AsyncDataProvider.getInstance().getDataCenterById(new AsyncQuery<>(returnValue -> {
dataCenter = returnValue;
if (dataCenter == null || !dataCenter.isLocal()) {
updateOptionsNonLocalFSData();
} else {
updateOptionsLocalFSData();
}
}), getEntity().getStoragePoolId());
} else {
//No data-center associated with this cluster.
AsyncDataProvider.getInstance().getDataCenterList(new AsyncQuery<>(dataCenters -> {
@SuppressWarnings("unchecked")
final List<StoragePool> localDataCenters = new ArrayList<>();
boolean enableButton = false;
for (StoragePool dataCenter: dataCenters) {
//Find at least one compatible data-center, so we can show the button.
if (getEntity().getCompatibilityVersion().compareTo(
dataCenter.getCompatibilityVersion()) >= 0 ) {
if (dataCenter.isLocal()) {
//Check if there are any clusters associated with this data-center already.
localDataCenters.add(dataCenter);
} else {
enableButton = true;
break;
}
}
}
if (enableButton || localDataCenters.isEmpty()) {
updateOptionsRequiredAddDataCenter(enableButton);
} else {
updateOptionsRequiredAddDataCenter(localDataCenters);
}
}
));
}
}
protected void updateOptionsRequiredAddDataCenter(final List<StoragePool> localDataCenters) {
AsyncDataProvider.getInstance().getClusterList(new AsyncQuery<>(
clusters -> {
List<StoragePool> localDataCenterWithCluster = new ArrayList<>();
for (StoragePool dataCenter: localDataCenters) {
for (Cluster cluster: clusters) {
if (cluster.getStoragePoolId() != null &&
cluster.getStoragePoolId().equals(dataCenter.getId())) {
localDataCenterWithCluster.add(dataCenter);
break;
}
}
}
localDataCenters.removeAll(localDataCenterWithCluster);
updateOptionsRequiredAddDataCenter(!localDataCenters.isEmpty());
})
);
}
protected void updateOptionsRequiredAddDataCenter(boolean enableButton) {
if (enableButton) {
// Add data-center action.
UICommand addDataCenterAction = new UICommand(ADD_DATA_CENTER, this);
addDataCenterAction.setTitle(addDataCenterTitle);
addDataCenterAction.setIsAvailable(enableButton);
getOptionalActions().add(addDataCenterAction);
} else {
setNote(new EntityModel<>(noAvailableActions));
}
stopProgress();
}
private boolean isUpHostCheckCompleted() {
if (!getEntity().supportsGlusterService()) {
return true;
}
return isAnyHostUpInCluster != null;
}
private boolean isAnyUpHostInCluster() {
if (!getEntity().supportsGlusterService()) {
return true;
}
return isAnyHostUpInCluster;
}
private void resetData() {
hosts = null;
allHosts = null;
localStorageHost = null;
dataCenter = null;
isAnyHostUpInCluster = null;
}
public void selectHost() {
final ArrayList<Cluster> clusters = new ArrayList<>();
clusters.add(getEntity());
final MoveHost model = new MoveHost();
model.setTitle(ConstantsManager.getInstance().getConstants().selectHostTitle());
model.setHelpTag(HelpTag.select_host);
model.setHashName("select_host"); //$NON-NLS-1$
// In case of local storage, only one host is allowed in the cluster so we should disable multi selection
AsyncDataProvider.getInstance().getDataCenterById(new AsyncQuery<>(
dataCenter -> {
boolean isMultiHostDC = dataCenter.isLocal();
if (isMultiHostDC) {
model.setMultiSelection(false);
}
setWindow(model);
model.getCluster().setItems(clusters);
model.getCluster().setSelectedItem(Linq.firstOrNull(clusters));
model.getCluster().setIsAvailable(false);
UICommand tempVar = UICommand.createDefaultOkUiCommand("OnSelectHost", ClusterGuideModel.this); //$NON-NLS-1$
model.getCommands().add(tempVar);
UICommand tempVar2 = UICommand.createCancelUiCommand("Cancel", ClusterGuideModel.this); //$NON-NLS-1$
model.getCommands().add(tempVar2);
}), getEntity().getStoragePoolId());
}
public void onSelectHost() {
MoveHost model = (MoveHost) getWindow();
if (model.getProgress() != null) {
return;
}
if (!model.validate()) {
return;
}
model.setSelectedHosts(new ArrayList<MoveHostData>());
for (EntityModel a : model.getItems()) {
if (a.getIsSelected()) {
model.getSelectedHosts().add((MoveHostData) a);
}
}
Cluster cluster = model.getCluster().getSelectedItem();
final List<VdcActionParametersBase> parameterList = new ArrayList<>();
for (MoveHostData hostData : model.getSelectedHosts()) {
VDS host = hostData.getEntity();
// Try to change host's cluster as neccessary.
if (host.getClusterId() != null && !host.getClusterId().equals(cluster.getId())) {
parameterList.add(new ChangeVDSClusterParameters(cluster.getId(), host.getId()));
}
}
model.startProgress();
Frontend.getInstance().runMultipleAction(VdcActionType.ChangeVDSCluster, parameterList,
result -> {
List<MoveHostData> hosts = ((MoveHost) getWindow()).getSelectedHosts();
List<VdcReturnValueBase> retVals = result.getReturnValue();
final List<VdcActionParametersBase> activateVdsParameterList = new ArrayList<>();
if (retVals != null && hosts.size() == retVals.size()) {
int i = 0;
for (MoveHostData selectedHostData : hosts) {
VDS selectedHost= selectedHostData.getEntity();
if (selectedHost.getStatus() == VDSStatus.PendingApproval && retVals.get(i) != null
&& retVals.get(i).getSucceeded()) {
Frontend.getInstance().runAction(VdcActionType.ApproveVds,
new ApproveVdsParameters(selectedHost.getId()));
} else if (selectedHostData.getActivateHost()) {
activateVdsParameterList.add(new VdsActionParameters(selectedHostData.getEntity().getId()));
}
i++;
}
}
if (activateVdsParameterList.isEmpty()) {
getWindow().stopProgress();
cancel();
postAction();
} else {
final String searchString = getVdsSearchString((MoveHost) getWindow());
Timer timer = new Timer() {
public void run() {
checkVdsClusterChangeSucceeded(searchString, parameterList, activateVdsParameterList);
}
};
timer.schedule(2000);
}
},
this);
}
private void addDataCenter() {
AsyncDataProvider.getInstance().getDataCenterList(new AsyncQuery<>(allDataCenters -> {
@SuppressWarnings("unchecked")
List<EntityModel<StoragePool>> filteredDataCenters = new ArrayList<>();
List<StoragePool> localDataCenters = new ArrayList<>();
for (StoragePool dataCenter: allDataCenters) {
//Find at least one compatible data-center, so we can show the button.
if (getEntity().getCompatibilityVersion().compareTo(
dataCenter.getCompatibilityVersion()) >= 0) {
if (dataCenter.isLocal()) {
//Check if there are any clusters associated with this data-center already.
localDataCenters.add(dataCenter);
} else {
filteredDataCenters.add(new EntityModel<>(dataCenter));
}
}
}
if (localDataCenters.isEmpty()) {
displayAddDataCenter(filteredDataCenters);
} else {
verifyLocalDataCenterNoCluster(filteredDataCenters, localDataCenters);
}
}
));
}
private void verifyLocalDataCenterNoCluster(final List<EntityModel<StoragePool>> filteredDataCenters,
final List<StoragePool> localDataCenters) {
AsyncDataProvider.getInstance().getClusterList(new AsyncQuery<>(clusters -> {
List<StoragePool> localDataCenterWithCluster = new ArrayList<>();
for (StoragePool dataCenter: localDataCenters) {
for (Cluster cluster: clusters) {
if (cluster.getStoragePoolId() != null &&
cluster.getStoragePoolId().equals(dataCenter.getId())) {
localDataCenterWithCluster.add(dataCenter);
break;
}
}
}
localDataCenters.removeAll(localDataCenterWithCluster);
for (StoragePool dataCenter: localDataCenters) {
filteredDataCenters.add(new EntityModel<>(dataCenter));
}
displayAddDataCenter(filteredDataCenters);
})
);
}
private void displayAddDataCenter(List<EntityModel<StoragePool>> dataCenters) {
ListModel<EntityModel<StoragePool>> dataCentersModel = new ListModel<>();
dataCentersModel.setItems(dataCenters);
dataCentersModel.setTitle(addDataCenterTitle);
dataCentersModel.setHashName("add_datacenter"); //$NON-NLS-1$
setWindow(dataCentersModel);
UICommand tempVar = UICommand.createDefaultOkUiCommand(ON_ADD_DATACENTER, ClusterGuideModel.this);
dataCentersModel.getCommands().add(tempVar);
UICommand tempVar2 = UICommand.createCancelUiCommand(CANCEL, ClusterGuideModel.this);
dataCentersModel.getCommands().add(tempVar2);
}
public void addHost() {
HostModel model = new NewHostModel();
setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().newHostTitle());
model.setHelpTag(HelpTag.new_host);
model.setHashName("new_host"); //$NON-NLS-1$
model.getPort().setEntity(54321);
model.getOverrideIpTables().setEntity(true);
model.setSpmPriorityValue(null);
model.getCluster().setSelectedItem(getEntity());
model.getCluster().setIsChangeable(false);
AsyncDataProvider.getInstance().getDataCenterList(new AsyncQuery<>(dataCenters -> {
HostModel model1 = (HostModel) getWindow();
model1.getDataCenter().setItems(dataCenters);
if (getEntity().getStoragePoolId() != null) {
model1.getDataCenter().setSelectedItem(Linq.firstOrNull(dataCenters,
new Linq.IdPredicate<>(getEntity().getStoragePoolId())));
}
model1.getDataCenter().setIsChangeable(false);
UICommand tempVar = UICommand.createDefaultOkUiCommand("OnConfirmPMHost", ClusterGuideModel.this); //$NON-NLS-1$
model1.getCommands().add(tempVar);
UICommand tempVar2 = UICommand.createCancelUiCommand("Cancel", ClusterGuideModel.this); //$NON-NLS-1$
model1.getCommands().add(tempVar2);
}));
}
public void onConfirmPMHost() {
HostModel model = (HostModel) getWindow();
if (!model.validate()) {
return;
}
if (!model.getIsPm().getEntity()
&& ApplicationModeHelper.getUiMode() != ApplicationMode.GlusterOnly) {
ConfirmationModel confirmModel = new ConfirmationModel();
setConfirmWindow(confirmModel);
confirmModel.setTitle(ConstantsManager.getInstance().getConstants().powerManagementConfigurationTitle());
confirmModel.setHelpTag(HelpTag.power_management_configuration);
confirmModel.setHashName("power_management_configuration"); //$NON-NLS-1$
confirmModel.setMessage(ConstantsManager.getInstance().getConstants().youHavntConfigPmMsg());
UICommand tempVar = UICommand.createDefaultOkUiCommand("OnAddHost", this); //$NON-NLS-1$
confirmModel.getCommands().add(tempVar);
UICommand tempVar2 = UICommand.createCancelUiCommand("CancelConfirmWithFocus", this); //$NON-NLS-1$
confirmModel.getCommands().add(tempVar2);
} else {
onAddHost();
}
}
public void onAddDataCenter() {
@SuppressWarnings("unchecked")
ListModel<EntityModel<StoragePool>> dataCentersModel = (ListModel<EntityModel<StoragePool>>)getWindow();
EntityModel<StoragePool> dataCenter = dataCentersModel.getSelectedItem();
if (dataCenter != null) {
Cluster cluster = getEntity();
cluster.setStoragePoolId(dataCenter.getEntity().getId());
dataCentersModel.startProgress();
Frontend.getInstance().runAction(VdcActionType.UpdateCluster, new ManagementNetworkOnClusterOperationParameters(cluster),
result -> {
if (result.getReturnValue() != null && result.getReturnValue().getSucceeded()) {
//Succeeded, close this window.
ClusterGuideModel guideModel = (ClusterGuideModel) result.getState();
guideModel.postAction();
}
//Close popup window.
setWindow(null);
},
this);
} else {
setWindow(null);
}
}
public void onAddHost() {
cancelConfirm();
HostModel model = (HostModel) getWindow();
if (model.getProgress() != null) {
return;
}
if (!model.validate()) {
return;
}
// Save changes.
VDS host = new VDS();
host.setVdsName(model.getName().getEntity());
host.setHostName(model.getHost().getEntity());
host.setPort(model.getPort().getEntity());
host.setSshPort(model.getAuthSshPort().getEntity());
host.setSshUsername(model.getUserName().getEntity());
host.setSshKeyFingerprint(model.getFetchSshFingerprint().getEntity());
host.setClusterId(model.getCluster().getSelectedItem().getId());
host.setVdsSpmPriority(model.getSpmPriorityValue());
// Save other PM parameters.
host.setPmEnabled(model.getIsPm().getEntity());
host.setDisablePowerManagementPolicy(model.getDisableAutomaticPowerManagement().getEntity());
host.setPmKdumpDetection(model.getPmKdumpDetection().getEntity());
AddVdsActionParameters vdsActionParams = new AddVdsActionParameters();
vdsActionParams.setvds(host);
vdsActionParams.setVdsId(host.getId());
if (model.getUserPassword().getEntity() != null) {
vdsActionParams.setPassword(model.getUserPassword().getEntity());
}
vdsActionParams.setAuthMethod(model.getAuthenticationMethod());
vdsActionParams.setOverrideFirewall(model.getOverrideIpTables().getEntity());
vdsActionParams.setFenceAgents(model.getFenceAgentListModel().getFenceAgents());
model.startProgress();
Frontend.getInstance().runAction(VdcActionType.AddVds, vdsActionParams,
result -> {
ClusterGuideModel localModel = (ClusterGuideModel) result.getState();
localModel.postOnAddHost(result.getReturnValue());
}, this);
}
public void postOnAddHost(VdcReturnValueBase returnValue) {
HostModel model = (HostModel) getWindow();
model.stopProgress();
if (returnValue != null && returnValue.getSucceeded()) {
cancel();
postAction();
}
}
@Override
protected void postAction() {
resetData();
updateOptions();
}
protected void cancel() {
resetData();
setWindow(null);
}
public void cancelConfirm() {
setConfirmWindow(null);
}
public void cancelConfirmWithFocus() {
setConfirmWindow(null);
HostModel hostModel = (HostModel) getWindow();
hostModel.setIsPowerManagementTabSelected(true);
}
@Override
public void executeCommand(UICommand command) {
super.executeCommand(command);
if (ADD_HOST.equals(command.getName())) {
addHost();
}
if (ON_CONFIRM_PM_HOST.equals(command.getName())) {
onConfirmPMHost();
}
if (ON_ADD_HOST.equals(command.getName())) {
onAddHost();
}
if (SELECT_HOST.equals(command.getName())) {
selectHost();
}
if (ON_SELECT_HOST.equals(command.getName())) {
onSelectHost();
}
if (CANCEL.equals(command.getName())) {
cancel();
}
if (CANCEL_CONFIRM.equals(command.getName())) {
cancelConfirm();
}
if (CANCEL_CONFIRM_WITH_FOCUS.equals(command.getName())) {
cancelConfirmWithFocus();
}
if (ADD_DATA_CENTER.equals(command.getName())) {
addDataCenter();
}
if (ON_ADD_DATACENTER.equals(command.getName())) {
onAddDataCenter();
}
}
}