this is a good point to commit the code; have the basic domain specific service offering working

This commit is contained in:
abhishek 2010-11-30 12:26:50 -08:00
parent 3735ba1466
commit 9a6eaaf21f
12 changed files with 232 additions and 12 deletions

View File

@ -25,6 +25,7 @@ import com.cloud.api.BaseCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.BaseCmd.CommandType;
import com.cloud.api.response.ServiceOfferingResponse;
import com.cloud.offering.ServiceOffering;
@ -64,6 +65,9 @@ public class CreateServiceOfferingCmd extends BaseCmd {
@Parameter(name=ApiConstants.USE_VIRTUAL_NETWORK, type=CommandType.BOOLEAN, description="if true, the VM created will use default virtual networking. If false, the VM created will use a direct attached networking model. The default value is true.")
private Boolean useVirtualNetwork;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="the ID of the containing domain, null for public offerings")
private Long domainId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -100,7 +104,11 @@ public class CreateServiceOfferingCmd extends BaseCmd {
return tags;
}
public Boolean getUseVirtualNetwork() {
public Long getDomainId() {
return domainId;
}
public Boolean getUseVirtualNetwork() {
return useVirtualNetwork;
}

View File

@ -26,6 +26,7 @@ import com.cloud.api.ApiConstants;
import com.cloud.api.BaseListCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.BaseCmd.CommandType;
import com.cloud.api.response.ListResponse;
import com.cloud.api.response.ServiceOfferingResponse;
import com.cloud.offering.ServiceOffering;
@ -48,6 +49,9 @@ public class ListServiceOfferingsCmd extends BaseListCmd {
@Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, description="the ID of the virtual machine. Pass this in if you want to see the available service offering that a virtual machine can be changed to.")
private Long virtualMachineId;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="the ID of the domain associated with the service offering")
private Long domainId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@ -65,6 +69,9 @@ public class ListServiceOfferingsCmd extends BaseListCmd {
return virtualMachineId;
}
public Long getDomainId(){
return domainId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -56,6 +56,9 @@ public class ServiceOfferingResponse extends BaseResponse {
@SerializedName("tags") @Param(description="the tags for the service offering")
private String tags;
@SerializedName("domainId") @Param(description="the domain id of the service offering")
private Long domainId;
public Long getId() {
return id;
}
@ -143,4 +146,13 @@ public class ServiceOfferingResponse extends BaseResponse {
public void setTags(String tags) {
this.tags = tags;
}
public Long getDomainId() {
return domainId;
}
public void setDomainId(Long domainId) {
this.domainId = domainId;
}
}

View File

@ -77,4 +77,6 @@ public interface ServiceOffering {
*/
boolean getUseLocalStorage();
Long getDomainId();
}

View File

@ -120,6 +120,21 @@ public class DiskOfferingVO implements DiskOffering {
this.systemUse = systemUse;
this.customized = customized;
}
//domain specific offerings constructor (null domainId implies public offering)
public DiskOfferingVO(String name, String displayText, boolean mirrored, String tags, boolean recreatable, boolean useLocalStorage, boolean systemUse, boolean customized, Long domainId) {
this.domainId = null;
this.type = Type.Service;
this.name = name;
this.displayText = displayText;
this.mirrored = mirrored;
this.tags = tags;
this.recreatable = recreatable;
this.useLocalStorage = useLocalStorage;
this.systemUse = systemUse;
this.customized = customized;
this.domainId = domainId;
}
@Override
public long getId() {

View File

@ -345,6 +345,7 @@ public class ApiResponseHelper implements ResponseGenerator {
offeringResponse.setOfferHa(offering.getOfferHA());
offeringResponse.setUseVirtualNetwork(offering.getGuestIpType().equals(GuestIpType.Virtualized));
offeringResponse.setTags(offering.getTags());
offeringResponse.setDomainId(offering.getDomainId());
offeringResponse.setObjectName("serviceoffering");
return offeringResponse;

View File

@ -56,9 +56,10 @@ public interface ConfigurationManager extends Manager {
* @param localStorageRequired
* @param offerHA
* @param useVirtualNetwork
* @param domainId
* @return ID
*/
ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, boolean offerHA, boolean useVirtualNetwork, String tags);
ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, boolean offerHA, boolean useVirtualNetwork, String tags, Long domainId);

View File

@ -1138,18 +1138,18 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
}
return createServiceOffering(userId, cmd.getServiceOfferingName(), cpuNumber.intValue(), memory.intValue(), cpuSpeed.intValue(), cmd.getDisplayText(),
localStorageRequired, offerHA, useVirtualNetwork, cmd.getTags());
localStorageRequired, offerHA, useVirtualNetwork, cmd.getTags(),cmd.getDomainId());
}
@Override
public ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, boolean offerHA, boolean useVirtualNetwork, String tags) {
public ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, boolean offerHA, boolean useVirtualNetwork, String tags, Long domainId) {
String networkRateStr = _configDao.getValue("network.throttling.rate");
String multicastRateStr = _configDao.getValue("multicast.throttling.rate");
int networkRate = ((networkRateStr == null) ? 200 : Integer.parseInt(networkRateStr));
int multicastRate = ((multicastRateStr == null) ? 10 : Integer.parseInt(multicastRateStr));
NetworkOffering.GuestIpType guestIpType = useVirtualNetwork ? NetworkOffering.GuestIpType.Virtualized : NetworkOffering.GuestIpType.DirectSingle;
tags = cleanupTags(tags);
ServiceOfferingVO offering = new ServiceOfferingVO(name, cpu, ramSize, speed, networkRate, multicastRate, offerHA, displayText, guestIpType, localStorageRequired, false, tags, false);
ServiceOfferingVO offering = new ServiceOfferingVO(name, cpu, ramSize, speed, networkRate, multicastRate, offerHA, displayText, guestIpType, localStorageRequired, false, tags, false,domainId);
if ((offering = _serviceOfferingDao.persist(offering)) != null) {
saveConfigurationEvent(userId, null, EventTypes.EVENT_SERVICE_OFFERING_CREATE, "Successfully created new service offering with name: " + name + ".", "soId=" + offering.getId(), "name=" + name, "numCPUs=" + cpu, "ram=" + ramSize, "cpuSpeed=" + speed,

View File

@ -1592,17 +1592,70 @@ public class ManagementServerImpl implements ManagementServer {
return _userAccountDao.search(sc, searchFilter);
}
private boolean isPermissible(Long accountDomainId, Long serviceOfferingDomainId){
if(accountDomainId == serviceOfferingDomainId)
return true; // account and service offering in same domain
DomainVO domainRecord = _domainDao.findById(accountDomainId);
if(domainRecord != null){
while(true){
if(domainRecord.getId() == serviceOfferingDomainId)
return true;
//try and move on to the next domain
if(domainRecord.getParent() != null)
domainRecord = _domainDao.findById(domainRecord.getParent());
else
break;
}
}
return false;
}
@Override
public List<ServiceOfferingVO> searchForServiceOfferings(ListServiceOfferingsCmd cmd) throws InvalidParameterValueException, PermissionDeniedException {
Filter searchFilter = new Filter(ServiceOfferingVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
//Note
//The list method for offerings is being modified in accordance with discussion with Will/Kevin
//For now, we will be listing the following based on the usertype
//1. For root, we will list all offerings
//2. For domainAdmin and regular users, we will list everything in their domains+parent domains ... all the way till root
Filter searchFilter = new Filter(ServiceOfferingVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
SearchCriteria<ServiceOfferingVO> sc = _offeringsDao.createSearchCriteria();
Account account = UserContext.current().getAccount();
Object name = cmd.getServiceOfferingName();
Object id = cmd.getId();
Object keyword = cmd.getKeyword();
Long vmId = cmd.getVirtualMachineId();
Long domainId = cmd.getDomainId();
//Keeping this logic consistent with domain specific zones
//if a domainId is provided, we just return the so associated with this domain
if(domainId != null){
if(account.getType() == Account.ACCOUNT_TYPE_ADMIN){
return _offeringsDao.findServiceOfferingByDomainId(domainId);//no perm check
}else{
//check if the user's domain == so's domain || user's domain is a child of so's domain
if(isPermissible(account.getDomainId(), domainId)){
//perm check succeeded
return _offeringsDao.findServiceOfferingByDomainId(domainId);
}else{
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "The account:"+account.getAccountName()+" does not fall in the same domain hierarchy as the service offering");
}
}
}
//For non-root users
if((account.getType() == Account.ACCOUNT_TYPE_NORMAL || account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)){
return searchOfferingsInternal(account, name, id, vmId, keyword, searchFilter);
}
//for root users, the existing flow
if (keyword != null) {
SearchCriteria<ServiceOfferingVO> ssc = _offeringsDao.createSearchCriteria();
ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
@ -1610,8 +1663,6 @@ public class ManagementServerImpl implements ManagementServer {
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
} else if (vmId != null) {
Account account = UserContext.current().getAccount();
UserVmVO vmInstance = _userVmDao.findById(vmId);
if ((vmInstance == null) || (vmInstance.getRemoved() != null)) {
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
@ -1642,6 +1693,80 @@ public class ManagementServerImpl implements ManagementServer {
return _offeringsDao.search(sc, searchFilter);
}
private List<ServiceOfferingVO> searchOfferingsInternal(Account account, Object name, Object id, Long vmId, Object keyword, Filter searchFilter){
//it was decided to return all offerings for the user's domain, and everything above till root (for normal user or domain admin)
//list all offerings belonging to this domain, and all of its parents
//check the parent, if not null, add offerings for that parent to list
List<ServiceOfferingVO> sol = new ArrayList<ServiceOfferingVO>();
DomainVO domainRecord = _domainDao.findById(account.getDomainId());
boolean includePublicOfferings = true;
if(domainRecord != null)
{
while(true){
SearchCriteria<ServiceOfferingVO> sc = _offeringsDao.createSearchCriteria();
if (keyword != null) {
includePublicOfferings = false;
SearchCriteria<ServiceOfferingVO> ssc = _offeringsDao.createSearchCriteria();
ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
} else if (vmId != null) {
includePublicOfferings = false;
UserVmVO vmInstance = _userVmDao.findById(vmId);
if ((vmInstance == null) || (vmInstance.getRemoved() != null)) {
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
}
if ((account != null) && !isAdmin(account.getType())) {
if (account.getId() != vmInstance.getAccountId()) {
throw new PermissionDeniedException("unable to find a virtual machine with id " + vmId + " for this account");
}
}
ServiceOfferingVO offering = _offeringsDao.findById(vmInstance.getServiceOfferingId());
sc.addAnd("id", SearchCriteria.Op.NEQ, offering.getId());
// Only return offerings with the same Guest IP type and storage pool preference
sc.addAnd("guestIpType", SearchCriteria.Op.EQ, offering.getGuestIpType());
sc.addAnd("useLocalStorage", SearchCriteria.Op.EQ, offering.getUseLocalStorage());
}
if (id != null) {
includePublicOfferings = false;
sc.addAnd("id", SearchCriteria.Op.EQ, id);
}
if (name != null) {
includePublicOfferings = false;
sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%");
}
sc.addAnd("systemUse", SearchCriteria.Op.EQ, false);
//for this domain
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainRecord.getId());
//search and add for this domain
sol.addAll(_offeringsDao.search(sc, searchFilter));
//try and move on to the next domain
if(domainRecord.getParent() != null)
domainRecord = _domainDao.findById(domainRecord.getParent());
else
break;//now we got all the offerings for this user/dom adm
}
}else{
s_logger.error("Could not find the domainId for account:"+account.getAccountName());
throw new CloudAuthenticationException("Could not find the domainId for account:"+account.getAccountName());
}
//add all the public offerings to the sol list before returning
if(includePublicOfferings)
sol.addAll(_offeringsDao.findPublicServiceOfferings());
return sol;
}
@Override
public List<ClusterVO> searchForClusters(ListClustersCmd cmd) {
Filter searchFilter = new Filter(ClusterVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());

View File

@ -72,6 +72,17 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
this.offerHA = offerHA;
this.guestIpType = guestIpType;
}
public ServiceOfferingVO(String name, int cpu, int ramSize, int speed, int rateMbps, int multicastRateMbps, boolean offerHA, String displayText, NetworkOffering.GuestIpType guestIpType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, Long domainId) {
super(name, displayText, false, tags, recreatable, useLocalStorage, systemUse,false,domainId);
this.cpu = cpu;
this.ramSize = ramSize;
this.speed = speed;
this.rateMbps = rateMbps;
this.multicastRateMbps = multicastRateMbps;
this.offerHA = offerHA;
this.guestIpType = guestIpType;
}
@Override
public boolean getOfferHA() {
@ -145,5 +156,6 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
@Override
public NetworkOffering.GuestIpType getGuestIpType() {
return guestIpType;
}
}
}

View File

@ -18,6 +18,8 @@
package com.cloud.service.dao;
import java.util.List;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.utils.db.GenericDao;
@ -26,5 +28,7 @@ import com.cloud.utils.db.GenericDao;
*/
public interface ServiceOfferingDao extends GenericDao<ServiceOfferingVO, Long> {
ServiceOfferingVO findByName(String name);
ServiceOfferingVO persistSystemServiceOffering(ServiceOfferingVO vo);
ServiceOfferingVO persistSystemServiceOffering(ServiceOfferingVO vo);
List<ServiceOfferingVO> findPublicServiceOfferings();
List<ServiceOfferingVO> findServiceOfferingByDomainId(Long domainId);
}

View File

@ -25,6 +25,7 @@ import javax.persistence.EntityExistsException;
import org.apache.log4j.Logger;
import com.cloud.dc.DataCenterVO;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
@ -35,7 +36,11 @@ import com.cloud.utils.db.SearchCriteria;
public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Long> implements ServiceOfferingDao {
protected static final Logger s_logger = Logger.getLogger(ServiceOfferingDaoImpl.class);
protected final SearchBuilder<ServiceOfferingVO> UniqueNameSearch;
protected final SearchBuilder<ServiceOfferingVO> UniqueNameSearch;
protected final SearchBuilder<ServiceOfferingVO> ServiceOfferingsByDomainIdSearch;
protected final SearchBuilder<ServiceOfferingVO> ServiceOfferingsByKeywordSearch;
protected final SearchBuilder<ServiceOfferingVO> PublicServiceOfferingSearch;
protected ServiceOfferingDaoImpl() {
super();
@ -43,6 +48,20 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
UniqueNameSearch.and("name", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ);
UniqueNameSearch.and("system", UniqueNameSearch.entity().isSystemUse(), SearchCriteria.Op.EQ);
UniqueNameSearch.done();
ServiceOfferingsByDomainIdSearch = createSearchBuilder();
ServiceOfferingsByDomainIdSearch.and("domainId", ServiceOfferingsByDomainIdSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
ServiceOfferingsByDomainIdSearch.done();
PublicServiceOfferingSearch = createSearchBuilder();
PublicServiceOfferingSearch.and("domainId", PublicServiceOfferingSearch.entity().getDomainId(), SearchCriteria.Op.NULL);
PublicServiceOfferingSearch.and("system", PublicServiceOfferingSearch.entity().isSystemUse(), SearchCriteria.Op.EQ);
PublicServiceOfferingSearch.done();
ServiceOfferingsByKeywordSearch = createSearchBuilder();
ServiceOfferingsByKeywordSearch.or("name", ServiceOfferingsByKeywordSearch.entity().getName(), SearchCriteria.Op.EQ);
ServiceOfferingsByKeywordSearch.or("displayText", ServiceOfferingsByKeywordSearch.entity().getDisplayText(), SearchCriteria.Op.EQ);
ServiceOfferingsByKeywordSearch.done();
}
@Override
@ -71,5 +90,19 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
// Assume it's conflict on unique name
return findByName(offering.getUniqueName());
}
}
@Override
public List<ServiceOfferingVO> findServiceOfferingByDomainId(Long domainId){
SearchCriteria<ServiceOfferingVO> sc = ServiceOfferingsByDomainIdSearch.create();
sc.setParameters("domainId", domainId);
return listBy(sc);
}
@Override
public List<ServiceOfferingVO> findPublicServiceOfferings(){
SearchCriteria<ServiceOfferingVO> sc = PublicServiceOfferingSearch.create();
sc.setParameters("system", false);
return listBy(sc);
}
}