mirror of https://github.com/apache/cloudstack.git
server: add support for sorting zones in UI/API (#3242)
Problem: Not able to configure a sort order for the zones that are listed in various views in the UI. Root Cause: There is no mechanism to accept sort key for existing zones or UI widget, that would allow to listing zones in the UI in a certain order. Solution: The order of zones in listed in various views in the UI can now be configured through the newly added “sort_key” field added for the zone. It can be set using updateZone API by providing “sort_key” parameter for a zone, or by reordering the items in the zones list in the UI. UI has been updated to show ordering controls in zones list view. Database changes include updating table “data_center” by adding “sort_key” column (containing integer values and defaults to zero). Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
parent
0d6cae6339
commit
90cd8aa73d
|
|
@ -16,11 +16,12 @@
|
|||
// under the License.
|
||||
package com.cloud.dc;
|
||||
|
||||
import com.cloud.org.Grouping;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.acl.InfrastructureEntity;
|
||||
import org.apache.cloudstack.kernel.Partition;
|
||||
|
||||
import java.util.Map;
|
||||
import com.cloud.org.Grouping;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -80,4 +81,6 @@ public interface DataCenter extends InfrastructureEntity, Grouping, Partition {
|
|||
String getZoneToken();
|
||||
|
||||
boolean isLocalStorageEnabled();
|
||||
|
||||
int getSortKey();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,6 +95,9 @@ public class UpdateZoneCmd extends BaseCmd {
|
|||
@Parameter(name = ApiConstants.LOCAL_STORAGE_ENABLED, type = CommandType.BOOLEAN, description = "true if local storage offering enabled, false otherwise")
|
||||
private Boolean localStorageEnabled;
|
||||
|
||||
@Parameter(name = ApiConstants.SORT_KEY, type = CommandType.INTEGER, description = "sort key of the zone, integer")
|
||||
private Integer sortKey;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -163,6 +166,10 @@ public class UpdateZoneCmd extends BaseCmd {
|
|||
return localStorageEnabled;
|
||||
}
|
||||
|
||||
public Integer getSortKey() {
|
||||
return sortKey;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ import com.cloud.exception.PermissionDeniedException;
|
|||
public interface QueryService {
|
||||
|
||||
// Config keys
|
||||
static final ConfigKey<Boolean> AllowUserViewDestroyedVM = new ConfigKey<Boolean>("Advanced", Boolean.class, "allow.user.view.destroyed.vm", "false",
|
||||
ConfigKey<Boolean> AllowUserViewDestroyedVM = new ConfigKey<>("Advanced", Boolean.class, "allow.user.view.destroyed.vm", "false",
|
||||
"Determines whether users can view their destroyed or expunging vm ", true, ConfigKey.Scope.Account);
|
||||
|
||||
static final ConfigKey<String> UserVMBlacklistedDetails = new ConfigKey<String>("Advanced", String.class,
|
||||
|
|
@ -96,6 +96,11 @@ public interface QueryService {
|
|||
"user.vm.readonly.ui.details", "dataDiskController, rootDiskController",
|
||||
"List of UI read-only VM settings/details as comma separated string", true);
|
||||
|
||||
ConfigKey<Boolean> SortKeyAscending = new ConfigKey<>("Advanced", Boolean.class, "sortkey.algorithm", "true",
|
||||
"Sort algorithm - ascending or descending - to use. For entities that use sort key(template, disk offering, service offering, " +
|
||||
"network offering, zones), we use the flag to determine if the entities should be sorted ascending (when flag is true) " +
|
||||
"or descending (when flag is false). Within the scope of the config all users see the same result.", true, ConfigKey.Scope.Global);
|
||||
|
||||
ListResponse<UserResponse> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException;
|
||||
|
||||
ListResponse<EventResponse> searchForEvents(ListEventsCmd cmd);
|
||||
|
|
|
|||
|
|
@ -16,14 +16,9 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.engine.datacenter.entity.api.db;
|
||||
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.org.Grouping;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.db.StateMachine;
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State;
|
||||
import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State.Event;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
|
|
@ -37,9 +32,16 @@ import javax.persistence.TableGenerator;
|
|||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.Transient;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State;
|
||||
import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State.Event;
|
||||
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.org.Grouping;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.db.StateMachine;
|
||||
|
||||
@Entity
|
||||
@Table(name = "data_center")
|
||||
|
|
@ -140,6 +142,9 @@ public class EngineDataCenterVO implements EngineDataCenter, Identity {
|
|||
@Column(name = "is_local_storage_enabled")
|
||||
boolean localStorageEnabled;
|
||||
|
||||
@Column(name = "sort_key")
|
||||
int sortKey;
|
||||
|
||||
//orchestration
|
||||
@Column(name = "owner")
|
||||
private String owner = null;
|
||||
|
|
@ -389,6 +394,10 @@ public class EngineDataCenterVO implements EngineDataCenter, Identity {
|
|||
this.localStorageEnabled = enabled;
|
||||
}
|
||||
|
||||
public int getSortKey() {
|
||||
return sortKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getDetails() {
|
||||
return details;
|
||||
|
|
|
|||
|
|
@ -16,10 +16,9 @@
|
|||
// under the License.
|
||||
package com.cloud.dc;
|
||||
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.org.Grouping;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
|
|
@ -31,9 +30,11 @@ import javax.persistence.Id;
|
|||
import javax.persistence.Table;
|
||||
import javax.persistence.TableGenerator;
|
||||
import javax.persistence.Transient;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.org.Grouping;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
@Entity
|
||||
@Table(name = "data_center")
|
||||
|
|
@ -134,6 +135,9 @@ public class DataCenterVO implements DataCenter {
|
|||
@Column(name = "is_local_storage_enabled")
|
||||
boolean localStorageEnabled;
|
||||
|
||||
@Column(name = "sort_key")
|
||||
int sortKey;
|
||||
|
||||
@Override
|
||||
public String getDnsProvider() {
|
||||
return dnsProvider;
|
||||
|
|
@ -363,6 +367,15 @@ public class DataCenterVO implements DataCenter {
|
|||
this.localStorageEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSortKey() {
|
||||
return sortKey;
|
||||
}
|
||||
|
||||
public void setSortKey(int newSortKey) {
|
||||
sortKey = newSortKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getDetails() {
|
||||
return details;
|
||||
|
|
|
|||
|
|
@ -21,3 +21,46 @@
|
|||
|
||||
-- DPDK client and server mode support
|
||||
ALTER TABLE `cloud`.`service_offering_details` CHANGE COLUMN `value` `value` TEXT NOT NULL;
|
||||
|
||||
-- Add `sort_key` column to data_center
|
||||
ALTER TABLE `cloud`.`data_center` ADD COLUMN `sort_key` INT(32) NOT NULL DEFAULT 0;
|
||||
|
||||
-- Recreate data_center_view
|
||||
DROP VIEW IF EXISTS `cloud`.`data_center_view`;
|
||||
CREATE VIEW `cloud`.`data_center_view` AS
|
||||
select
|
||||
data_center.id,
|
||||
data_center.uuid,
|
||||
data_center.name,
|
||||
data_center.is_security_group_enabled,
|
||||
data_center.is_local_storage_enabled,
|
||||
data_center.description,
|
||||
data_center.dns1,
|
||||
data_center.dns2,
|
||||
data_center.ip6_dns1,
|
||||
data_center.ip6_dns2,
|
||||
data_center.internal_dns1,
|
||||
data_center.internal_dns2,
|
||||
data_center.guest_network_cidr,
|
||||
data_center.domain,
|
||||
data_center.networktype,
|
||||
data_center.allocation_state,
|
||||
data_center.zone_token,
|
||||
data_center.dhcp_provider,
|
||||
data_center.removed,
|
||||
data_center.sort_key,
|
||||
domain.id domain_id,
|
||||
domain.uuid domain_uuid,
|
||||
domain.name domain_name,
|
||||
domain.path domain_path,
|
||||
dedicated_resources.affinity_group_id,
|
||||
dedicated_resources.account_id,
|
||||
affinity_group.uuid affinity_group_uuid
|
||||
from
|
||||
`cloud`.`data_center`
|
||||
left join
|
||||
`cloud`.`domain` ON data_center.domain_id = domain.id
|
||||
left join
|
||||
`cloud`.`dedicated_resources` ON data_center.id = dedicated_resources.data_center_id
|
||||
left join
|
||||
`cloud`.`affinity_group` ON dedicated_resources.affinity_group_id = affinity_group.id;
|
||||
|
|
|
|||
|
|
@ -2496,9 +2496,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
// till
|
||||
// root
|
||||
|
||||
Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
|
||||
isAscending = (isAscending == null ? true : isAscending);
|
||||
Filter searchFilter = new Filter(DiskOfferingJoinVO.class, "sortKey", isAscending, cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||
Filter searchFilter = new Filter(DiskOfferingJoinVO.class, "sortKey", SortKeyAscending.value(), cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||
SearchCriteria<DiskOfferingJoinVO> sc = _diskOfferingJoinDao.createSearchCriteria();
|
||||
sc.addAnd("type", Op.EQ, DiskOfferingVO.Type.Disk);
|
||||
|
||||
|
|
@ -2638,9 +2636,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
// their domains+parent domains ... all the way
|
||||
// till
|
||||
// root
|
||||
Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
|
||||
isAscending = (isAscending == null ? true : isAscending);
|
||||
Filter searchFilter = new Filter(ServiceOfferingJoinVO.class, "sortKey", isAscending, cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||
Filter searchFilter = new Filter(ServiceOfferingJoinVO.class, "sortKey", SortKeyAscending.value(), cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
Object name = cmd.getServiceOfferingName();
|
||||
|
|
@ -2814,7 +2810,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
|
||||
}
|
||||
|
||||
Filter searchFilter = new Filter(DataCenterJoinVO.class, null, false, cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||
Filter searchFilter = new Filter(DataCenterJoinVO.class, "sortKey", SortKeyAscending.value(), cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||
SearchCriteria<DataCenterJoinVO> sc = sb.create();
|
||||
|
||||
if (networkType != null) {
|
||||
|
|
@ -3074,10 +3070,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
|
||||
VMTemplateVO template = null;
|
||||
|
||||
Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
|
||||
isAscending = (isAscending == null ? Boolean.TRUE : isAscending);
|
||||
Filter searchFilter = new Filter(TemplateJoinVO.class, "sortKey", isAscending, startIndex, pageSize);
|
||||
searchFilter.addOrderBy(TemplateJoinVO.class, "tempZonePair", isAscending);
|
||||
Filter searchFilter = new Filter(TemplateJoinVO.class, "sortKey", SortKeyAscending.value(), startIndex, pageSize);
|
||||
searchFilter.addOrderBy(TemplateJoinVO.class, "tempZonePair", SortKeyAscending.value());
|
||||
|
||||
SearchBuilder<TemplateJoinVO> sb = _templateJoinDao.createSearchBuilder();
|
||||
sb.select(null, Func.DISTINCT, sb.entity().getTempZonePair()); // select distinct (templateId, zoneId) pair
|
||||
|
|
@ -3702,6 +3696,6 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
|
||||
@Override
|
||||
public ConfigKey<?>[] getConfigKeys() {
|
||||
return new ConfigKey<?>[] {AllowUserViewDestroyedVM, UserVMBlacklistedDetails, UserVMReadOnlyUIDetails};
|
||||
return new ConfigKey<?>[] {AllowUserViewDestroyedVM, UserVMBlacklistedDetails, UserVMReadOnlyUIDetails, SortKeyAscending};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,9 @@ public class DataCenterJoinVO extends BaseViewVO implements InternalIdentity, Id
|
|||
@Column(name = "account_id")
|
||||
private long accountId;
|
||||
|
||||
@Column(name = "sort_key")
|
||||
private int sortKey;
|
||||
|
||||
public DataCenterJoinVO() {
|
||||
}
|
||||
|
||||
|
|
@ -221,4 +224,8 @@ public class DataCenterJoinVO extends BaseViewVO implements InternalIdentity, Id
|
|||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public int getSortKey() {
|
||||
return sortKey;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -987,14 +987,6 @@ public enum Config {
|
|||
"30",
|
||||
"Garbage collection interval to destroy unused ELB vms in minutes. Minimum of 5",
|
||||
null),
|
||||
SortKeyAlgorithm(
|
||||
"Advanced",
|
||||
ManagementServer.class,
|
||||
Boolean.class,
|
||||
"sortkey.algorithm",
|
||||
"false",
|
||||
"Sort algorithm for those who use sort key(template, disk offering, service offering, network offering), true means ascending sort while false means descending sort",
|
||||
null),
|
||||
EnableEC2API("Advanced", ManagementServer.class, Boolean.class, "enable.ec2.api", "false", "enable EC2 API on CloudStack", null),
|
||||
EnableS3API("Advanced", ManagementServer.class, Boolean.class, "enable.s3.api", "false", "enable Amazon S3 API on CloudStack", null),
|
||||
RecreateSystemVmEnabled(
|
||||
|
|
|
|||
|
|
@ -1922,6 +1922,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
guestCidr = zone.getGuestNetworkCidr();
|
||||
}
|
||||
|
||||
int sortKey = cmd.getSortKey() != null ? cmd.getSortKey() : zone.getSortKey();
|
||||
|
||||
// validate network domain
|
||||
if (networkDomain != null && !networkDomain.isEmpty()) {
|
||||
if (!NetUtils.verifyDomainName(networkDomain)) {
|
||||
|
|
@ -1944,6 +1946,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
zone.setInternalDns1(internalDns1);
|
||||
zone.setInternalDns2(internalDns2);
|
||||
zone.setGuestNetworkCidr(guestCidr);
|
||||
zone.setSortKey(sortKey);
|
||||
if (localStorageEnabled != null) {
|
||||
zone.setLocalStorageEnabled(localStorageEnabled.booleanValue());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,6 +187,24 @@
|
|||
}
|
||||
});
|
||||
|
||||
// Update global pagesize for sort key in UI
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: createURL('listConfigurations'),
|
||||
data: {name: 'sortkey.algorithm'},
|
||||
dataType: 'json',
|
||||
async: false,
|
||||
success: function(data, textStatus, xhr) {
|
||||
if (data && data.listconfigurationsresponse && data.listconfigurationsresponse.configuration) {
|
||||
var config = data.listconfigurationsresponse.configuration[0];
|
||||
if (config && config.name == 'sortkey.algorithm') {
|
||||
g_sortKeyIsAscending = config.value == 'true';
|
||||
}
|
||||
}
|
||||
},
|
||||
error: function(xhr) { // ignore any errors, fallback to the default
|
||||
}
|
||||
});
|
||||
|
||||
// Populate IDP list
|
||||
$.ajax({
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ var g_cloudstackversion = null;
|
|||
var g_queryAsyncJobResultInterval = 3000;
|
||||
var g_idpList = null;
|
||||
var g_appendIdpDomain = false;
|
||||
var g_sortKeyIsAscending = false;
|
||||
|
||||
//keyboard keycode
|
||||
var keycode_Enter = 13;
|
||||
|
|
@ -2418,7 +2419,7 @@ cloudStack.api = {
|
|||
url: createURL(updateCommand),
|
||||
data: {
|
||||
id: args.context[objType].id,
|
||||
sortKey: args.index
|
||||
sortKey: g_sortKeyIsAscending ? (-1 * args.index) : args.index
|
||||
},
|
||||
success: function(json) {
|
||||
args.response.success();
|
||||
|
|
|
|||
|
|
@ -7641,6 +7641,8 @@
|
|||
}
|
||||
},
|
||||
|
||||
reorder: cloudStack.api.actions.sort('updateZone', 'physicalResources'),
|
||||
|
||||
dataProvider: function (args) {
|
||||
var array1 =[];
|
||||
if (args.filterBy != null) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue