Added the listHostTags API command

This commit is contained in:
seif 2014-08-15 17:16:58 +02:00 committed by Mike Tutkowski
parent fd6d083ad6
commit 59ea2e2960
12 changed files with 419 additions and 2 deletions

View File

@ -0,0 +1,64 @@
/*
* 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.command.admin.host;
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.HostTagResponse;
@APICommand(name = "listHostTags", description = "Lists host tags", responseObject = HostTagResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListHostTagsCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListHostTagsCmd.class.getName());
private static final String s_name = "listhosttagsresponse";
// ///////////////////////////////////////////////////
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
// ///////////////////////////////////////////////////
// ///////////////// Accessors ///////////////////////
// ///////////////////////////////////////////////////
// ///////////////////////////////////////////////////
// ///////////// API Implementation///////////////////
// ///////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public ApiCommandJobType getInstanceType() {
return ApiCommandJobType.Host;
}
@Override
public void execute() {
ListResponse<HostTagResponse> response = _queryService.searchForHostTags(this);
response.setResponseName(getCommandName());
setResponseObject(response);
}
}

View File

@ -0,0 +1,60 @@
// 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 com.cloud.serializer.Param;
import org.apache.cloudstack.api.BaseResponse;
public class HostTagResponse extends BaseResponse {
@SerializedName("id")
@Param(description = "the ID of the host tag")
private String id;
@SerializedName("hostid")
@Param(description = "the host ID of the host tag")
private long hostId;
@SerializedName("name")
@Param(description = "the name of the host tag")
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public long getHostId() {
return hostId;
}
public void setHostId(long hostId) {
this.hostId = hostId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -20,6 +20,7 @@ import java.util.List;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd;
import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd;
import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
@ -50,6 +51,7 @@ import org.apache.cloudstack.api.response.DiskOfferingResponse;
import org.apache.cloudstack.api.response.DomainRouterResponse;
import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.HostTagResponse;
import org.apache.cloudstack.api.response.ImageStoreResponse;
import org.apache.cloudstack.api.response.InstanceGroupResponse;
import org.apache.cloudstack.api.response.ListResponse;
@ -128,5 +130,6 @@ public interface QueryService {
ListResponse<DomainRouterResponse> searchForInternalLbVms(ListInternalLBVMsCmd cmd);
public ListResponse<StorageTagResponse> searchForStorageTags(ListStorageTagsCmd cmd);
public ListResponse<HostTagResponse> searchForHostTags(ListHostTagsCmd cmd);
}

View File

@ -299,6 +299,7 @@ deleteHost=3
prepareHostForMaintenance=1
cancelHostMaintenance=1
listHosts=3
listHostTags=7
findHostsForMigration=1
addSecondaryStorage=1
updateHostPassword=1

View File

@ -263,6 +263,7 @@
<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="hostTagDaoImpl" class="com.cloud.api.query.dao.HostTagDaoImpl" />
<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

@ -41,6 +41,7 @@ import org.apache.cloudstack.api.response.DomainRouterResponse;
import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.HostForMigrationResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.HostTagResponse;
import org.apache.cloudstack.api.response.ImageStoreResponse;
import org.apache.cloudstack.api.response.InstanceGroupResponse;
import org.apache.cloudstack.api.response.ProjectAccountResponse;
@ -74,6 +75,7 @@ import com.cloud.api.query.dao.DataCenterJoinDao;
import com.cloud.api.query.dao.DiskOfferingJoinDao;
import com.cloud.api.query.dao.DomainRouterJoinDao;
import com.cloud.api.query.dao.HostJoinDao;
import com.cloud.api.query.dao.HostTagDao;
import com.cloud.api.query.dao.ImageStoreJoinDao;
import com.cloud.api.query.dao.InstanceGroupJoinDao;
import com.cloud.api.query.dao.ProjectAccountJoinDao;
@ -96,6 +98,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO;
import com.cloud.api.query.vo.DomainRouterJoinVO;
import com.cloud.api.query.vo.EventJoinVO;
import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.api.query.vo.HostTagVO;
import com.cloud.api.query.vo.ImageStoreJoinVO;
import com.cloud.api.query.vo.InstanceGroupJoinVO;
import com.cloud.api.query.vo.ProjectAccountJoinVO;
@ -390,6 +393,7 @@ public class ApiDBUtils {
static VolumeJoinDao s_volJoinDao;
static StoragePoolJoinDao s_poolJoinDao;
static StorageTagDao s_tagDao;
static HostTagDao s_hostTagDao;
static ImageStoreJoinDao s_imageStoreJoinDao;
static AccountJoinDao s_accountJoinDao;
static AsyncJobJoinDao s_jobJoinDao;
@ -587,6 +591,8 @@ public class ApiDBUtils {
@Inject
private StorageTagDao tagDao;
@Inject
private HostTagDao hosttagDao;
@Inject
private ImageStoreJoinDao imageStoreJoinDao;
@Inject
private AccountJoinDao accountJoinDao;
@ -725,6 +731,7 @@ public class ApiDBUtils {
s_volJoinDao = volJoinDao;
s_poolJoinDao = poolJoinDao;
s_tagDao = tagDao;
s_hostTagDao = hosttagDao;
s_imageStoreJoinDao = imageStoreJoinDao;
s_accountJoinDao = accountJoinDao;
s_jobJoinDao = jobJoinDao;
@ -1744,6 +1751,10 @@ public class ApiDBUtils {
return s_tagDao.newStorageTagResponse(vr);
}
public static HostTagResponse newHostTagResponse(HostTagVO vr) {
return s_hostTagDao.newHostTagResponse(vr);
}
public static StoragePoolResponse fillStoragePoolDetails(StoragePoolResponse vrData, StoragePoolJoinVO vr) {
return s_poolJoinDao.setStoragePoolResponse(vrData, vr);
}

View File

@ -36,6 +36,7 @@ import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
import org.apache.cloudstack.api.ResourceDetail;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.command.admin.account.ListAccountsCmdByAdmin;
import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd;
import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd;
import org.apache.cloudstack.api.command.admin.iso.ListIsosCmdByAdmin;
@ -72,6 +73,7 @@ import org.apache.cloudstack.api.response.DiskOfferingResponse;
import org.apache.cloudstack.api.response.DomainRouterResponse;
import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.HostTagResponse;
import org.apache.cloudstack.api.response.ImageStoreResponse;
import org.apache.cloudstack.api.response.InstanceGroupResponse;
import org.apache.cloudstack.api.response.ListResponse;
@ -107,6 +109,7 @@ import com.cloud.api.query.dao.DataCenterJoinDao;
import com.cloud.api.query.dao.DiskOfferingJoinDao;
import com.cloud.api.query.dao.DomainRouterJoinDao;
import com.cloud.api.query.dao.HostJoinDao;
import com.cloud.api.query.dao.HostTagDao;
import com.cloud.api.query.dao.ImageStoreJoinDao;
import com.cloud.api.query.dao.InstanceGroupJoinDao;
import com.cloud.api.query.dao.ProjectAccountJoinDao;
@ -129,6 +132,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO;
import com.cloud.api.query.vo.DomainRouterJoinVO;
import com.cloud.api.query.vo.EventJoinVO;
import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.api.query.vo.HostTagVO;
import com.cloud.api.query.vo.ImageStoreJoinVO;
import com.cloud.api.query.vo.InstanceGroupJoinVO;
import com.cloud.api.query.vo.ProjectAccountJoinVO;
@ -290,6 +294,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
@Inject
private StorageTagDao _storageTagDao;
@Inject
private HostTagDao _hostTagDao;
@Inject
private ImageStoreJoinDao _imageStoreJoinDao;
@ -2183,6 +2190,47 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
return new Pair<List<StorageTagVO>, Integer>(vrs, count);
}
@Override
public ListResponse<HostTagResponse> searchForHostTags(ListHostTagsCmd cmd) {
Pair<List<HostTagVO>, Integer> result = searchForHostTagsInternal(cmd);
ListResponse<HostTagResponse> response = new ListResponse<HostTagResponse>();
List<HostTagResponse> tagResponses = ViewResponseHelper.createHostTagResponse(result.first().toArray(new HostTagVO[result.first().size()]));
response.setResponses(tagResponses, result.second());
return response;
}
private Pair<List<HostTagVO>, Integer> searchForHostTagsInternal(ListHostTagsCmd cmd) {
Filter searchFilter = new Filter(HostTagVO.class, "id", Boolean.TRUE, null, null);
SearchBuilder<HostTagVO> sb = _hostTagDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
SearchCriteria<HostTagVO> sc = sb.create();
// search host tag details by ids
Pair<List<HostTagVO>, Integer> uniqueTagPair = _hostTagDao.searchAndCount(sc, searchFilter);
Integer count = uniqueTagPair.second();
if (count.intValue() == 0) {
return uniqueTagPair;
}
List<HostTagVO> uniqueTags = uniqueTagPair.first();
Long[] vrIds = new Long[uniqueTags.size()];
int i = 0;
for (HostTagVO v : uniqueTags) {
vrIds[i++] = v.getId();
}
List<HostTagVO> vrs = _hostTagDao.searchByIds(vrIds);
return new Pair<List<HostTagVO>, Integer>(vrs, count);
}
@Override
public ListResponse<ImageStoreResponse> searchForImageStores(ListImageStoresCmd cmd) {
Pair<List<ImageStoreJoinVO>, Integer> result = searchForImageStoresInternal(cmd);

View File

@ -23,7 +23,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import org.apache.log4j.Logger;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
import org.apache.cloudstack.api.ApiConstants.VMDetails;
@ -35,6 +34,7 @@ import org.apache.cloudstack.api.response.DomainRouterResponse;
import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.HostForMigrationResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.HostTagResponse;
import org.apache.cloudstack.api.response.ImageStoreResponse;
import org.apache.cloudstack.api.response.InstanceGroupResponse;
import org.apache.cloudstack.api.response.ProjectAccountResponse;
@ -61,6 +61,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO;
import com.cloud.api.query.vo.DomainRouterJoinVO;
import com.cloud.api.query.vo.EventJoinVO;
import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.api.query.vo.HostTagVO;
import com.cloud.api.query.vo.ImageStoreJoinVO;
import com.cloud.api.query.vo.InstanceGroupJoinVO;
import com.cloud.api.query.vo.ProjectAccountJoinVO;
@ -301,6 +302,16 @@ public class ViewResponseHelper {
return list;
}
public static List<HostTagResponse> createHostTagResponse(HostTagVO... hostTags) {
ArrayList<HostTagResponse> list = new ArrayList<HostTagResponse>();
for (HostTagVO vr : hostTags) {
list.add(ApiDBUtils.newHostTagResponse(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.HostTagResponse;
import com.cloud.api.query.vo.HostTagVO;
import com.cloud.utils.db.GenericDao;
public interface HostTagDao extends GenericDao<HostTagVO, Long> {
HostTagResponse newHostTagResponse(HostTagVO hostTag);
List<HostTagVO> searchByIds(Long... hostTagIds);
}

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.HostTagResponse;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.api.query.vo.HostTagVO;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@Component
@Local(value = {HostTagDao.class})
public class HostTagDaoImpl extends GenericDaoBase<HostTagVO, Long> implements HostTagDao {
public static final Logger s_logger = Logger.getLogger(HostTagDaoImpl.class);
@Inject
private ConfigurationDao _configDao;
private final SearchBuilder<HostTagVO> stSearch;
private final SearchBuilder<HostTagVO> stIdSearch;
protected HostTagDaoImpl() {
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 host_tags WHERE ";
}
@Override
public HostTagResponse newHostTagResponse(HostTagVO tag) {
HostTagResponse tagResponse = new HostTagResponse();
tagResponse.setName(tag.getName());
tagResponse.setHostId(tag.getHostId());
tagResponse.setObjectName("hosttag");
return tagResponse;
}
@Override
public List<HostTagVO> 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<HostTagVO> uvList = new ArrayList<HostTagVO>();
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<HostTagVO> sc = stSearch.create();
sc.setParameters("idIN", (Object[])ids);
List<HostTagVO> 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<HostTagVO> sc = stSearch.create();
sc.setParameters("idIN", (Object[])ids);
List<HostTagVO> 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 = "host_tags")
public class HostTagVO extends BaseViewVO implements InternalIdentity {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "id")
private long id;
@Column(name = "tag")
private String name;
@Column(name = "host_id")
long hostId;
@Override
public long getId() {
return id;
}
public String getName() {
return name;
}
public long getHostId() {
return hostId;
}
public void setHostId(long hostId) {
this.hostId = hostId;
}
}

View File

@ -40,7 +40,6 @@ import javax.naming.ConfigurationException;
import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
@ -84,6 +83,7 @@ import org.apache.cloudstack.api.command.admin.host.AddSecondaryStorageCmd;
import org.apache.cloudstack.api.command.admin.host.CancelMaintenanceCmd;
import org.apache.cloudstack.api.command.admin.host.DeleteHostCmd;
import org.apache.cloudstack.api.command.admin.host.FindHostsForMigrationCmd;
import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd;
import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
import org.apache.cloudstack.api.command.admin.host.PrepareForMaintenanceCmd;
import org.apache.cloudstack.api.command.admin.host.ReconnectHostCmd;
@ -2564,6 +2564,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
cmdList.add(CancelMaintenanceCmd.class);
cmdList.add(DeleteHostCmd.class);
cmdList.add(ListHostsCmd.class);
cmdList.add(ListHostTagsCmd.class);
cmdList.add(FindHostsForMigrationCmd.class);
cmdList.add(PrepareForMaintenanceCmd.class);
cmdList.add(ReconnectHostCmd.class);