package org.ovirt.engine.ui.uicommonweb.models.gluster; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.ovirt.engine.core.common.businessentities.gluster.GlusterBrickEntity; import org.ovirt.engine.core.common.businessentities.gluster.GlusterGeoRepNonEligibilityReason; import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity; 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.utils.Pair; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.ui.frontend.Frontend; import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider; import org.ovirt.engine.ui.uicommonweb.help.HelpTag; import org.ovirt.engine.ui.uicommonweb.models.EntityModel; import org.ovirt.engine.ui.uicommonweb.models.ListModel; import org.ovirt.engine.ui.uicommonweb.models.Model; import org.ovirt.engine.ui.uicommonweb.validation.IValidation; import org.ovirt.engine.ui.uicommonweb.validation.LengthValidation; import org.ovirt.engine.ui.uicommonweb.validation.NotEmptyValidation; import org.ovirt.engine.ui.uicompat.ConstantsManager; import org.ovirt.engine.ui.uicompat.EnumTranslator; import org.ovirt.engine.ui.uicompat.EventArgs; import org.ovirt.engine.ui.uicompat.IEventListener; import org.ovirt.engine.ui.uicompat.PropertyChangedEventArgs; import org.ovirt.engine.ui.uicompat.UIConstants; import org.ovirt.engine.ui.uicompat.UIMessages; public class GlusterVolumeGeoRepCreateModel extends Model{ private EntityModel<Boolean> showEligibleVolumes; private EntityModel<String> slaveUserName; private ListModel<GlusterVolumeEntity> slaveVolumes; private ListModel<String> slaveClusters; private ListModel<Pair<String, Guid>> slaveHosts; private EntityModel<Boolean> startSession; private String queryFailureMessage; private Collection<GlusterVolumeEntity> volumeList = new ArrayList<>(); private final UIConstants constants = ConstantsManager.getInstance().getConstants(); private final UIMessages messages = ConstantsManager.getInstance().getMessages(); private GlusterVolumeEntity masterVolume; private String recommendationViolations; private EntityModel<String> slaveUserGroupName; public GlusterVolumeGeoRepCreateModel(GlusterVolumeEntity masterVolume) { this.masterVolume = masterVolume; init(); initValueChangeListeners(); } private void initValueChangeListeners() { getShowEligibleVolumes().getEntityChangedEvent().addListener((ev, sender, args) -> { if (!getShowEligibleVolumes().getEntity()) { getVolumesForForceSessionCreate(); } else { getEligibleVolumes(); setRecommendationViolations(null); } }); IEventListener<EventArgs> clusterEventListener = (ev, sender, args) -> { String selectedCluster = getSlaveClusters().getSelectedItem(); List<GlusterVolumeEntity> volumesInCurrentCluster = new ArrayList<>(); if (selectedCluster != null) { volumesInCurrentCluster = getVolumesInCluster(selectedCluster, getVolumeList()); } if (volumesInCurrentCluster.size() > 0) { getSlaveVolumes().setItems(volumesInCurrentCluster, volumesInCurrentCluster.get(0)); } else { getSlaveVolumes().setItems(volumesInCurrentCluster); } }; getSlaveClusters().getSelectedItemChangedEvent().addListener(clusterEventListener); IEventListener<EventArgs> slaveVolumeEventListener = (ev, sender, args) -> { GlusterVolumeEntity selectedSlaveVolume = getSlaveVolumes().getSelectedItem(); Set<Pair<String, Guid>> hostsInCurrentVolume = new HashSet<>(); if (!getShowEligibleVolumes().getEntity() && selectedSlaveVolume != null) { updateRecommendatonViolations(); } if (selectedSlaveVolume != null) { hostsInCurrentVolume = getHostNamesForVolume(selectedSlaveVolume); } getSlaveHosts().setItems(hostsInCurrentVolume); }; getSlaveVolumes().getSelectedItemChangedEvent().addListener(slaveVolumeEventListener); getSlaveUserName().getEntityChangedEvent().addListener((ev, sender, args) -> { String slaveUser = getSlaveUserName().getEntity(); getSlaveUserGroupName().setIsChangeable( slaveUser != null && !slaveUser.equalsIgnoreCase(ConstantsManager.getInstance() .getConstants() .rootUser())); }); } public void getVolumesForForceSessionCreate() { GlusterVolumeGeoRepCreateModel.this.startProgress(constants.fetchingDataMessage()); SearchParameters volumesSearchParameters = new SearchParameters("Volumes:", SearchType.GlusterVolume, false);//$NON-NLS-1$ volumesSearchParameters.setRefresh(true); Frontend.getInstance().runQuery(VdcQueryType.Search, volumesSearchParameters, new AsyncQuery<VdcQueryReturnValue>(returnValue -> showAvailableVolumes(returnValue))); } private void showAvailableVolumes(VdcQueryReturnValue returnValue) { stopProgress(); if(!returnValue.getSucceeded()) { setQueryFailureMessage(returnValue.getExceptionString()); } else { setVolumeList((Collection) returnValue.getReturnValue()); Set<String> clusterForVolumes = getClusterForVolumes(getVolumeList()); getSlaveClusters().setItems(clusterForVolumes, clusterForVolumes.isEmpty() ? null : clusterForVolumes.iterator().next()); } } public void getEligibleVolumes() { this.startProgress(constants.fetchingDataMessage()); Frontend.getInstance().runQuery(VdcQueryType.GetGlusterGeoReplicationEligibleVolumes, new IdQueryParameters(masterVolume.getId()), new AsyncQuery<VdcQueryReturnValue>(returnValue -> showAvailableVolumes(returnValue))); } protected Set<String> getClusterForVolumes(Collection<GlusterVolumeEntity> eligibleVolumes) { Set<String> clusters = new HashSet<>(); for(GlusterVolumeEntity currentVolume : eligibleVolumes) { clusters.add(currentVolume.getClusterName()); } return clusters; } public List<GlusterVolumeEntity> getVolumesInCluster(String cluster, Collection<GlusterVolumeEntity> volumes) { List<GlusterVolumeEntity> volumesInCurrentCluster= new ArrayList<>(); for(GlusterVolumeEntity currentVolume : volumes) { if(currentVolume.getClusterName().equals(cluster)) { volumesInCurrentCluster.add(currentVolume); } } return volumesInCurrentCluster; } public Set<Pair<String, Guid>> getHostNamesForVolume(GlusterVolumeEntity volume) { Set<Pair<String, Guid>> hosts = new HashSet<>(); for(GlusterBrickEntity currentBrick : volume.getBricks()) { hosts.add(new Pair<>(currentBrick.getServerName(), currentBrick.getServerId())); } return hosts; } public ListModel<String> getSlaveClusters() { return slaveClusters; } public void setSlaveClusters(ListModel<String> slaveClusters) { this.slaveClusters = slaveClusters; } public ListModel<Pair<String, Guid>> getSlaveHosts() { return slaveHosts; } public void setSlaveHosts(ListModel<Pair<String, Guid>> slaveHosts) { this.slaveHosts = slaveHosts; } public Collection<GlusterVolumeEntity> getVolumeList() { return volumeList; } public void setVolumeList(Collection<GlusterVolumeEntity> volumeList) { this.volumeList = volumeList; onPropertyChanged(new PropertyChangedEventArgs("RecommendationViolations"));//$NON-NLS-1$ } private void init() { setTitle(constants.newGeoRepSessionTitle()); setHelpTag(HelpTag.volume_geo_rep_create); setHashName("volume_geo_rep_create");//$NON-NLS-1$ setShowEligibleVolumes(new EntityModel<Boolean>()); setSlaveClusters(new ListModel<String>()); setSlaveVolumes(new ListModel<GlusterVolumeEntity>()); setSlaveHosts(new ListModel<Pair<String, Guid>>()); setStartSession(new EntityModel<Boolean>()); setSlaveUserName(new EntityModel<>(constants.emptyString())); setSlaveUserGroupName(new EntityModel<String>()); } public EntityModel<String> getSlaveUserName() { return slaveUserName; } public void setSlaveUserName(EntityModel<String> slaveUserName) { this.slaveUserName = slaveUserName; } public ListModel<GlusterVolumeEntity> getSlaveVolumes() { return slaveVolumes; } public void setSlaveVolumes(ListModel<GlusterVolumeEntity> slaveVolumeSelected) { this.slaveVolumes = slaveVolumeSelected; } public EntityModel<Boolean> getStartSession() { return startSession; } public void setStartSession(EntityModel<Boolean> startSession) { this.startSession = startSession; } public EntityModel<Boolean> getShowEligibleVolumes() { return showEligibleVolumes; } public void setShowEligibleVolumes(EntityModel<Boolean> showEligibleVolumes) { this.showEligibleVolumes = showEligibleVolumes; } public GlusterVolumeEntity getMasterVolume() { return masterVolume; } public void setMasterVolume(GlusterVolumeEntity masterVolume) { this.masterVolume = masterVolume; } public String getRecommendationViolations() { return recommendationViolations; } public void setRecommendationViolations(String recommendationViolations) { this.recommendationViolations = recommendationViolations; onPropertyChanged(new PropertyChangedEventArgs("RecommendationViolations"));//$NON-NLS-1$ } public void updateRecommendatonViolations() { startProgress(constants.fetchingDataMessage()); AsyncDataProvider.getInstance().getGlusterVolumeGeoRepRecommendationViolations(new AsyncQuery<>( eligibilityViolators -> { stopProgress(); if(eligibilityViolators.size() > 0) { StringBuilder configViolations = new StringBuilder(constants.geoReplicationRecommendedConfigViolation()); for(GlusterGeoRepNonEligibilityReason currentViolator : eligibilityViolators) { configViolations.append("\n* ");//$NON-NLS-1$ configViolations.append(EnumTranslator.getInstance().translate(currentViolator)); } setRecommendationViolations(configViolations.toString()); } else { setRecommendationViolations(null); } }), masterVolume.getId(), getSlaveVolumes().getSelectedItem().getId()); } public boolean validate() { getSlaveVolumes().validateSelectedItem(new IValidation[] { new NotEmptyValidation(), new LengthValidation(128)}); getSlaveHosts().validateSelectedItem(new IValidation[] { new NotEmptyValidation(), new LengthValidation(128)}); return getSlaveVolumes().getIsValid() && getSlaveHosts().getIsValid(); } public String getQueryFailureMessage() { return queryFailureMessage; } public void setQueryFailureMessage(String queryFailureMessage) { this.queryFailureMessage = queryFailureMessage; onPropertyChanged(new PropertyChangedEventArgs("QueryFailed"));//$NON-NLS-1$ } public EntityModel<String> getSlaveUserGroupName() { return slaveUserGroupName; } public void setSlaveUserGroupName(EntityModel<String> slaveUserGroupName) { this.slaveUserGroupName = slaveUserGroupName; } }