Intermidiate checkin for Projects feature; added 3 new apis - create/delete/listProject(s) - as a part of checkin

This commit is contained in:
alena 2011-07-01 09:21:42 -07:00
parent f28a2b40a3
commit 17f785f07a
20 changed files with 989 additions and 52 deletions

View File

@ -18,43 +18,44 @@
package com.cloud.api;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
import com.cloud.configuration.ConfigurationService;
import com.cloud.consoleproxy.ConsoleProxyService;
import com.cloud.dao.EntityManager;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.NetworkService;
import com.cloud.network.VirtualNetworkApplianceService;
import com.cloud.network.lb.LoadBalancingRulesService;
import com.cloud.network.rules.RulesService;
import com.cloud.network.security.SecurityGroupService;
import com.cloud.network.vpn.RemoteAccessVpnService;
import com.cloud.resource.ResourceService;
import com.cloud.server.ManagementService;
import com.cloud.storage.StorageService;
import com.cloud.storage.snapshot.SnapshotService;
import com.cloud.template.TemplateService;
import com.cloud.user.Account;
import com.cloud.user.AccountService;
import com.cloud.user.UserContext;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.vm.UserVmService;
import com.cloud.vm.BareMetalVmService;
import org.apache.log4j.Logger;
import com.cloud.configuration.ConfigurationService;
import com.cloud.consoleproxy.ConsoleProxyService;
import com.cloud.dao.EntityManager;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.NetworkService;
import com.cloud.network.VirtualNetworkApplianceService;
import com.cloud.network.lb.LoadBalancingRulesService;
import com.cloud.network.rules.RulesService;
import com.cloud.network.security.SecurityGroupService;
import com.cloud.network.vpn.RemoteAccessVpnService;
import com.cloud.projects.ProjectService;
import com.cloud.resource.ResourceService;
import com.cloud.server.ManagementService;
import com.cloud.storage.StorageService;
import com.cloud.storage.snapshot.SnapshotService;
import com.cloud.template.TemplateService;
import com.cloud.user.Account;
import com.cloud.user.AccountService;
import com.cloud.user.UserContext;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.vm.BareMetalVmService;
import com.cloud.vm.UserVmService;
public abstract class BaseCmd {
private static final Logger s_logger = Logger.getLogger(BaseCmd.class.getName());
@ -114,7 +115,8 @@ public abstract class BaseCmd {
public static RulesService _rulesService;
public static LoadBalancingRulesService _lbService;
public static RemoteAccessVpnService _ravService;
public static BareMetalVmService _bareMetalVmService;
public static BareMetalVmService _bareMetalVmService;
public static ProjectService _projectService;
static void setComponents(ResponseGenerator generator) {
@ -136,7 +138,8 @@ public abstract class BaseCmd {
_lbService = locator.getManager(LoadBalancingRulesService.class);
_ravService = locator.getManager(RemoteAccessVpnService.class);
_responseGenerator = generator;
_bareMetalVmService = locator.getManager(BareMetalVmService.class);
_bareMetalVmService = locator.getManager(BareMetalVmService.class);
_projectService = locator.getManager(ProjectService.class);
}
public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException;

View File

@ -19,7 +19,6 @@ package com.cloud.api;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Set;
import com.cloud.api.commands.QueryAsyncJobResultCmd;
import com.cloud.api.response.AccountResponse;
@ -43,9 +42,10 @@ import com.cloud.api.response.LoadBalancerResponse;
import com.cloud.api.response.NetworkOfferingResponse;
import com.cloud.api.response.NetworkResponse;
import com.cloud.api.response.PodResponse;
import com.cloud.api.response.ProjectResponse;
import com.cloud.api.response.RemoteAccessVpnResponse;
import com.cloud.api.response.ResourceLimitResponse;
import com.cloud.api.response.ResourceCountResponse;
import com.cloud.api.response.ResourceLimitResponse;
import com.cloud.api.response.SecurityGroupResponse;
import com.cloud.api.response.ServiceOfferingResponse;
import com.cloud.api.response.SnapshotPolicyResponse;
@ -63,8 +63,8 @@ import com.cloud.api.response.ZoneResponse;
import com.cloud.async.AsyncJob;
import com.cloud.capacity.Capacity;
import com.cloud.configuration.Configuration;
import com.cloud.configuration.ResourceLimit;
import com.cloud.configuration.ResourceCount;
import com.cloud.configuration.ResourceLimit;
import com.cloud.dc.DataCenter;
import com.cloud.dc.Pod;
import com.cloud.dc.Vlan;
@ -86,6 +86,7 @@ import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.org.Cluster;
import com.cloud.projects.Project;
import com.cloud.storage.Snapshot;
import com.cloud.storage.StoragePool;
import com.cloud.storage.Volume;
@ -95,7 +96,6 @@ import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.user.UserAccount;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
import com.cloud.vm.InstanceGroup;
import com.cloud.vm.VirtualMachine;
@ -201,5 +201,7 @@ public interface ResponseGenerator {
Long getSecurityGroupId(String groupName, long accountId);
List<TemplateResponse> createIsoResponses(long isoId, Long zoneId, boolean readyOnly);
ProjectResponse createProjectResponse(Project project);
}

View File

@ -0,0 +1,123 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.api.commands;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.BaseCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.ProjectResponse;
import com.cloud.projects.Project;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
@Implementation(description="Creates a project", responseObject=ProjectResponse.class)
public class CreateProjectCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(CreateProjectCmd.class.getName());
private static final String s_name = "createprojectresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="account who will own the project")
private String accountName;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="domain ID of the account owning a project")
private Long domainId;
@Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="name of the project")
private String name;
@Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, required=true, description="display text of the project")
private String displayText;
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the zone id of the project")
private Long zoneId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getAccountName() {
return accountName;
}
public Long getDomainId() {
return domainId;
}
public String getName() {
return name;
}
public String getDisplayText() {
return displayText;
}
public Long getZoneId() {
return zoneId;
}
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
Account account = UserContext.current().getCaller();
if ((account == null) || isAdmin(account.getType())) {
if ((domainId != null) && (accountName != null)) {
Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId);
if (userAccount != null) {
return userAccount.getId();
}
}
}
if (account != null) {
return account.getId();
}
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute(){
UserContext.current().setEventDetails("Project Name: "+ getName() + ", zoneId " + zoneId);
Project project = _projectService.createProject(getName(), getDisplayText(), getZoneId(), getAccountName(), getDomainId());
if (project != null) {
ProjectResponse response = _responseGenerator.createProjectResponse(project);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create a project");
}
}
}

View File

@ -0,0 +1,100 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.api.commands;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.BaseAsyncCmd;
import com.cloud.api.BaseCmd;
import com.cloud.api.BaseCmd.CommandType;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.ProjectResponse;
import com.cloud.api.response.SuccessResponse;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.Network;
import com.cloud.projects.Project;
import com.cloud.user.UserContext;
@Implementation(description="Deletes a project", responseObject=SuccessResponse.class)
public class DeleteProjectCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(DeleteProjectCmd.class.getName());
private static final String s_name = "deleteprojectresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="id of the project to be deleted")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long geId() {
return id;
}
@Override
public String getCommandName() {
return s_name;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute(){
UserContext.current().setEventDetails("Project Id: " + id);
boolean result = _projectService.deleteProject(id);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete project");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_PROJECT_DELETE;
}
@Override
public String getEventDescription() {
return "Deleting project: " + id;
}
@Override
public long getEntityOwnerId() {
Project project = _projectService.getProject(id);
if (project == null) {
throw new InvalidParameterValueException("Project id=" + id + " doesn't exist");
} else {
return _projectService.getProject(id).getAccountId();
}
}
}

View File

@ -0,0 +1,111 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.api.commands;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.BaseListCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.response.ListResponse;
import com.cloud.api.response.ProjectResponse;
import com.cloud.projects.Project;
@Implementation(description="Lists projects and provides detailed information for listed projects", responseObject=ProjectResponse.class)
public class ListProjectsCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListProjectsCmd.class.getName());
private static final String s_name = "listprojectsresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="list projects by project ID")
private Long id;
@Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="list projects by owner name")
private String accountName;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="list projects for the domain specified")
private Long domainId;
@Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="list projects by name")
private String name;
@Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="list projects by display text")
private String displayText;
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="list projects for specific zone")
private Long zoneId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
public String getAccountName() {
return accountName;
}
public Long getDomainId() {
return domainId;
}
public String getName() {
return name;
}
public String getDisplayText() {
return displayText;
}
public Long getZoneId() {
return zoneId;
}
@Override
public String getCommandName() {
return s_name;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute(){
List<? extends Project> projects = _projectService.listProjects(id, name, displayText, zoneId, accountName, domainId, this.getKeyword(), this.getStartIndex(), this.getPageSizeVal());
ListResponse<ProjectResponse> response = new ListResponse<ProjectResponse>();
List<ProjectResponse> projectResponses = new ArrayList<ProjectResponse>();
for (Project project : projects) {
ProjectResponse projectResponse = _responseGenerator.createProjectResponse(project);
projectResponses.add(projectResponse);
}
response.setResponses(projectResponses);
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
}

View File

@ -0,0 +1,103 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.api.response;
import com.cloud.api.ApiConstants;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
public class ProjectResponse extends BaseResponse{
@SerializedName("id") @Param(description="the id of the project")
private Long id;
@SerializedName("name") @Param(description="the name of the project")
private String name;
@SerializedName("displaytext") @Param(description="the displaytext of the project")
private String displaytext;
@SerializedName("zoneid") @Param(description="zone id of the project")
private Long zoneId;
@SerializedName(ApiConstants.ACCOUNT) @Param(description="the owner of the project")
private String accountName;
@SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain id of the project owner")
private Long domainId;
@SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the project owner")
private String domain;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getZoneId() {
return zoneId;
}
public void setZoneId(Long zoneId) {
this.zoneId = zoneId;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public Long getDomainId() {
return domainId;
}
public void setDomainId(Long domainId) {
this.domainId = domainId;
}
public String getDisplaytext() {
return displaytext;
}
public void setDisplaytext(String displaytext) {
this.displaytext = displaytext;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
}

View File

@ -200,4 +200,8 @@ public class EventTypes {
public static final String EVENT_ZONE_VLAN_ASSIGN = "ZONE.VLAN.ASSIGN";
public static final String EVENT_ZONE_VLAN_RELEASE = "ZONE.VLAN.RELEASE";
//Projects
public static final String EVENT_PROJECT_CREATE = "PROJECT.CREATE";
public static final String EVENT_PROJECT_DELETE = "PROJECT.DELETE";
}

View File

@ -0,0 +1,25 @@
package com.cloud.projects;
import java.util.Date;
import com.cloud.acl.ControlledEntity;
public interface Project extends ControlledEntity{
String getDisplayText();
long getDomainId();
long getAccountId();
long getId();
Date getCreated();
Date getRemoved();
long getDataCenterId();
String getName();
}

View File

@ -0,0 +1,36 @@
package com.cloud.projects;
import java.util.List;
public interface ProjectService {
/**
* Creates a new project
*
* @param name - project name
* @param displayText - project display text
* @param zoneId - id of the zone the project belongs to
* @param accountName - account name of the project owner
* @param domainId - domainid of the project owner
* @return the project if created successfully, null otherwise
*/
Project createProject(String name, String displayText, long zoneId, String accountName, Long domainId);
/**
* Deletes a project
*
* @param id - project id
* @return true if the project was deleted successfully, false otherwise
*/
boolean deleteProject(long id);
/**
* Gets a project by id
*
* @param id - project id
* @return project object
*/
Project getProject(long id);
List<? extends Project> listProjects(Long id, String name, String displayText, Long zoneId, String accountName, Long domainId, String keyword, Long startIndex, Long pageSize);
}

View File

@ -260,3 +260,7 @@ createSSHKeyPair=com.cloud.api.commands.CreateSSHKeyPairCmd;15
deleteSSHKeyPair=com.cloud.api.commands.DeleteSSHKeyPairCmd;15
listSSHKeyPairs=com.cloud.api.commands.ListSSHKeyPairsCmd;15
#### Projects commands
createProject=com.cloud.api.commands.CreateProjectCmd;15
deleteProject=com.cloud.api.commands.DeleteProjectCmd;15
listProjects=com.cloud.api.commands.ListProjectsCmd;15

View File

@ -55,11 +55,11 @@ import com.cloud.api.response.ListResponse;
import com.cloud.api.response.LoadBalancerResponse;
import com.cloud.api.response.NetworkOfferingResponse;
import com.cloud.api.response.NetworkResponse;
import com.cloud.api.response.NicResponse;
import com.cloud.api.response.PodResponse;
import com.cloud.api.response.ProjectResponse;
import com.cloud.api.response.RemoteAccessVpnResponse;
import com.cloud.api.response.ResourceLimitResponse;
import com.cloud.api.response.ResourceCountResponse;
import com.cloud.api.response.ResourceLimitResponse;
import com.cloud.api.response.SecurityGroupResponse;
import com.cloud.api.response.SecurityGroupResultObject;
import com.cloud.api.response.ServiceOfferingResponse;
@ -81,9 +81,9 @@ import com.cloud.async.AsyncJobResult;
import com.cloud.capacity.Capacity;
import com.cloud.capacity.CapacityVO;
import com.cloud.configuration.Configuration;
import com.cloud.configuration.ResourceCount;
import com.cloud.configuration.ResourceCount.ResourceType;
import com.cloud.configuration.ResourceLimit;
import com.cloud.configuration.ResourceCount;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
@ -116,11 +116,11 @@ import com.cloud.network.rules.StaticNatRule;
import com.cloud.network.security.IngressRule;
import com.cloud.network.security.SecurityGroup;
import com.cloud.network.security.SecurityGroupRules;
import com.cloud.network.security.SecurityGroupVO;
import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.org.Cluster;
import com.cloud.projects.Project;
import com.cloud.server.Criteria;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.GuestOS;
@ -148,12 +148,10 @@ import com.cloud.user.UserContext;
import com.cloud.user.UserStatisticsVO;
import com.cloud.user.UserVO;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.InstanceGroup;
import com.cloud.vm.InstanceGroupVO;
import com.cloud.vm.NicProfile;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
@ -2076,4 +2074,23 @@ public class ApiResponseHelper implements ResponseGenerator {
return sg.getId();
}
}
@Override
public ProjectResponse createProjectResponse(Project project) {
ProjectResponse response = new ProjectResponse();
response.setId(project.getId());
response.setName(project.getName());
response.setDisplaytext(project.getDisplayText());
response.setZoneId(project.getDataCenterId());
Account owner = ApiDBUtils.findAccountById(project.getAccountId());
response.setAccountName(owner.getAccountName());
Domain domain = ApiDBUtils.findDomainById(owner.getDomainId());
response.setDomainId(domain.getId());
response.setDomain(domain.getName());
response.setObjectName("project");
return response;
}
}

View File

@ -238,6 +238,7 @@ public enum Config {
DefaultMaxAccountTemplates("Account Defaults", ManagementServer.class, Long.class, "max.account.templates", "20", "The default maximum number of templates that can be deployed for an account", null),
DefaultMaxAccountSnapshots("Account Defaults", ManagementServer.class, Long.class, "max.account.snapshots", "20", "The default maximum number of snapshots that can be created for an account", null),
DefaultMaxAccountVolumes("Account Defaults", ManagementServer.class, Long.class, "max.account.volumes", "20", "The default maximum number of volumes that can be created for an account", null),
DefaultMaxAccountProjects("Account Defaults", ManagementServer.class, Long.class, "max.account.projects", "20", "The default maximum number of projects that can be created for an account", null),
DirectAgentLoadSize("Advanced", ManagementServer.class, Integer.class, "direct.agent.load.size", "16", "The number of direct agents to load each time", null),
AgentLbEnable("Advanced", ClusterManager.class, Boolean.class, "agent.lb.enabled", "true", "If agent load balancing enabled in cluster setup", null),

View File

@ -103,6 +103,8 @@ import com.cloud.network.security.dao.SecurityGroupWorkDaoImpl;
import com.cloud.network.security.dao.VmRulesetLogDaoImpl;
import com.cloud.network.vpn.RemoteAccessVpnManagerImpl;
import com.cloud.offerings.dao.NetworkOfferingDaoImpl;
import com.cloud.projects.ProjectManagerImpl;
import com.cloud.projects.dao.ProjectDaoImpl;
import com.cloud.resource.ResourceManagerImpl;
import com.cloud.service.dao.ServiceOfferingDaoImpl;
import com.cloud.storage.StorageManagerImpl;
@ -274,6 +276,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
addDao("DcDetailsDao", DcDetailsDaoImpl.class);
addDao("SwiftDao", SwiftDaoImpl.class);
addDao("AgentTransferMapDao", HostTransferMapDaoImpl.class);
addDao("ProjectDao", ProjectDaoImpl.class);
}
@Override
@ -321,6 +324,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
ComponentInfo<? extends Manager> info = addManager("ConsoleProxyManager", ConsoleProxyManagerImpl.class);
info.addParameter("consoleproxy.sslEnabled", "true");
addManager("ClusteredAgentManager", ClusteredAgentManagerImpl.class);
addManager("ProjectManager", ProjectManagerImpl.class);
}
@Override

View File

@ -0,0 +1,4 @@
package com.cloud.projects;
public interface ProjectManager extends ProjectService{
}

View File

@ -0,0 +1,224 @@
package com.cloud.projects;
import java.util.List;
import java.util.Map;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenter;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.projects.dao.ProjectDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.UserContext;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
import com.cloud.utils.component.Manager;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
@Local(value = { ProjectService.class })
public class ProjectManagerImpl implements ProjectManager, Manager{
public static final Logger s_logger = Logger.getLogger(ProjectManagerImpl.class);
private String _name;
private long _maxProjects;
@Inject
private AccountDao _accountDao;
@Inject
private DomainDao _domainDao;
@Inject
private ProjectDao _projectDao;
@Inject
AccountManager _accountMgr;
@Inject
ConfigurationManager _configMgr;
@Override
public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
_name = name;
ComponentLocator locator = ComponentLocator.getCurrentLocator();
ConfigurationDao configDao = locator.getDao(ConfigurationDao.class);
Map<String, String> configs = configDao.getConfiguration(params);
String value = configs.get(Config.DefaultMaxAccountProjects.key());
_maxProjects = NumbersUtil.parseLong(value, 20);
return true;
}
@Override
public boolean start() {
return true;
}
@Override
public boolean stop() {
return true;
}
@Override
public String getName() {
return _name;
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project")
public Project createProject(String name, String displayText, long zoneId, String accountName, Long domainId) {
Account caller = UserContext.current().getCaller();
Account owner = caller;
//Verify request parameters
if ((accountName != null && domainId == null) || (domainId != null && accountName == null)) {
throw new InvalidParameterValueException("Account name and domain id must be specified together");
}
if (accountName != null) {
owner = _accountMgr.finalizeOwner(caller, accountName, domainId);
}
DataCenter zone = _configMgr.getZone(zoneId);
if (zone == null) {
throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
}
//TODO - do resource limit check here
Project project = _projectDao.persist(new ProjectVO(name, displayText, zoneId, owner.getAccountId(), owner.getDomainId()));
if (project != null) {
UserContext.current().setEventDetails("Project id=" + project.getId());
}
return project;
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_DELETE, eventDescription = "deleting project", async = true)
public boolean deleteProject (long projectId) {
Account caller = UserContext.current().getCaller();
Project project= getProject(projectId);
//verify input parameters
if (project == null) {
throw new InvalidParameterValueException("Unable to find project by id " + projectId);
}
_accountMgr.checkAccess(caller, project);
//TODO - delete all project resources here
return _projectDao.remove(projectId);
}
@Override
public Project getProject (long projectId) {
return _projectDao.findById(projectId);
}
@Override
public List<? extends Project> listProjects(Long id, String name, String displayText, Long zoneId, String accountName, Long domainId, String keyword, Long startIndex, Long pageSize) {
Account caller = UserContext.current().getCaller();
Long accountId = null;
String path = null;
Filter searchFilter = new Filter(ProjectVO.class, "id", false, startIndex, pageSize);
SearchBuilder<ProjectVO> sb = _projectDao.createSearchBuilder();
if (_accountMgr.isAdmin(caller.getType())) {
if (domainId != null) {
DomainVO domain = _domainDao.findById(domainId);
if (domain == null) {
throw new InvalidParameterValueException("Domain id=" + domainId + " doesn't exist in the system");
}
_accountMgr.checkAccess(caller, domain);
if (accountName != null) {
Account owner = _accountMgr.getActiveAccount(accountName, domainId);
if (owner == null) {
throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId);
}
accountId = owner.getId();
}
}
if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
DomainVO domain = _domainDao.findById(caller.getDomainId());
path = domain.getPath();
}
} else {
if (accountName != null && !accountName.equals(caller.getAccountName())) {
throw new PermissionDeniedException("Can't list account " + accountName + " projects; unauthorized");
}
if (domainId != null && domainId.equals(caller.getDomainId())) {
throw new PermissionDeniedException("Can't list domain id= " + domainId + " projects; unauthorized");
}
accountId = caller.getId();
}
if (path != null) {
SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
}
SearchCriteria<ProjectVO> sc = sb.create();
if (id != null) {
sc.addAnd("id", Op.EQ, id);
}
if (name != null) {
sc.addAnd("name", Op.EQ, name);
}
if (displayText != null) {
sc.addAnd("displayText", Op.EQ, displayText);
}
if (zoneId != null) {
sc.addAnd("dataCenterId", Op.EQ, zoneId);
}
if (accountId != null) {
sc.addAnd("accountId", Op.EQ, accountId);
}
if (keyword != null) {
SearchCriteria<ProjectVO> ssc = _projectDao.createSearchCriteria();
ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
}
if (path != null) {
sc.setJoinParameters("domainSearch", "path", path);
}
return _projectDao.search(sc, searchFilter);
}
}

View File

@ -0,0 +1,140 @@
package com.cloud.projects;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.cloud.utils.db.GenericDao;
@Entity
@Table(name="projects")
public class ProjectVO implements Project{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private long id;
@Column(name="name")
private String name;
@Column(name="display_text")
String displayText;
@Column(name="domain_id")
long domainId;
@Column(name="account_id")
long accountId;
@Column(name="data_center_id")
long dataCenterId;
@Column(name=GenericDao.CREATED_COLUMN)
private Date created;
@Column(name=GenericDao.REMOVED_COLUMN)
private Date removed;
@Column(name="cleanup_needed")
private boolean needsCleanup = false;
protected ProjectVO(){
}
public ProjectVO(String name, String displayText, long dataCenterId, long accountId, long domainId) {
this.name = name;
this.displayText = displayText;
this.accountId = accountId;
this.domainId = domainId;
this.dataCenterId = dataCenterId;
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getDisplayText() {
return displayText;
}
public void setDisplayText(String displayText) {
this.displayText = displayText;
}
@Override
public long getDomainId() {
return domainId;
}
public void setDomainId(long domainId) {
this.domainId = domainId;
}
@Override
public long getAccountId() {
return accountId;
}
public void setAccountId(long accountId) {
this.accountId = accountId;
}
@Override
public long getId() {
return id;
}
@Override
public Date getCreated() {
return created;
}
@Override
public Date getRemoved() {
return removed;
}
@Override
public long getDataCenterId() {
return dataCenterId;
}
public void setNeedsCleanup(boolean value) {
needsCleanup = value;
}
public boolean getNeedsCleanup() {
return needsCleanup;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder("Project[");
buf.append(id).append("|").append(name).append("|domainid=").append(domainId).append("]");
return buf.toString();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ProjectVO)) {
return false;
}
ProjectVO that = (ProjectVO)obj;
if (this.id != that.id) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,8 @@
package com.cloud.projects.dao;
import com.cloud.projects.ProjectVO;
import com.cloud.utils.db.GenericDao;
public interface ProjectDao extends GenericDao<ProjectVO, Long>{
}

View File

@ -0,0 +1,11 @@
package com.cloud.projects.dao;
import javax.ejb.Local;
import com.cloud.projects.ProjectVO;
import com.cloud.utils.db.GenericDaoBase;
@Local(value={ProjectDao.class})
public class ProjectDaoImpl extends GenericDaoBase<ProjectVO, Long> implements ProjectDao {
}

View File

@ -53,10 +53,9 @@ import com.cloud.api.commands.UpdateResourceLimitCmd;
import com.cloud.api.commands.UpdateUserCmd;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.ResourceCount;
import com.cloud.configuration.ResourceCount.ResourceType;
import com.cloud.configuration.ResourceCountVO;
import com.cloud.configuration.ResourceLimitVO;
import com.cloud.configuration.ResourceCount.ResourceType;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.configuration.dao.ResourceCountDao;
import com.cloud.configuration.dao.ResourceLimitDao;
@ -71,7 +70,6 @@ import com.cloud.event.UsageEventVO;
import com.cloud.event.dao.UsageEventDao;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.PermissionDeniedException;
@ -120,7 +118,6 @@ import com.cloud.vm.ReservationContextImpl;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.dao.InstanceGroupDao;
import com.cloud.vm.dao.UserVmDao;

View File

@ -114,6 +114,7 @@ DROP TABLE IF EXISTS `cloud`.`vpn_users`;
DROP TABLE IF EXISTS `cloud`.`data_center_details`;
DROP TABLE IF EXISTS `cloud`.`network_tags`;
DROP TABLE IF EXISTS `cloud`.`op_host_transfer`;
DROP TABLE IF EXISTS `cloud`.`projects`;
CREATE TABLE `cloud`.`version` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
@ -1544,4 +1545,23 @@ CREATE TABLE `cloud`.`op_host_transfer` (
CONSTRAINT `fk_op_host_transfer__future_mgmt_server_id` FOREIGN KEY `fk_op_host_transfer__future_mgmt_server_id`(`future_mgmt_server_id`) REFERENCES `mshost`(`msid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`projects` (
`id` bigint unsigned NOT NULL auto_increment,
`name` varchar(255) COMMENT 'project name',
`display_text` varchar(255) COMMENT 'project name',
`account_id` bigint unsigned,
`domain_id` bigint unsigned,
`data_center_id` bigint unsigned,
`created` datetime COMMENT 'date created',
`removed` datetime COMMENT 'date removed',
`cleanup_needed` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`id`),
CONSTRAINT `fk_projects__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE,
CONSTRAINT `fk_projects__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`),
CONSTRAINT `fk_projects__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE,
INDEX `i_projects__removed`(`removed`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET foreign_key_checks = 1;