Changes for a new API command to list the storage tags

This commit is contained in:
seif 2014-08-07 15:10:13 +02:00 committed by Mike Tutkowski
parent 6d1482b97b
commit 67ca2557f9
13 changed files with 411 additions and 0 deletions

View File

@ -0,0 +1,46 @@
package org.apache.cloudstack.api.command.admin.storage;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandJobType;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.StorageTagResponse;
@APICommand(name = "listStorageTags", description = "Lists storage tags", responseObject = StorageTagResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListStorageTagsCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListStorageTagsCmd.class.getName());
private static final String s_name = "liststoragetagsresponse";
// ///////////////////////////////////////////////////
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
// ///////////////////////////////////////////////////
// ///////////////// Accessors ///////////////////////
// ///////////////////////////////////////////////////
// ///////////////////////////////////////////////////
// ///////////// API Implementation///////////////////
// ///////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public ApiCommandJobType getInstanceType() {
return ApiCommandJobType.StoragePool;
}
@Override
public void execute() {
ListResponse<StorageTagResponse> response = _queryService.searchForStorageTags(this);
response.setResponseName(getCommandName());
setResponseObject(response);
}
}

View File

@ -0,0 +1,59 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.response;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.BaseResponse;
import com.cloud.serializer.Param;
public class StorageTagResponse extends BaseResponse {
@SerializedName("id")
@Param(description = "the ID of the storage tag")
private String id;
@SerializedName("poolid")
@Param(description = "the pool ID of the storage tag")
private long poolId;
@SerializedName("name")
@Param(description = "the name of the storage tag")
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public long getPoolId() {
return poolId;
}
public void setPoolId(long l) {
this.poolId = l;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -25,6 +25,7 @@ import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
@ -60,6 +61,7 @@ import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.StorageTagResponse;
import org.apache.cloudstack.api.response.TemplateResponse;
import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
@ -125,5 +127,6 @@ public interface QueryService {
public List<ResourceDetailResponse> listResourceDetails(ListResourceDetailsCmd cmd);
ListResponse<DomainRouterResponse> searchForInternalLbVms(ListInternalLBVMsCmd cmd);
public ListResponse<StorageTagResponse> searchForStorageTags(ListStorageTagsCmd cmd);
}

View File

@ -329,6 +329,7 @@ listAsyncJobs=15
#### storage pools commands
listStoragePools=3
listStorageProviders=3
listStorageTags=7
createStoragePool=1
updateStoragePool=1
deleteStoragePool=1

View File

@ -262,6 +262,7 @@
<bean id="storageNetworkIpRangeDaoImpl" class="com.cloud.dc.dao.StorageNetworkIpRangeDaoImpl" />
<bean id="storagePoolDetailsDaoImpl" class="com.cloud.storage.dao.StoragePoolDetailsDaoImpl" />
<bean id="storagePoolJoinDaoImpl" class="com.cloud.api.query.dao.StoragePoolJoinDaoImpl" />
<bean id="storageTagDaoImpl" class="com.cloud.api.query.dao.StorageTagDaoImpl" />
<bean id="storagePoolWorkDaoImpl" class="com.cloud.storage.dao.StoragePoolWorkDaoImpl" />
<bean id="templatePrimaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreDaoImpl" />
<bean id="uploadDaoImpl" class="com.cloud.storage.dao.UploadDaoImpl" />

View File

@ -50,6 +50,7 @@ import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.StorageTagResponse;
import org.apache.cloudstack.api.response.TemplateResponse;
import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
@ -82,6 +83,7 @@ import com.cloud.api.query.dao.ResourceTagJoinDao;
import com.cloud.api.query.dao.SecurityGroupJoinDao;
import com.cloud.api.query.dao.ServiceOfferingJoinDao;
import com.cloud.api.query.dao.StoragePoolJoinDao;
import com.cloud.api.query.dao.StorageTagDao;
import com.cloud.api.query.dao.TemplateJoinDao;
import com.cloud.api.query.dao.UserAccountJoinDao;
import com.cloud.api.query.dao.UserVmJoinDao;
@ -103,6 +105,7 @@ import com.cloud.api.query.vo.ResourceTagJoinVO;
import com.cloud.api.query.vo.SecurityGroupJoinVO;
import com.cloud.api.query.vo.ServiceOfferingJoinVO;
import com.cloud.api.query.vo.StoragePoolJoinVO;
import com.cloud.api.query.vo.StorageTagVO;
import com.cloud.api.query.vo.TemplateJoinVO;
import com.cloud.api.query.vo.UserAccountJoinVO;
import com.cloud.api.query.vo.UserVmJoinVO;
@ -386,6 +389,7 @@ public class ApiDBUtils {
static HostJoinDao s_hostJoinDao;
static VolumeJoinDao s_volJoinDao;
static StoragePoolJoinDao s_poolJoinDao;
static StorageTagDao s_tagDao;
static ImageStoreJoinDao s_imageStoreJoinDao;
static AccountJoinDao s_accountJoinDao;
static AsyncJobJoinDao s_jobJoinDao;
@ -581,6 +585,8 @@ public class ApiDBUtils {
@Inject
private StoragePoolJoinDao poolJoinDao;
@Inject
private StorageTagDao tagDao;
@Inject
private ImageStoreJoinDao imageStoreJoinDao;
@Inject
private AccountJoinDao accountJoinDao;
@ -718,6 +724,7 @@ public class ApiDBUtils {
s_hostJoinDao = hostJoinDao;
s_volJoinDao = volJoinDao;
s_poolJoinDao = poolJoinDao;
s_tagDao = tagDao;
s_imageStoreJoinDao = imageStoreJoinDao;
s_accountJoinDao = accountJoinDao;
s_jobJoinDao = jobJoinDao;
@ -1733,6 +1740,10 @@ public class ApiDBUtils {
return s_poolJoinDao.newStoragePoolResponse(vr);
}
public static StorageTagResponse newStorageTagResponse(StorageTagVO vr) {
return s_tagDao.newStorageTagResponse(vr);
}
public static StoragePoolResponse fillStoragePoolDetails(StoragePoolResponse vrData, StoragePoolJoinVO vr) {
return s_poolJoinDao.setStoragePoolResponse(vrData, vr);
}

View File

@ -46,6 +46,7 @@ import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
import org.apache.cloudstack.api.command.admin.template.ListTemplatesCmdByAdmin;
import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
import org.apache.cloudstack.api.command.admin.vm.ListVMsCmdByAdmin;
@ -85,6 +86,7 @@ import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.StorageTagResponse;
import org.apache.cloudstack.api.response.TemplateResponse;
import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
@ -115,6 +117,7 @@ import com.cloud.api.query.dao.ResourceTagJoinDao;
import com.cloud.api.query.dao.SecurityGroupJoinDao;
import com.cloud.api.query.dao.ServiceOfferingJoinDao;
import com.cloud.api.query.dao.StoragePoolJoinDao;
import com.cloud.api.query.dao.StorageTagDao;
import com.cloud.api.query.dao.TemplateJoinDao;
import com.cloud.api.query.dao.UserAccountJoinDao;
import com.cloud.api.query.dao.UserVmJoinDao;
@ -136,6 +139,7 @@ import com.cloud.api.query.vo.ResourceTagJoinVO;
import com.cloud.api.query.vo.SecurityGroupJoinVO;
import com.cloud.api.query.vo.ServiceOfferingJoinVO;
import com.cloud.api.query.vo.StoragePoolJoinVO;
import com.cloud.api.query.vo.StorageTagVO;
import com.cloud.api.query.vo.TemplateJoinVO;
import com.cloud.api.query.vo.UserAccountJoinVO;
import com.cloud.api.query.vo.UserVmJoinVO;
@ -284,6 +288,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
@Inject
private StoragePoolJoinDao _poolJoinDao;
@Inject
private StorageTagDao _storageTagDao;
@Inject
private ImageStoreJoinDao _imageStoreJoinDao;
@ -2129,6 +2136,47 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
}
@Override
public ListResponse<StorageTagResponse> searchForStorageTags(ListStorageTagsCmd cmd) {
Pair<List<StorageTagVO>, Integer> result = searchForStorageTagsInternal(cmd);
ListResponse<StorageTagResponse> response = new ListResponse<StorageTagResponse>();
List<StorageTagResponse> tagResponses = ViewResponseHelper.createStorageTagResponse(result.first().toArray(new StorageTagVO[result.first().size()]));
response.setResponses(tagResponses, result.second());
return response;
}
private Pair<List<StorageTagVO>, Integer> searchForStorageTagsInternal(ListStorageTagsCmd cmd) {
Filter searchFilter = new Filter(StorageTagVO.class, "id", Boolean.TRUE, null, null);
SearchBuilder<StorageTagVO> sb = _storageTagDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
SearchCriteria<StorageTagVO> sc = sb.create();
// search storage tag details by ids
Pair<List<StorageTagVO>, Integer> uniqueTagPair = _storageTagDao.searchAndCount(sc, searchFilter);
Integer count = uniqueTagPair.second();
if (count.intValue() == 0) {
return uniqueTagPair;
}
List<StorageTagVO> uniqueTags = uniqueTagPair.first();
Long[] vrIds = new Long[uniqueTags.size()];
int i = 0;
for (StorageTagVO v : uniqueTags) {
vrIds[i++] = v.getId();
}
List<StorageTagVO> vrs = _storageTagDao.searchByIds(vrIds);
return new Pair<List<StorageTagVO>, Integer>(vrs, count);
}
@Override
public ListResponse<ImageStoreResponse> searchForImageStores(ListImageStoresCmd cmd) {
Pair<List<ImageStoreJoinVO>, Integer> result = searchForImageStoresInternal(cmd);

View File

@ -44,6 +44,7 @@ import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.StorageTagResponse;
import org.apache.cloudstack.api.response.TemplateResponse;
import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
@ -69,6 +70,7 @@ import com.cloud.api.query.vo.ResourceTagJoinVO;
import com.cloud.api.query.vo.SecurityGroupJoinVO;
import com.cloud.api.query.vo.ServiceOfferingJoinVO;
import com.cloud.api.query.vo.StoragePoolJoinVO;
import com.cloud.api.query.vo.StorageTagVO;
import com.cloud.api.query.vo.TemplateJoinVO;
import com.cloud.api.query.vo.UserAccountJoinVO;
import com.cloud.api.query.vo.UserVmJoinVO;
@ -289,6 +291,16 @@ public class ViewResponseHelper {
return new ArrayList<StoragePoolResponse>(vrDataList.values());
}
public static List<StorageTagResponse> createStorageTagResponse(StorageTagVO... storageTags) {
ArrayList<StorageTagResponse> list = new ArrayList<StorageTagResponse>();
for (StorageTagVO vr : storageTags) {
list.add(ApiDBUtils.newStorageTagResponse(vr));
}
return list;
}
public static List<ImageStoreResponse> createImageStoreResponse(ImageStoreJoinVO... stores) {
Hashtable<Long, ImageStoreResponse> vrDataList = new Hashtable<Long, ImageStoreResponse>();
// Initialise the vrdatalist with the input data

View File

@ -0,0 +1,30 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.api.query.dao;
import java.util.List;
import org.apache.cloudstack.api.response.StorageTagResponse;
import com.cloud.api.query.vo.StorageTagVO;
import com.cloud.utils.db.GenericDao;
public interface StorageTagDao extends GenericDao<StorageTagVO, Long> {
StorageTagResponse newStorageTagResponse(StorageTagVO storageTag);
List<StorageTagVO> searchByIds(Long... storageTagIds);
}

View File

@ -0,0 +1,126 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.api.query.dao;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Local;
import javax.inject.Inject;
import org.apache.cloudstack.api.response.StorageTagResponse;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.api.query.vo.StorageTagVO;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@Component
@Local(value = {StorageTagDao.class})
public class StorageTagDaoImpl extends GenericDaoBase<StorageTagVO, Long> implements StorageTagDao {
public static final Logger s_logger = Logger.getLogger(StorageTagDaoImpl.class);
@Inject
private ConfigurationDao _configDao;
private final SearchBuilder<StorageTagVO> stSearch;
private final SearchBuilder<StorageTagVO> stIdSearch;
protected StorageTagDaoImpl() {
stSearch = createSearchBuilder();
stSearch.and("idIN", stSearch.entity().getId(), SearchCriteria.Op.IN);
stSearch.done();
stIdSearch = createSearchBuilder();
stIdSearch.and("id", stIdSearch.entity().getId(), SearchCriteria.Op.EQ);
stIdSearch.done();
_count = "select count(distinct id) from storage_tag_view WHERE ";
}
@Override
public StorageTagResponse newStorageTagResponse(StorageTagVO tag) {
StorageTagResponse tagResponse = new StorageTagResponse();
tagResponse.setName(tag.getName());
tagResponse.setPoolId(tag.getPoolId());
tagResponse.setObjectName("storagetag");
return tagResponse;
}
@Override
public List<StorageTagVO> searchByIds(Long... stIds) {
String batchCfg = _configDao.getValue("detail.batch.query.size");
final int detailsBatchSize = batchCfg != null ? Integer.parseInt(batchCfg) : 2000;
// query details by batches
List<StorageTagVO> uvList = new ArrayList<StorageTagVO>();
int curr_index = 0;
if (stIds.length > detailsBatchSize) {
while ((curr_index + detailsBatchSize) <= stIds.length) {
Long[] ids = new Long[detailsBatchSize];
for (int k = 0, j = curr_index; j < curr_index + detailsBatchSize; j++, k++) {
ids[k] = stIds[j];
}
SearchCriteria<StorageTagVO> sc = stSearch.create();
sc.setParameters("idIN", (Object[])ids);
List<StorageTagVO> vms = searchIncludingRemoved(sc, null, null, false);
if (vms != null) {
uvList.addAll(vms);
}
curr_index += detailsBatchSize;
}
}
if (curr_index < stIds.length) {
int batch_size = (stIds.length - curr_index);
// set the ids value
Long[] ids = new Long[batch_size];
for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
ids[k] = stIds[j];
}
SearchCriteria<StorageTagVO> sc = stSearch.create();
sc.setParameters("idIN", (Object[])ids);
List<StorageTagVO> vms = searchIncludingRemoved(sc, null, null, false);
if (vms != null) {
uvList.addAll(vms);
}
}
return uvList;
}
}

View File

@ -0,0 +1,61 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.api.query.vo;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.cloudstack.api.InternalIdentity;
/**
* Storage Tags DB view.
*
*/
@Entity
@Table(name = "storage_tag_view")
public class StorageTagVO extends BaseViewVO implements InternalIdentity {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "id")
private long id;
@Column(name = "name")
private String name;
@Column(name = "pool_id")
long poolId;
@Override
public long getId() {
return id;
}
public String getName() {
return name;
}
public long getPoolId() {
return poolId;
}
public void setPoolId(long poolId) {
this.poolId = poolId;
}
}

View File

@ -176,6 +176,7 @@ import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
import org.apache.cloudstack.api.command.admin.storage.ListS3sCmd;
import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
import org.apache.cloudstack.api.command.admin.storage.ListStorageProvidersCmd;
import org.apache.cloudstack.api.command.admin.storage.PreparePrimaryStorageForMaintenanceCmd;
import org.apache.cloudstack.api.command.admin.storage.UpdateCloudToUseObjectStoreCmd;
@ -2623,6 +2624,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
cmdList.add(ListS3sCmd.class);
cmdList.add(ListSwiftsCmd.class);
cmdList.add(ListStoragePoolsCmd.class);
cmdList.add(ListStorageTagsCmd.class);
cmdList.add(FindStoragePoolsForMigrationCmd.class);
cmdList.add(PreparePrimaryStorageForMaintenanceCmd.class);
cmdList.add(UpdateStoragePoolCmd.class);

View File

@ -22,6 +22,17 @@
-- Disable foreign key checking
-- SET foreign_key_checks = 0;
DROP VIEW IF EXISTS `cloud`.`storage_tag_view`;
CREATE VIEW `cloud`.`storage_tag_view` AS
select
storage_pool_details.id,
storage_pool_details.pool_id,
storage_pool_details.name
from
`cloud`.`storage_pool_details`
where
value='true';
ALTER TABLE `cloud`.`volumes` ADD COLUMN `provisioning_type` VARCHAR(32) NOT NULL DEFAULT 'thin' COMMENT 'pre allocation setting of the volume';
ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `provisioning_type` VARCHAR(32) NOT NULL DEFAULT 'thin' COMMENT 'pre allocation setting of the volume';