diff --git a/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java b/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java index e7d37907dad..4d429240506 100644 --- a/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java +++ b/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java @@ -22,7 +22,8 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.BaseCmd.CommandType; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -31,7 +32,7 @@ import com.cloud.api.response.NetworkACLResponse; import com.cloud.network.rules.FirewallRule; @Implementation(description="Lists all network ACLs", responseObject=NetworkACLResponse.class) -public class ListNetworkACLsCmd extends BaseListProjectAndAccountResourcesCmd { +public class ListNetworkACLsCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListNetworkACLsCmd.class.getName()); private static final String s_name = "listnetworkaclsresponse"; diff --git a/api/src/com/cloud/api/commands/ListProjectsCmd.java b/api/src/com/cloud/api/commands/ListProjectsCmd.java index 6a40461b5a7..0b0162c9681 100644 --- a/api/src/com/cloud/api/commands/ListProjectsCmd.java +++ b/api/src/com/cloud/api/commands/ListProjectsCmd.java @@ -13,7 +13,11 @@ package com.cloud.api.commands; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import org.apache.log4j.Logger; @@ -24,6 +28,7 @@ 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.exception.InvalidParameterValueException; import com.cloud.projects.Project; @Implementation(description="Lists projects and provides detailed information for listed projects", responseObject=ProjectResponse.class, since="3.0.0") @@ -48,6 +53,9 @@ public class ListProjectsCmd extends BaseListAccountResourcesCmd { @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="list projects by state") private String state; + @Parameter(name = ApiConstants.TAGS, type = CommandType.MAP, description = "List projects by tags (key/value pairs)") + private Map tags; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -68,6 +76,25 @@ public class ListProjectsCmd extends BaseListAccountResourcesCmd { public String getCommandName() { return s_name; } + + public Map getTags() { + Map tagsMap = null; + if (tags != null && !tags.isEmpty()) { + tagsMap = new HashMap(); + Collection servicesCollection = tags.values(); + Iterator iter = servicesCollection.iterator(); + while (iter.hasNext()) { + HashMap services = (HashMap) iter.next(); + String key = services.get("key"); + String value = services.get("value"); + if (value == null) { + throw new InvalidParameterValueException("No value is passed in for key " + key); + } + tagsMap.put(key, value); + } + } + return tagsMap; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// @@ -75,7 +102,9 @@ public class ListProjectsCmd extends BaseListAccountResourcesCmd { @Override public void execute(){ - List projects = _projectService.listProjects(id, name, displayText, state, this.getAccountName(), this.getDomainId(), this.getKeyword(), this.getStartIndex(), this.getPageSizeVal(), this.listAll(), this.isRecursive()); + List projects = _projectService.listProjects(id, name, displayText, state, + this.getAccountName(), this.getDomainId(), this.getKeyword(), this.getStartIndex(), this.getPageSizeVal(), + this.listAll(), this.isRecursive(), getTags()); ListResponse response = new ListResponse(); List projectResponses = new ArrayList(); for (Project project : projects) { diff --git a/api/src/com/cloud/api/commands/ListStaticRoutesCmd.java b/api/src/com/cloud/api/commands/ListStaticRoutesCmd.java index f3e0021bc94..3039bca13b9 100644 --- a/api/src/com/cloud/api/commands/ListStaticRoutesCmd.java +++ b/api/src/com/cloud/api/commands/ListStaticRoutesCmd.java @@ -16,7 +16,7 @@ import java.util.ArrayList; import java.util.List; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -29,7 +29,7 @@ import com.cloud.network.vpc.StaticRoute; */ @Implementation(description="Lists all static routes", responseObject=StaticRouteResponse.class) -public class ListStaticRoutesCmd extends BaseListProjectAndAccountResourcesCmd { +public class ListStaticRoutesCmd extends BaseListTaggedResourcesCmd { private static final String s_name = "liststaticroutesresponse"; ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/commands/ListVPCsCmd.java b/api/src/com/cloud/api/commands/ListVPCsCmd.java index 26064e79084..e60c6e290f6 100644 --- a/api/src/com/cloud/api/commands/ListVPCsCmd.java +++ b/api/src/com/cloud/api/commands/ListVPCsCmd.java @@ -18,7 +18,7 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseListAccountResourcesCmd; +import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; @@ -31,7 +31,7 @@ import com.cloud.network.vpc.Vpc; */ @Implementation(description="Lists VPCs", responseObject=VpcResponse.class) -public class ListVPCsCmd extends BaseListAccountResourcesCmd{ +public class ListVPCsCmd extends BaseListTaggedResourcesCmd{ public static final Logger s_logger = Logger.getLogger(ListVPCsCmd.class.getName()); private static final String s_name = "listvpcsresponse"; @@ -137,7 +137,7 @@ public class ListVPCsCmd extends BaseListAccountResourcesCmd{ List vpcs = _vpcService.listVpcs(getId(), getVpcName(), getDisplayText(), getSupportedServices(), getCidr(), getVpcOffId(), getState(), getAccountName(), getDomainId(), this.getKeyword(), this.getStartIndex(), this.getPageSizeVal(), getZoneId(), this.isRecursive(), - this.listAll(), getRestartRequired()); + this.listAll(), getRestartRequired(), getTags()); ListResponse response = new ListResponse(); List offeringResponses = new ArrayList(); for (Vpc vpc : vpcs) { diff --git a/api/src/com/cloud/api/response/NetworkACLResponse.java b/api/src/com/cloud/api/response/NetworkACLResponse.java index 1338d89f57a..f54b05fc9af 100644 --- a/api/src/com/cloud/api/response/NetworkACLResponse.java +++ b/api/src/com/cloud/api/response/NetworkACLResponse.java @@ -12,6 +12,8 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.api.response; +import java.util.List; + import com.cloud.api.ApiConstants; import com.cloud.serializer.Param; import com.cloud.utils.IdentityProxy; @@ -45,6 +47,10 @@ public class NetworkACLResponse extends BaseResponse { @SerializedName(ApiConstants.ICMP_CODE) @Param(description = "error code for this icmp message") private Integer icmpCode; + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with the network ACLs", + responseObject = ResourceTagResponse.class) + private List tags; public void setId(Long id) { this.id.setValue(id); @@ -81,4 +87,8 @@ public class NetworkACLResponse extends BaseResponse { public void setTrafficType(String trafficType) { this.trafficType = trafficType; } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/api/response/ProjectResponse.java b/api/src/com/cloud/api/response/ProjectResponse.java index 6bcadbb3457..d49abb3182a 100644 --- a/api/src/com/cloud/api/response/ProjectResponse.java +++ b/api/src/com/cloud/api/response/ProjectResponse.java @@ -12,9 +12,11 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.api.response; +import java.util.List; + import com.cloud.api.ApiConstants; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; import com.google.gson.annotations.SerializedName; @SuppressWarnings("unused") @@ -40,6 +42,9 @@ public class ProjectResponse extends BaseResponse{ @SerializedName(ApiConstants.STATE) @Param(description="the state of the project") private String state; + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with vm", responseObject = ResourceTagResponse.class) + private List tags; public void setId(Long id) { @@ -69,4 +74,8 @@ public class ProjectResponse extends BaseResponse{ public void setState(String state) { this.state = state; } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/api/response/StaticRouteResponse.java b/api/src/com/cloud/api/response/StaticRouteResponse.java index 025be6e0b82..6faef646547 100644 --- a/api/src/com/cloud/api/response/StaticRouteResponse.java +++ b/api/src/com/cloud/api/response/StaticRouteResponse.java @@ -12,6 +12,8 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.api.response; +import java.util.List; + import com.cloud.api.ApiConstants; import com.cloud.serializer.Param; import com.cloud.utils.IdentityProxy; @@ -54,6 +56,10 @@ public class StaticRouteResponse extends BaseResponse implements ControlledEntit @SerializedName(ApiConstants.DOMAIN) @Param(description = "the domain associated with the static route") private String domainName; + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with static route", + responseObject = ResourceTagResponse.class) + private List tags; public void setId(Long id) { this.id.setValue(id); @@ -99,4 +105,8 @@ public class StaticRouteResponse extends BaseResponse implements ControlledEntit public void setProjectName(String projectName) { this.projectName = projectName; } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/api/response/VpcResponse.java b/api/src/com/cloud/api/response/VpcResponse.java index c2f119749bc..8d27ca4a7c9 100644 --- a/api/src/com/cloud/api/response/VpcResponse.java +++ b/api/src/com/cloud/api/response/VpcResponse.java @@ -79,6 +79,9 @@ public class VpcResponse extends BaseResponse implements ControlledEntityRespons @SerializedName(ApiConstants.NETWORK_DOMAIN) @Param(description="the network domain") private String networkDomain; + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with the project", responseObject = ResourceTagResponse.class) + private List tags; public void setId(Long id) { this.id.setValue(id); @@ -160,4 +163,8 @@ public class VpcResponse extends BaseResponse implements ControlledEntityRespons public void setZoneName(String zoneName) { this.zoneName = zoneName; } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/api/src/com/cloud/network/vpc/VpcService.java b/api/src/com/cloud/network/vpc/VpcService.java index fec908083fc..bf35d1fcf69 100644 --- a/api/src/com/cloud/network/vpc/VpcService.java +++ b/api/src/com/cloud/network/vpc/VpcService.java @@ -107,13 +107,14 @@ public interface VpcService { * @param isRecursive TODO * @param listAll TODO * @param restartRequired TODO + * @param tags TODO * @param vpc * @return */ public List listVpcs(Long id, String vpcName, String displayText, List supportedServicesStr, String cidr, Long vpcOffId, String state, String accountName, Long domainId, String keyword, Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, - Boolean restartRequired); + Boolean restartRequired, Map tags); /** * @param vpcId diff --git a/api/src/com/cloud/projects/ProjectService.java b/api/src/com/cloud/projects/ProjectService.java index 9e3b6c333fa..ef421e54170 100644 --- a/api/src/com/cloud/projects/ProjectService.java +++ b/api/src/com/cloud/projects/ProjectService.java @@ -13,6 +13,7 @@ package com.cloud.projects; import java.util.List; +import java.util.Map; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ResourceAllocationException; @@ -55,7 +56,8 @@ public interface ProjectService { */ Project getProject(long id); - List listProjects(Long id, String name, String displayText, String state, String accountName, Long domainId, String keyword, Long startIndex, Long pageSize, boolean listAll, boolean isRecursive); + List listProjects(Long id, String name, String displayText, String state, String accountName, + Long domainId, String keyword, Long startIndex, Long pageSize, boolean listAll, boolean isRecursive, Map tags); ProjectAccount assignAccountToProject(Project project, long accountId, Role accountRole); diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index c3307b6b17b..02cab333f36 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -30,7 +30,11 @@ public interface ResourceTag extends ControlledEntity{ PortForwardingRule, FirewallRule, SecurityGroup, - PublicIpAddress + PublicIpAddress, + Project, + Vpc, + NetworkACL, + StaticRoute } /** diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 26245e22076..ce3daa9ccd4 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -3044,6 +3044,15 @@ public class ApiResponseHelper implements ResponseGenerator { response.setDomain(domain.getName()); response.setOwner(ApiDBUtils.getProjectOwner(project.getId()).getAccountName()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Project, project.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); response.setObjectName("project"); return response; @@ -3122,6 +3131,16 @@ public class ApiResponseHelper implements ResponseGenerator { response.setIcmpType(networkACL.getIcmpType()); response.setState(stateToSet); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.NetworkACL, networkACL.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); + response.setObjectName("networkacl"); return response; } @@ -3702,6 +3721,16 @@ public class ApiResponseHelper implements ResponseGenerator { response.setNetworks(networkResponses); response.setServices(serviceResponses); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Vpc, vpc.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); + response.setObjectName("vpc"); return response; } @@ -3743,6 +3772,15 @@ public class ApiResponseHelper implements ResponseGenerator { response.setState(stateToSet); populateAccount(response, result.getAccountId()); populateDomain(response, result.getDomainId()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.StaticRoute, result.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); response.setObjectName("staticroute"); return response; diff --git a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java index 6fc0350ec80..a1e3b081c73 100644 --- a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java +++ b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java @@ -298,6 +298,8 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i _tagsDao.removeBy(id, TaggedResourceType.PortForwardingRule); } else if (entry.getPurpose() == Purpose.Firewall) { _tagsDao.removeBy(id, TaggedResourceType.FirewallRule); + } else if (entry.getPurpose() == Purpose.NetworkACL) { + _tagsDao.removeBy(id, TaggedResourceType.NetworkACL); } } boolean result = super.remove(id); diff --git a/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java index d4b195b00e8..9cdca8eeb33 100644 --- a/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java +++ b/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java @@ -18,6 +18,9 @@ import javax.ejb.Local; import com.cloud.network.vpc.StaticRoute; import com.cloud.network.vpc.StaticRouteVO; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.dao.ResourceTagsDaoImpl; +import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; @@ -25,6 +28,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; /** * @author Alena Prokharchyk @@ -36,6 +40,7 @@ public class StaticRouteDaoImpl extends GenericDaoBase impl protected final SearchBuilder AllFieldsSearch; protected final SearchBuilder NotRevokedSearch; protected final GenericSearchBuilder RoutesByGatewayCount; + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); protected StaticRouteDaoImpl() { super(); @@ -92,4 +97,18 @@ public class StaticRouteDaoImpl extends GenericDaoBase impl sc.setParameters("gatewayId", gatewayId); return customSearch(sc, null).get(0); } + + @Override + @DB + public boolean remove(Long id) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + StaticRouteVO entry = findById(id); + if (entry != null) { + _tagsDao.removeBy(id, TaggedResourceType.StaticRoute); + } + boolean result = super.remove(id); + txn.commit(); + return result; + } } diff --git a/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java index e0ea5d920f3..11f5a2e7d0f 100644 --- a/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java +++ b/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java @@ -18,6 +18,9 @@ import javax.ejb.Local; import com.cloud.network.vpc.Vpc; import com.cloud.network.vpc.VpcVO; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.dao.ResourceTagsDaoImpl; +import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; @@ -25,6 +28,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; /** * @author Alena Prokharchyk @@ -35,6 +39,7 @@ import com.cloud.utils.db.SearchCriteria.Op; public class VpcDaoImpl extends GenericDaoBase implements VpcDao{ final GenericSearchBuilder CountByOfferingId; final SearchBuilder AllFieldsSearch; + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); protected VpcDaoImpl() { super(); @@ -82,5 +87,19 @@ public class VpcDaoImpl extends GenericDaoBase implements VpcDao{ sc.setParameters("state", Vpc.State.Inactive); return listBy(sc, null); } + + @Override + @DB + public boolean remove(Long id) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + VpcVO entry = findById(id); + if (entry != null) { + _tagsDao.removeBy(id, TaggedResourceType.Vpc); + } + boolean result = super.remove(id); + txn.commit(); + return result; + } } diff --git a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java index faef7115ed9..1906daadb96 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java @@ -43,6 +43,9 @@ import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRule.TrafficType; import com.cloud.network.rules.FirewallRuleVO; import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.UserContext; @@ -51,6 +54,7 @@ import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.db.DB; 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; @@ -67,7 +71,6 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLManager{ String _name; private static final Logger s_logger = Logger.getLogger(NetworkACLManagerImpl.class); - @Inject AccountManager _accountMgr; @Inject @@ -78,7 +81,8 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLManager{ NetworkManager _networkMgr; @Inject VpcManager _vpcMgr; - + @Inject + ResourceTagDao _resourceTagDao; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -317,6 +321,7 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLManager{ Long networkId = cmd.getNetworkId(); Long id = cmd.getId(); String trafficType = cmd.getTrafficType(); + Map tags = cmd.getTags(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -337,6 +342,18 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLManager{ sb.and("network", sb.entity().getNetworkId(), Op.EQ); sb.and("purpose", sb.entity().getPurpose(), Op.EQ); sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ); + + if (tags != null && !tags.isEmpty()) { + SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); + for (int count=0; count < tags.size(); count++) { + tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); + tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); + tagSearch.cp(); + } + tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.groupBy(sb.entity().getId()); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + } SearchCriteria sc = sb.create(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -352,6 +369,16 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLManager{ if (trafficType != null) { sc.setParameters("trafficType", trafficType); } + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.NetworkACL.toString()); + for (String key : tags.keySet()) { + sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); + sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); + count++; + } + } sc.setParameters("purpose", Purpose.NetworkACL); diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 1ad63f1ffa6..aa1ddc45b82 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -70,6 +70,9 @@ import com.cloud.offerings.NetworkOfferingServiceMapVO; import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; import com.cloud.org.Grouping; import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.User; @@ -135,6 +138,8 @@ public class VpcManagerImpl implements VpcManager, Manager{ VpcOfferingServiceMapDao _vpcOffServiceDao; @Inject PhysicalNetworkDao _pNtwkDao; + @Inject + ResourceTagDao _resourceTagDao; private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker")); @@ -655,7 +660,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ @Override public List listVpcs(Long id, String vpcName, String displayText, List supportedServicesStr, String cidr, Long vpcOffId, String state, String accountName, Long domainId, String keyword, - Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, Boolean restartRequired) { + Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, Boolean restartRequired, Map tags) { Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -678,7 +683,19 @@ public class VpcManagerImpl implements VpcManager, Manager{ sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); sb.and("restartRequired", sb.entity().isRestartRequired(), SearchCriteria.Op.EQ); - + + if (tags != null && !tags.isEmpty()) { + SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); + for (int count=0; count < tags.size(); count++) { + tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); + tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); + tagSearch.cp(); + } + tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.groupBy(sb.entity().getId()); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + } + // now set the SC criteria... SearchCriteria sc = sb.create(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -697,6 +714,16 @@ public class VpcManagerImpl implements VpcManager, Manager{ if (displayText != null) { sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%"); } + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Vpc.toString()); + for (String key : tags.keySet()) { + sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); + sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); + count++; + } + } if (id != null) { sc.addAnd("id", SearchCriteria.Op.EQ, id); @@ -1422,6 +1449,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ String accountName = cmd.getAccountName(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); + Map tags = cmd.getTags(); Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); @@ -1439,6 +1467,18 @@ public class VpcManagerImpl implements VpcManager, Manager{ sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); sb.and("vpcGatewayId", sb.entity().getVpcGatewayId(), SearchCriteria.Op.EQ); + if (tags != null && !tags.isEmpty()) { + SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); + for (int count=0; count < tags.size(); count++) { + tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); + tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); + tagSearch.cp(); + } + tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.groupBy(sb.entity().getId()); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + } + SearchCriteria sc = sb.create(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -1454,6 +1494,16 @@ public class VpcManagerImpl implements VpcManager, Manager{ sc.addAnd("vpcGatewayId", Op.EQ, vpcId); } + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.StaticRoute.toString()); + for (String key : tags.keySet()) { + sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); + sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); + count++; + } + } + return _staticRouteDao.search(sc, searchFilter); } diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index 9b06e49a58f..52d710af76b 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -56,6 +56,9 @@ import com.cloud.projects.ProjectAccount.Role; import com.cloud.projects.dao.ProjectAccountDao; import com.cloud.projects.dao.ProjectDao; import com.cloud.projects.dao.ProjectInvitationDao; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; @@ -107,6 +110,8 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ private ConfigurationDao _configDao; @Inject private ProjectInvitationDao _projectInvitationDao; + @Inject + protected ResourceTagDao _resourceTagDao; protected boolean _invitationRequired = false; protected long _invitationTimeOut = 86400000; @@ -343,7 +348,9 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ } @Override - public List listProjects(Long id, String name, String displayText, String state, String accountName, Long domainId, String keyword, Long startIndex, Long pageSize, boolean listAll, boolean isRecursive) { + public List listProjects(Long id, String name, String displayText, String state, + String accountName, Long domainId, String keyword, Long startIndex, Long pageSize, boolean listAll, + boolean isRecursive, Map tags) { Account caller = UserContext.current().getCaller(); Long accountId = null; String path = null; @@ -380,14 +387,12 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ accountId = caller.getId(); } - if (domainId == null && accountId == null && (caller.getType() == Account.ACCOUNT_TYPE_NORMAL || !listAll)) { accountId = caller.getId(); } else if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || (isRecursive && !listAll)) { DomainVO domain = _domainDao.findById(caller.getDomainId()); path = domain.getPath(); } - if (path != null) { SearchBuilder domainSearch = _domainDao.createSearchBuilder(); @@ -401,6 +406,18 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ sb.join("projectAccountSearch", projectAccountSearch, sb.entity().getId(), projectAccountSearch.entity().getProjectId(), JoinBuilder.JoinType.INNER); } + if (tags != null && !tags.isEmpty()) { + SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); + for (int count=0; count < tags.size(); count++) { + tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); + tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); + tagSearch.cp(); + } + tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.groupBy(sb.entity().getId()); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + } + SearchCriteria sc = sb.create(); if (id != null) { @@ -438,6 +455,16 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ sc.setJoinParameters("domainSearch", "path", path); } + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Project.toString()); + for (String key : tags.keySet()) { + sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); + sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); + count++; + } + } + return _projectDao.search(sc, searchFilter); } diff --git a/server/src/com/cloud/projects/dao/ProjectDaoImpl.java b/server/src/com/cloud/projects/dao/ProjectDaoImpl.java index cf9d6618b9e..744a54fc933 100644 --- a/server/src/com/cloud/projects/dao/ProjectDaoImpl.java +++ b/server/src/com/cloud/projects/dao/ProjectDaoImpl.java @@ -20,6 +20,9 @@ import org.apache.log4j.Logger; import com.cloud.projects.Project; import com.cloud.projects.ProjectVO; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.dao.ResourceTagsDaoImpl; +import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; @@ -34,6 +37,7 @@ public class ProjectDaoImpl extends GenericDaoBase implements P protected final SearchBuilder AllFieldsSearch; protected GenericSearchBuilder CountByDomain; protected GenericSearchBuilder ProjectAccountSearch; + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); protected ProjectDaoImpl() { AllFieldsSearch = createSearchBuilder(); @@ -69,9 +73,9 @@ public class ProjectDaoImpl extends GenericDaoBase implements P if (!update(projectId, projectToRemove)) { s_logger.warn("Failed to reset name for the project id=" + projectId + " as a part of project remove"); return false; - } else { - - } + } + + _tagsDao.removeBy(projectId, TaggedResourceType.Project); result = super.remove(projectId); txn.commit(); @@ -100,5 +104,4 @@ public class ProjectDaoImpl extends GenericDaoBase implements P sc.setParameters("state", state); return listBy(sc); } - } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 33c1df78cf7..21de0a75cbb 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -327,6 +327,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag @Inject(adapter = StoragePoolDiscoverer.class) protected Adapters _discoverers; + protected SearchBuilder HostTemplateStatesSearch; protected GenericSearchBuilder UpHostsInPoolSearch; protected SearchBuilder StoragePoolSearch; diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index c8aaa3b0deb..ca4dededb10 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -35,7 +35,10 @@ import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.RemoteAccessVpnDao; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.security.dao.SecurityGroupDao; +import com.cloud.network.vpc.Dao.StaticRouteDao; +import com.cloud.network.vpc.Dao.VpcDao; import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.projects.dao.ProjectDao; import com.cloud.server.ResourceTag; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.server.TaggedResourceService; @@ -58,6 +61,7 @@ import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.uuididentity.dao.IdentityDao; import com.cloud.vm.dao.UserVmDao; @@ -102,6 +106,12 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager RemoteAccessVpnDao _vpnDao; @Inject IPAddressDao _publicIpDao; + @Inject + ProjectDao _projectDao; + @Inject + VpcDao _vpcDao; + @Inject + StaticRouteDao _staticRouteDao; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -117,6 +127,10 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager _daoMap.put(TaggedResourceType.FirewallRule, _firewallDao); _daoMap.put(TaggedResourceType.SecurityGroup, _securityGroupDao); _daoMap.put(TaggedResourceType.PublicIpAddress, _publicIpDao); + _daoMap.put(TaggedResourceType.Project, _projectDao); + _daoMap.put(TaggedResourceType.Vpc, _vpcDao); + _daoMap.put(TaggedResourceType.NetworkACL, _firewallDao); + _daoMap.put(TaggedResourceType.StaticRoute, _staticRouteDao); return true; } @@ -139,6 +153,9 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager private Long getResourceId(String resourceId, TaggedResourceType resourceType) { GenericDao dao = _daoMap.get(resourceType); + if (dao == null) { + throw new CloudRuntimeException("Dao is not loaded for the resource type " + resourceType); + } Class claz = DbUtil.getEntityBeanType(dao); Long identityId = null; @@ -182,7 +199,7 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager if (tableName == null) { throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); } - pair = _identityDao.getAccountDomainInfo(tableName, resourceId); + pair = _identityDao.getAccountDomainInfo(tableName, resourceId, resourceType); if (pair.first() != null || pair.second() != null) { break; } diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDao.java b/server/src/com/cloud/uuididentity/dao/IdentityDao.java index f963fcbc476..8a5b14db7b4 100644 --- a/server/src/com/cloud/uuididentity/dao/IdentityDao.java +++ b/server/src/com/cloud/uuididentity/dao/IdentityDao.java @@ -13,6 +13,7 @@ package com.cloud.uuididentity.dao; import com.cloud.api.IdentityMapper; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.utils.Pair; import com.cloud.utils.db.GenericDao; @@ -24,7 +25,8 @@ public interface IdentityDao extends GenericDao { /** * @param tableName * @param identityId + * @param resourceType TODO * @return */ - Pair getAccountDomainInfo(String tableName, Long identityId); + Pair getAccountDomainInfo(String tableName, Long identityId, TaggedResourceType resourceType); } diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java b/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java index a86dbcb0447..fefe70b25bd 100644 --- a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java +++ b/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java @@ -25,6 +25,7 @@ import org.apache.log4j.Logger; import com.cloud.api.IdentityMapper; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.utils.Pair; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; @@ -97,7 +98,7 @@ public class IdentityDaoImpl extends GenericDaoBase implements @DB @Override - public Pair getAccountDomainInfo(String tableName, Long identityId) { + public Pair getAccountDomainInfo(String tableName, Long identityId, TaggedResourceType resourceType) { assert(tableName != null); PreparedStatement pstmt = null; @@ -118,7 +119,11 @@ public class IdentityDaoImpl extends GenericDaoBase implements //get accountId try { - pstmt = txn.prepareAutoCloseStatement(String.format("SELECT account_id FROM `%s` WHERE id=?", tableName)); + String account = "account_id"; + if (resourceType == TaggedResourceType.Project) { + account = "project_account_id"; + } + pstmt = txn.prepareAutoCloseStatement(String.format("SELECT " + account + " FROM `%s` WHERE id=?", tableName)); pstmt.setLong(1, identityId); ResultSet rs = pstmt.executeQuery(); if (rs.next()) {