package org.ovirt.engine.ui.uicommonweb.models;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.ovirt.engine.core.common.businessentities.Cluster;
import org.ovirt.engine.core.common.businessentities.Erratum;
import org.ovirt.engine.core.common.businessentities.Provider;
import org.ovirt.engine.core.common.businessentities.StorageDomain;
import org.ovirt.engine.core.common.businessentities.StoragePool;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.comparators.LexoNumericNameableComparator;
import org.ovirt.engine.core.common.businessentities.comparators.NameableComparator;
import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity;
import org.ovirt.engine.core.common.businessentities.network.Network;
import org.ovirt.engine.core.common.mode.ApplicationMode;
import org.ovirt.engine.core.common.queries.IdQueryParameters;
import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.ui.frontend.AsyncCallback;
import org.ovirt.engine.ui.frontend.Frontend;
import org.ovirt.engine.ui.uicommonweb.UICommand;
import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
import org.ovirt.engine.ui.uicompat.ConstantsManager;
import org.ovirt.engine.ui.uicompat.Event;
import org.ovirt.engine.ui.uicompat.EventArgs;
import org.ovirt.engine.ui.uicompat.EventDefinition;
import org.ovirt.engine.ui.uicompat.FrontendMultipleQueryAsyncResult;
import org.ovirt.engine.ui.uicompat.IFrontendMultipleQueryAsyncCallback;
import org.ovirt.engine.ui.uicompat.PropertyChangedEventArgs;
public class SystemTreeModel extends SearchableListModel<Void, SystemTreeItemModel> implements IFrontendMultipleQueryAsyncCallback {
public static final EventDefinition resetRequestedEventDefinition;
public static final EventDefinition beforeItemsChangedEventDefinition;
private Event<EventArgs> privateResetRequestedEvent;
private Event<EventArgs> privateBeforeItemsChangedEvent;
public Event<EventArgs> getResetRequestedEvent() {
return privateResetRequestedEvent;
}
private void setResetRequestedEvent(Event<EventArgs> value) {
privateResetRequestedEvent = value;
}
public Event<EventArgs> getBeforeItemsChangedEvent() {
return privateBeforeItemsChangedEvent;
}
private void setBeforeItemsChangedEvent(Event<EventArgs> value) {
privateBeforeItemsChangedEvent = value;
}
private UICommand privateResetCommand;
public UICommand getResetCommand() {
return privateResetCommand;
}
private void setResetCommand(UICommand value) {
privateResetCommand = value;
}
private UICommand privateExpandAllCommand;
public UICommand getExpandAllCommand() {
return privateExpandAllCommand;
}
private void setExpandAllCommand(UICommand value) {
privateExpandAllCommand = value;
}
private UICommand privateCollapseAllCommand;
public UICommand getCollapseAllCommand() {
return privateCollapseAllCommand;
}
private void setCollapseAllCommand(UICommand value) {
privateCollapseAllCommand = value;
}
@Override
public ArrayList<SystemTreeItemModel> getItems() {
return (ArrayList<SystemTreeItemModel>) super.getItems();
}
@Override
public void setItems(Collection<SystemTreeItemModel> value) {
getBeforeItemsChangedEvent().raise(this, EventArgs.EMPTY);
super.setItems(value);
}
public void setItems(ArrayList<SystemTreeItemModel> value) {
if (items != value) {
itemsChanging(value, items);
items = value;
itemsChanged();
getItemsChangedEvent().raise(this, EventArgs.EMPTY);
onPropertyChanged(new PropertyChangedEventArgs("Items")); //$NON-NLS-1$
}
}
private List<StoragePool> privateDataCenters;
public List<StoragePool> getDataCenters() {
return privateDataCenters;
}
public void setDataCenters(List<StoragePool> value) {
privateDataCenters = value;
}
private List<Provider> privateProviders;
private List<Provider> getProviders() {
return privateProviders;
}
private void setProviders(List<Provider> value) {
privateProviders = value;
}
private List<Erratum> privateErrata;
public List<Erratum> getErrata() {
return privateErrata;
}
public void setErrata(List<Erratum> value) {
privateErrata = value;
}
private HashMap<Guid, ArrayList<Cluster>> privateClusterMap;
public HashMap<Guid, ArrayList<Cluster>> getClusterMap() {
return privateClusterMap;
}
public void setClusterMap(HashMap<Guid, ArrayList<Cluster>> value) {
privateClusterMap = value;
}
private Map<Guid, List<Network>> networkMap;
public Map<Guid, List<Network>> getNetworkMap() {
return networkMap;
}
public void setNetworkMap(Map<Guid, List<Network>> value) {
networkMap = value;
}
private HashMap<Guid, ArrayList<VDS>> privateHostMap;
public HashMap<Guid, ArrayList<VDS>> getHostMap() {
return privateHostMap;
}
public void setHostMap(HashMap<Guid, ArrayList<VDS>> value) {
privateHostMap = value;
}
private HashMap<Guid, ArrayList<GlusterVolumeEntity>> privateVolumeMap;
public HashMap<Guid, ArrayList<GlusterVolumeEntity>> getVolumeMap() {
return privateVolumeMap;
}
public void setVolumeMap(HashMap<Guid, ArrayList<GlusterVolumeEntity>> value) {
privateVolumeMap = value;
}
private Map<Guid, SystemTreeItemModel> treeItemById;
public SystemTreeItemModel getItemById(Guid id) {
return treeItemById.get(id);
}
static {
resetRequestedEventDefinition = new EventDefinition("ResetRequested", SystemTreeModel.class); //$NON-NLS-1$
beforeItemsChangedEventDefinition = new EventDefinition("BeforeItemsChanged", //$NON-NLS-1$
SystemTreeModel.class);
}
public SystemTreeModel() {
setResetRequestedEvent(new Event<>(resetRequestedEventDefinition));
setBeforeItemsChangedEvent(new Event<>(beforeItemsChangedEventDefinition));
setResetCommand(new UICommand("Reset", this)); //$NON-NLS-1$
setExpandAllCommand(new UICommand("ExpandAll", this)); //$NON-NLS-1$
setCollapseAllCommand(new UICommand("CollapseAll", this)); //$NON-NLS-1$
setIsTimerDisabled(true);
setItems(new ArrayList<SystemTreeItemModel>());
}
@Override
protected void syncSearch() {
super.syncSearch();
doDataCenterSearch();
doClusterSearch();
doHostSearch();
doVolumeSearch();
doProviderSearch();
//Stop the timer if it is running. syncSearch only gets called by either a manual refresh and the timer
//shouldn't run during that, or during a fast forward, and that restarts the timer each cycle.
getTimer().stop();
}
/**
* Create and run the query for all data centers.
*/
private void doDataCenterSearch() {
AsyncDataProvider.getInstance().getDataCenterList(new AsyncQuery<>(result -> {
setDataCenters(result);
//These need to be here so we can get data center ids for use in the queries.
doNetworksSearch();
}), false);
}
/**
* Create and run the query for all clusters.
*/
private void doClusterSearch() {
AsyncDataProvider.getInstance().getClusterList(new AsyncQuery<>((AsyncCallback<List<Cluster>>) clusters -> {
setClusterMap(new HashMap<Guid, ArrayList<Cluster>>());
for (Cluster cluster : clusters) {
if (cluster.getStoragePoolId() != null) {
Guid key = cluster.getStoragePoolId();
if (!getClusterMap().containsKey(key)) {
getClusterMap().put(key, new ArrayList<Cluster>());
}
List<Cluster> list = getClusterMap().get(key);
list.add(cluster);
}
}
}), false);
}
/**
* Create and run the query for all hosts.
*/
private void doHostSearch() {
AsyncDataProvider.getInstance().getHostList(new AsyncQuery<>(hosts -> {
setHostMap(new HashMap<Guid, ArrayList<VDS>>());
for (VDS host : hosts) {
Guid key = host.getClusterId();
if (!getHostMap().containsKey(key)) {
getHostMap().put(key, new ArrayList<VDS>());
}
List<VDS> list = getHostMap().get(key);
list.add(host);
}
}), false);
}
/**
* Create and run the query for all volumes.
*/
private void doVolumeSearch() {
AsyncQuery<List<GlusterVolumeEntity>> volumeQuery = new AsyncQuery<>(volumes -> {
setVolumeMap(new HashMap<Guid, ArrayList<GlusterVolumeEntity>>());
for (GlusterVolumeEntity volume : volumes) {
Guid key = volume.getClusterId();
if (!getVolumeMap().containsKey(key)) {
getVolumeMap().put(key, new ArrayList<GlusterVolumeEntity>());
}
List<GlusterVolumeEntity> list = getVolumeMap().get(key);
list.add(volume);
}
});
AsyncDataProvider.getInstance().getVolumeList(volumeQuery, null, false);
}
/**
* Create and run the query for all networks.
*/
private void doNetworksSearch() {
// Networks
ArrayList<VdcQueryType> queryTypeList = new ArrayList<>();
ArrayList<VdcQueryParametersBase> queryParamList = new ArrayList<>();
for (StoragePool dataCenter : getDataCenters()) {
queryTypeList.add(VdcQueryType.GetAllNetworks);
queryParamList.add(new IdQueryParameters(dataCenter.getId()));
}
Frontend.getInstance().runMultipleQueries(queryTypeList, queryParamList,
result -> {
setNetworkMap(new HashMap<Guid, List<Network>>());
List<VdcQueryReturnValue> returnValueList = result.getReturnValues();
List<Network> dcNetworkList;
Guid dcId;
for (int i = 0; i < returnValueList.size(); i++) {
VdcQueryReturnValue returnValue = returnValueList.get(i);
if (returnValue.getSucceeded() && returnValue.getReturnValue() != null) {
dcNetworkList = returnValue.getReturnValue();
dcId = getDataCenters().get(i).getId();
getNetworkMap().put(dcId, dcNetworkList);
}
}
doStorageSearch();
});
}
/**
* Create and run the query for all storage domains.
*/
private void doStorageSearch() {
// Storages
ArrayList<VdcQueryType> queryTypeList = new ArrayList<>();
ArrayList<VdcQueryParametersBase> queryParamList = new ArrayList<>();
for (StoragePool dataCenter : getDataCenters()) {
queryTypeList.add(VdcQueryType.GetStorageDomainsByStoragePoolId);
queryParamList.add(new IdQueryParameters(dataCenter.getId()));
}
if ((ApplicationModeHelper.getUiMode().getValue() & ApplicationMode.VirtOnly.getValue()) == 0) {
FrontendMultipleQueryAsyncResult dummyResult = new FrontendMultipleQueryAsyncResult();
VdcQueryReturnValue value = new VdcQueryReturnValue();
value.setSucceeded(true);
dummyResult.getReturnValues().add(value);
SystemTreeModel.this.executed(dummyResult);
} else {
Frontend.getInstance().runMultipleQueries(queryTypeList, queryParamList, this);
}
}
/**
* Create and run the query for all providers.
*/
private void doProviderSearch() {
AsyncDataProvider.getInstance().getAllProviders(new AsyncQuery<>(returnValue -> setProviders((List) returnValue)), false);
}
@Override
public void executeCommand(UICommand command) {
super.executeCommand(command);
if (command == getResetCommand()) {
reset();
}
else if (command == getExpandAllCommand()) {
expandAll();
}
else if (command == getCollapseAllCommand()) {
collapseAll();
}
}
private void collapseAll() {
setIsExpandedRecursively(false, getItems().get(0));
}
private void expandAll() {
setIsExpandedRecursively(true, getItems().get(0));
}
private void setIsExpandedRecursively(boolean value, SystemTreeItemModel root) {
root.setIsExpanded(value);
for (SystemTreeItemModel model : root.getChildren()) {
setIsExpandedRecursively(value, model);
}
}
private void reset() {
getResetRequestedEvent().raise(this, EventArgs.EMPTY);
}
@Override
public void executed(FrontendMultipleQueryAsyncResult result) {
List<StorageDomain> storageDomains = null;
int count = -1;
treeItemById = new HashMap<>();
// Build tree items.
SystemTreeItemModel systemItem = new SystemTreeItemModel();
systemItem.setType(SystemTreeItemType.System);
systemItem.setIsSelected(true);
systemItem.setTitle(ConstantsManager.getInstance().getConstants().systemTitle());
// Add Data Centers node under System
SystemTreeItemModel dataCentersItem = new SystemTreeItemModel();
dataCentersItem.setType(SystemTreeItemType.DataCenters);
dataCentersItem.setApplicationMode(ApplicationMode.VirtOnly);
dataCentersItem.setTitle(ConstantsManager.getInstance().getConstants().dataCentersTitle());
systemItem.addChild(dataCentersItem);
// Populate everything under Data Centers
for (VdcQueryReturnValue returnValue : result.getReturnValues()) {
++count;
if (!returnValue.getSucceeded()) {
continue;
}
storageDomains = returnValue.getReturnValue();
SystemTreeItemModel dataCenterItem = new SystemTreeItemModel();
dataCenterItem.setType(SystemTreeItemType.DataCenter);
dataCenterItem.setApplicationMode(ApplicationMode.VirtOnly);
StoragePool dataCenter = getDataCenters().get(count);
dataCenterItem.setTitle(dataCenter.getName());
dataCenterItem.setEntity(dataCenter);
dataCentersItem.addChild(dataCenterItem);
treeItemById.put(dataCenter.getId(), dataCenterItem);
SystemTreeItemModel storagesItem = new SystemTreeItemModel();
storagesItem.setType(SystemTreeItemType.Storages);
storagesItem.setApplicationMode(ApplicationMode.VirtOnly);
storagesItem.setTitle(ConstantsManager.getInstance().getConstants().storageTitle());
storagesItem.setEntity(dataCenter);
dataCenterItem.addChild(storagesItem);
if (storageDomains != null && storageDomains.size() > 0) {
// sort by name first
Collections.sort(storageDomains, new LexoNumericNameableComparator<>());
for (StorageDomain storage : storageDomains) {
SystemTreeItemModel storageItem = new SystemTreeItemModel();
storageItem.setType(SystemTreeItemType.Storage);
storageItem.setApplicationMode(ApplicationMode.VirtOnly);
storageItem.setTitle(storage.getStorageName());
storageItem.setEntity(storage);
storagesItem.addChild(storageItem);
treeItemById.put(storage.getId(), storageItem);
}
}
SystemTreeItemModel networksItem = new SystemTreeItemModel();
networksItem.setType(SystemTreeItemType.Networks);
networksItem.setApplicationMode(ApplicationMode.VirtOnly);
networksItem.setTitle(ConstantsManager.getInstance().getConstants().networksTitle());
networksItem.setEntity(dataCenter);
dataCenterItem.addChild(networksItem);
List<Network> dcNetworks = getNetworkMap().get(dataCenter.getId());
if (dcNetworks != null) {
// sort by name first
Collections.sort(dcNetworks, new NameableComparator());
for (Network network : dcNetworks) {
SystemTreeItemModel networkItem = new SystemTreeItemModel();
networkItem.setType(SystemTreeItemType.Network);
networkItem.setApplicationMode(ApplicationMode.VirtOnly);
networkItem.setTitle(network.getName());
networkItem.setEntity(network);
networksItem.addChild(networkItem);
treeItemById.put(network.getId(), networkItem);
}
}
SystemTreeItemModel templatesItem = new SystemTreeItemModel();
templatesItem.setType(SystemTreeItemType.Templates);
templatesItem.setApplicationMode(ApplicationMode.VirtOnly);
templatesItem.setTitle(ConstantsManager.getInstance().getConstants().templatesTitle());
templatesItem.setEntity(dataCenter);
dataCenterItem.addChild(templatesItem);
SystemTreeItemModel clustersItem = new SystemTreeItemModel();
clustersItem.setType(SystemTreeItemType.Clusters);
clustersItem.setTitle(ConstantsManager.getInstance().getConstants().clustersTitle());
clustersItem.setEntity(dataCenter);
dataCenterItem.addChild(clustersItem);
if (getClusterMap().containsKey(dataCenter.getId())) {
List<Cluster> clusters = getClusterMap().get(dataCenter.getId());
Collections.sort(clusters, new LexoNumericNameableComparator<>());
for (Cluster cluster : clusters) {
SystemTreeItemModel clusterItem = new SystemTreeItemModel();
clusterItem.setType(cluster.supportsGlusterService() ? SystemTreeItemType.Cluster_Gluster
: SystemTreeItemType.Cluster);
clusterItem.setTitle(cluster.getName());
clusterItem.setEntity(cluster);
clustersItem.addChild(clusterItem);
treeItemById.put(cluster.getId(), clusterItem);
SystemTreeItemModel hostsItem = new SystemTreeItemModel();
hostsItem.setType(SystemTreeItemType.Hosts);
hostsItem.setTitle(ConstantsManager.getInstance().getConstants().hostsTitle());
hostsItem.setEntity(cluster);
clusterItem.addChild(hostsItem);
if (getHostMap().containsKey(cluster.getId())) {
for (VDS host : getHostMap().get(cluster.getId())) {
SystemTreeItemModel hostItem = new SystemTreeItemModel();
hostItem.setType(SystemTreeItemType.Host);
hostItem.setTitle(host.getName());
hostItem.setEntity(host);
hostsItem.addChild(hostItem);
treeItemById.put(host.getId(), hostItem);
}
}
if (cluster.supportsGlusterService()) {
SystemTreeItemModel volumesItem = new SystemTreeItemModel();
volumesItem.setType(SystemTreeItemType.Volumes);
volumesItem.setApplicationMode(ApplicationMode.GlusterOnly);
volumesItem.setTitle(ConstantsManager.getInstance().getConstants().volumesTitle());
volumesItem.setEntity(cluster);
clusterItem.addChild(volumesItem);
if (getVolumeMap().containsKey(cluster.getId())) {
for (GlusterVolumeEntity volume : getVolumeMap().get(cluster.getId())) {
SystemTreeItemModel volumeItem = new SystemTreeItemModel();
volumeItem.setType(SystemTreeItemType.Volume);
volumeItem.setApplicationMode(ApplicationMode.GlusterOnly);
volumeItem.setTitle(volume.getName());
volumeItem.setEntity(volume);
volumesItem.addChild(volumeItem);
treeItemById.put(volume.getId(), volumeItem);
}
}
}
if (cluster.supportsVirtService()) {
SystemTreeItemModel vmsItem = new SystemTreeItemModel();
vmsItem.setType(SystemTreeItemType.VMs);
vmsItem.setApplicationMode(ApplicationMode.VirtOnly);
vmsItem.setTitle(ConstantsManager.getInstance().getConstants().vmsTitle());
vmsItem.setEntity(cluster);
clusterItem.addChild(vmsItem);
}
}
}
}
// Add Providers node under System
SystemTreeItemModel providersItem = new SystemTreeItemModel();
providersItem.setType(SystemTreeItemType.Providers);
providersItem.setApplicationMode(ApplicationMode.VirtOnly);
providersItem.setTitle(ConstantsManager.getInstance().getConstants().externalProvidersTitle());
systemItem.addChild(providersItem);
// Populate with providers
for (Provider provider : getProviders()) {
SystemTreeItemModel providerItem = new SystemTreeItemModel();
providerItem.setType(SystemTreeItemType.Provider);
providerItem.setApplicationMode(ApplicationMode.VirtOnly);
providerItem.setTitle(provider.getName());
providerItem.setEntity(provider);
providersItem.addChild(providerItem);
treeItemById.put(provider.getId(), providerItem);
}
// add Errata node under System
SystemTreeItemModel errataItem = new SystemTreeItemModel();
errataItem.setType(SystemTreeItemType.Errata);
errataItem.setApplicationMode(ApplicationMode.AllModes);
errataItem.setTitle(ConstantsManager.getInstance().getConstants().errata());
systemItem.addChild(errataItem);
//Add sessions node under System
SystemTreeItemModel sessionsItem = new SystemTreeItemModel();
sessionsItem.setType(SystemTreeItemType.Sessions);
sessionsItem.setApplicationMode(ApplicationMode.AllModes);
sessionsItem.setTitle(ConstantsManager.getInstance().getConstants().activeUserSessionsTitle());
systemItem.addChild(sessionsItem);
if (!ApplicationModeHelper.getUiMode().equals(ApplicationMode.AllModes)) {
ApplicationModeHelper.filterSystemTreeByApplictionMode(systemItem);
}
List<SystemTreeItemModel> newItems =
new ArrayList<>(Arrays.asList(new SystemTreeItemModel[] { systemItem }));
if (items == null || items.size() == 0 || !newItems.get(0).equals(items.toArray()[0], true)) {
setItems(newItems);
}
}
@Override
protected SystemTreeItemModel determineSelectedItems(List<SystemTreeItemModel> newItems,
SystemTreeItemModel lastSelectedItem, List<SystemTreeItemModel> lastSelectedItems) {
SystemTreeItemModel newSelectedItem = null;
for (SystemTreeItemModel newItem : newItems) {
newSelectedItem = findNode(newItem, lastSelectedItem);
// Search for selected item
if (newSelectedItem == null) {
// Search for selected items
for (SystemTreeItemModel item : lastSelectedItems) {
if (newItem.equals(item)) {
selectedItems.add(newItem);
}
}
}
}
return newSelectedItem;
}
public SystemTreeItemModel findNode(SystemTreeItemModel root, SystemTreeItemModel match) {
SystemTreeItemModel result = null;
if (root != null && match != null) {
if (root.equals(match)) {
result = root; //match found.
} else {
if (root.getChildren().size() > 0) {
for (int i = 0; i < root.getChildren().size(); i++) {
result = findNode(root.getChildren().get(i), match);
if (result != null) {
break;
}
}
}
}
}
return result;
}
@Override
protected String getListName() {
return "SystemTreeModel"; //$NON-NLS-1$
}
@Override
protected boolean refreshOnInactiveTimer() {
return true;
}
}