You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by al...@apache.org on 2012/06/21 00:48:03 UTC
[2/4] git commit: Initial checkin for resource tags feature
Initial checkin for resource tags feature
Conflicts:
api/src/com/cloud/api/ApiConstants.java
client/tomcatconf/commands.properties.in
server/src/com/cloud/api/ApiDBUtils.java
server/src/com/cloud/uuididentity/dao/IdentityDao.java
server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java
setup/db/create-schema.sql
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/62d45b96
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/62d45b96
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/62d45b96
Branch: refs/heads/master
Commit: 62d45b9670520a1ee8b520509393d4258c689b50
Parents: 01f172c
Author: Alena Prokharchyk <al...@citrix.com>
Authored: Wed Jun 6 17:21:38 2012 -0700
Committer: Alena Prokharchyk <al...@citrix.com>
Committed: Wed Jun 20 15:45:08 2012 -0700
----------------------------------------------------------------------
api/src/com/cloud/api/ApiConstants.java | 2 +
api/src/com/cloud/api/BaseCmd.java | 3 +
api/src/com/cloud/api/ResponseGenerator.java | 10 +
api/src/com/cloud/api/commands/CreateTagsCmd.java | 123 ++++++
api/src/com/cloud/api/commands/ListTagsCmd.java | 87 ++++
.../cloud/api/response/ResourceTagResponse.java | 94 +++++
api/src/com/cloud/configuration/Resource.java | 16 +
api/src/com/cloud/event/EventTypes.java | 5 +
api/src/com/cloud/server/ResourceTag.java | 48 +++
.../com/cloud/server/TaggedResourceService.java | 49 +++
client/tomcatconf/commands.properties.in | 7 +-
server/src/com/cloud/api/ApiDBUtils.java | 10 +
server/src/com/cloud/api/ApiResponseHelper.java | 44 ++-
.../configuration/DefaultComponentLibrary.java | 14 +-
server/src/com/cloud/tags/ResourceTagVO.java | 139 +++++++
.../com/cloud/tags/TaggedResourceManagerImpl.java | 251 ++++++++++++
server/src/com/cloud/tags/dao/ResourceTagDao.java | 23 +
.../com/cloud/tags/dao/ResourceTagsDaoImpl.java | 29 ++
.../com/cloud/uuididentity/dao/IdentityDao.java | 26 +-
.../cloud/uuididentity/dao/IdentityDaoImpl.java | 318 ++++++++-------
setup/db/create-schema.sql | 18 +
wscript | 1 +
22 files changed, 1155 insertions(+), 162 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/api/src/com/cloud/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java
index 7872cba..54bfaff 100755
--- a/api/src/com/cloud/api/ApiConstants.java
+++ b/api/src/com/cloud/api/ApiConstants.java
@@ -358,6 +358,8 @@ public class ApiConstants {
public static final String VSM_DEVICE_STATE = "vsmdevicestate";
public static final String ADD_VSM_FLAG = "addvsmflag";
public static final String CAN_USE_FOR_DEPLOY = "canusefordeploy";
+ public static final String RESOURCE_IDS = "resourceids";
+ public static final String RESOURCE_ID = "resourceid";
public enum HostDetails {
all, capacity, events, stats, min;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/api/src/com/cloud/api/BaseCmd.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/BaseCmd.java b/api/src/com/cloud/api/BaseCmd.java
index a9b6f60..0924796 100755
--- a/api/src/com/cloud/api/BaseCmd.java
+++ b/api/src/com/cloud/api/BaseCmd.java
@@ -49,6 +49,7 @@ import com.cloud.projects.Project;
import com.cloud.projects.ProjectService;
import com.cloud.resource.ResourceService;
import com.cloud.server.ManagementService;
+import com.cloud.server.TaggedResourceService;
import com.cloud.storage.StorageService;
import com.cloud.storage.snapshot.SnapshotService;
import com.cloud.template.TemplateService;
@@ -128,6 +129,7 @@ public abstract class BaseCmd {
public static ResourceLimitService _resourceLimitService;
public static IdentityService _identityService;
public static StorageNetworkService _storageNetworkService;
+ public static TaggedResourceService _taggedResourceService;
static void setComponents(ResponseGenerator generator) {
ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name);
@@ -155,6 +157,7 @@ public abstract class BaseCmd {
_resourceLimitService = locator.getManager(ResourceLimitService.class);
_identityService = locator.getManager(IdentityService.class);
_storageNetworkService = locator.getManager(StorageNetworkService.class);
+ _taggedResourceService = locator.getManager(TaggedResourceService.class);
}
public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/api/src/com/cloud/api/ResponseGenerator.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/ResponseGenerator.java b/api/src/com/cloud/api/ResponseGenerator.java
index 5f55705..864a9e6 100755
--- a/api/src/com/cloud/api/ResponseGenerator.java
+++ b/api/src/com/cloud/api/ResponseGenerator.java
@@ -56,6 +56,7 @@ import com.cloud.api.response.ProviderResponse;
import com.cloud.api.response.RemoteAccessVpnResponse;
import com.cloud.api.response.ResourceCountResponse;
import com.cloud.api.response.ResourceLimitResponse;
+import com.cloud.api.response.ResourceTagResponse;
import com.cloud.api.response.SecurityGroupResponse;
import com.cloud.api.response.ServiceOfferingResponse;
import com.cloud.api.response.ServiceResponse;
@@ -114,6 +115,7 @@ import com.cloud.org.Cluster;
import com.cloud.projects.Project;
import com.cloud.projects.ProjectAccount;
import com.cloud.projects.ProjectInvitation;
+import com.cloud.server.ResourceTag;
import com.cloud.storage.Snapshot;
import com.cloud.storage.StoragePool;
import com.cloud.storage.Swift;
@@ -280,4 +282,12 @@ public interface ResponseGenerator {
* @return
*/
Long getIdentiyId(String tableName, String token);
+
+ /**
+ * @param resourceTag
+ * @return
+ */
+ ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag);
+
+
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/api/src/com/cloud/api/commands/CreateTagsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/commands/CreateTagsCmd.java b/api/src/com/cloud/api/commands/CreateTagsCmd.java
new file mode 100644
index 0000000..c0ac974
--- /dev/null
+++ b/api/src/com/cloud/api/commands/CreateTagsCmd.java
@@ -0,0 +1,123 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.api.commands;
+
+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;
+
+import com.cloud.api.ApiConstants;
+import com.cloud.api.BaseAsyncCmd;
+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.SuccessResponse;
+import com.cloud.configuration.Resource;
+import com.cloud.event.EventTypes;
+import com.cloud.server.ResourceTag;
+
+/**
+ * @author Alena Prokharchyk
+ */
+
+@Implementation(description = "Creates resource tag(s)", responseObject = SuccessResponse.class, since = "Burbank")
+public class CreateTagsCmd extends BaseAsyncCmd{
+ public static final Logger s_logger = Logger.getLogger(CreateTagsCmd.class.getName());
+
+ private static final String s_name = "createtagsresponse";
+
+ // ///////////////////////////////////////////////////
+ // ////////////// API parameters /////////////////////
+ // ///////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.TAGS, type = CommandType.MAP, required=true, description = "Map of tags (key/value pairs)")
+ private Map tag;
+
+ @Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.STRING, required=true, description="type of the resource")
+ private String resourceType;
+
+ @Parameter(name=ApiConstants.RESOURCE_IDS, type=CommandType.LIST, required=true,
+ collectionType=CommandType.STRING, description="list of resources to create the tags for")
+ private List<String> resourceIds;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+
+ public Resource.TaggedResourceType getResourceType(){
+ return _taggedResourceService.getResourceType(resourceType);
+ }
+
+ public Map<String, String> getTags() {
+ Map<String, String> tagsMap = null;
+ if (!tag.isEmpty()) {
+ tagsMap = new HashMap<String, String>();
+ Collection<?> servicesCollection = tag.values();
+ Iterator<?> iter = servicesCollection.iterator();
+ while (iter.hasNext()) {
+ HashMap<String, String> services = (HashMap<String, String>) iter.next();
+ String key = services.get("key");
+ String value = services.get("value");
+ tagsMap.put(key, value);
+ }
+ }
+ return tagsMap;
+ }
+
+ public List<String> getResourceIds() {
+ return resourceIds;
+ }
+
+ // ///////////////////////////////////////////////////
+ // ///////////// API Implementation///////////////////
+ // ///////////////////////////////////////////////////
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ //FIXME - validate the owner here
+ return 1;
+ }
+
+ @Override
+ public void execute() {
+ List<ResourceTag> tags = _taggedResourceService.createTags(getResourceIds(), getResourceType(), getTags());
+
+ if (tags != null && !tags.isEmpty()) {
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create tags");
+ }
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_TAGS_CREATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "creating tags";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/api/src/com/cloud/api/commands/ListTagsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/commands/ListTagsCmd.java b/api/src/com/cloud/api/commands/ListTagsCmd.java
new file mode 100644
index 0000000..80e2a2a
--- /dev/null
+++ b/api/src/com/cloud/api/commands/ListTagsCmd.java
@@ -0,0 +1,87 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.api.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.cloud.api.ApiConstants;
+import com.cloud.api.BaseListProjectAndAccountResourcesCmd;
+import com.cloud.api.Implementation;
+import com.cloud.api.Parameter;
+import com.cloud.api.response.ListResponse;
+import com.cloud.api.response.ResourceTagResponse;
+import com.cloud.server.ResourceTag;
+
+/**
+ * @author Alena Prokharchyk
+ */
+
+@Implementation(description = "List resource tag(s)", responseObject = ResourceTagResponse.class, since = "Burbank")
+public class ListTagsCmd extends BaseListProjectAndAccountResourcesCmd{
+ private static final String s_name = "listtagsresponse";
+
+ @Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.STRING, description="list by resource type")
+ private String resourceType;
+
+ @Parameter(name=ApiConstants.RESOURCE_ID, type=CommandType.STRING, description="list by resource id")
+ private String resourceId;
+
+ @Parameter(name=ApiConstants.KEY, type=CommandType.STRING, description="list by key")
+ private String key;
+
+ @Parameter(name=ApiConstants.VALUE, type=CommandType.STRING, description="list by value")
+ private String value;
+
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public void execute() {
+
+ List<? extends ResourceTag> tags = _taggedResourceService.listTags(this);
+ ListResponse<ResourceTagResponse> response = new ListResponse<ResourceTagResponse>();
+ List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
+ for (ResourceTag tag : tags) {
+ ResourceTagResponse tagResponse = _responseGenerator.createResourceTagResponse(tag);
+ tagResponses.add(tagResponse);
+ }
+ response.setResponses(tagResponses);
+
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ }
+
+ public String getResourceType() {
+ return resourceType;
+ }
+
+ public String getResourceId() {
+ return resourceId;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/api/src/com/cloud/api/response/ResourceTagResponse.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/response/ResourceTagResponse.java b/api/src/com/cloud/api/response/ResourceTagResponse.java
new file mode 100644
index 0000000..fc8d43c
--- /dev/null
+++ b/api/src/com/cloud/api/response/ResourceTagResponse.java
@@ -0,0 +1,94 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.api.response;
+
+import com.cloud.api.ApiConstants;
+import com.cloud.serializer.Param;
+import com.cloud.utils.IdentityProxy;
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * @author Alena Prokharchyk
+ */
+
+@SuppressWarnings("unused")
+public class ResourceTagResponse extends BaseResponse implements ControlledEntityResponse{
+ @SerializedName(ApiConstants.KEY) @Param(description="tag key name")
+ private String key;
+
+ @SerializedName(ApiConstants.VALUE) @Param(description="tag value")
+ private String value;
+
+ @SerializedName(ApiConstants.RESOURCE_TYPE) @Param(description="resource type")
+ private String resourceType;
+
+ @SerializedName(ApiConstants.RESOURCE_ID) @Param(description="id of the resource")
+ private String id;
+
+ @SerializedName(ApiConstants.ACCOUNT)
+ @Param(description = "the account associated with the tag")
+ private String accountName;
+
+ @SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id the tag belongs to")
+ private IdentityProxy projectId = new IdentityProxy("projects");
+
+ @SerializedName(ApiConstants.PROJECT) @Param(description="the project name where tag belongs to")
+ private String projectName;
+
+ @SerializedName(ApiConstants.DOMAIN_ID)
+ @Param(description = "the ID of the domain associated with the tag")
+ private IdentityProxy domainId = new IdentityProxy("domain");
+
+ @SerializedName(ApiConstants.DOMAIN)
+ @Param(description = "the domain associated with the tag")
+ private String domainName;
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public void setResourceType(String resourceType) {
+ this.resourceType = resourceType;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public void setAccountName(String accountName) {
+ this.accountName = accountName;
+ }
+
+ public void setDomainId(Long domainId) {
+ this.domainId.setValue(domainId);
+ }
+
+ public void setDomainName(String domainName) {
+ this.domainName = domainName;
+ }
+
+ @Override
+ public void setProjectId(Long projectId) {
+ this.projectId.setValue(projectId);
+ }
+
+ @Override
+ public void setProjectName(String projectName) {
+ this.projectName = projectName;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/api/src/com/cloud/configuration/Resource.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/configuration/Resource.java b/api/src/com/cloud/configuration/Resource.java
index 24bb669..bb2121b 100644
--- a/api/src/com/cloud/configuration/Resource.java
+++ b/api/src/com/cloud/configuration/Resource.java
@@ -19,6 +19,22 @@ package com.cloud.configuration;
public interface Resource {
public static final short RESOURCE_UNLIMITED = -1;
+
+ public enum TaggedResourceType {
+ UserVm,
+ Template,
+ ISO,
+ Volume,
+ Snapshot,
+ Network,
+ LoadBalancingRule,
+ PortForwardingRule,
+ FirewallRule,
+ SecurityGroup,
+ RemoteAccessVpn,
+ PublicIpAdddress,
+ SecondaryStorageVm
+ }
public enum ResourceType {
user_vm("user_vm", 0, ResourceOwnerType.Account, ResourceOwnerType.Domain),
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/api/src/com/cloud/event/EventTypes.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index 424ddc9..c42db5d 100755
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -259,4 +259,9 @@ public class EventTypes {
public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_ADD = "PHYSICAL.FIREWALL.ADD";
public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_DELETE = "PHYSICAL.FIREWALL.DELETE";
public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_CONFIGURE = "PHYSICAL.FIREWALL.CONFIGURE";
+
+ // tag related events
+ public static final String EVENT_TAGS_CREATE = "CREATE_TAGS";
+ public static final String EVENT_TAGS_DELETE = "DELETE_TAGS";
+
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/api/src/com/cloud/server/ResourceTag.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java
new file mode 100644
index 0000000..050c8c8
--- /dev/null
+++ b/api/src/com/cloud/server/ResourceTag.java
@@ -0,0 +1,48 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.server;
+
+import com.cloud.acl.ControlledEntity;
+import com.cloud.configuration.Resource;
+
+/**
+ * @author Alena Prokharchyk
+ */
+public interface ResourceTag extends ControlledEntity{
+
+ /**
+ * @return
+ */
+ long getId();
+
+ /**
+ * @return
+ */
+ String getKey();
+
+ /**
+ * @return
+ */
+ String getValue();
+
+ /**
+ * @return
+ */
+ long getResourceId();
+
+ /**
+ * @return
+ */
+ Resource.TaggedResourceType getResourceType();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/api/src/com/cloud/server/TaggedResourceService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/server/TaggedResourceService.java b/api/src/com/cloud/server/TaggedResourceService.java
new file mode 100644
index 0000000..9a4bd32
--- /dev/null
+++ b/api/src/com/cloud/server/TaggedResourceService.java
@@ -0,0 +1,49 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.server;
+
+import java.util.List;
+import java.util.Map;
+
+import com.cloud.api.commands.ListTagsCmd;
+import com.cloud.configuration.Resource;
+import com.cloud.configuration.Resource.TaggedResourceType;
+
+/**
+ * @author Alena Prokharchyk
+ */
+public interface TaggedResourceService {
+
+ Resource.TaggedResourceType getResourceType (String resourceTypeStr);
+
+ /**
+ * @param resourceIds TODO
+ * @param resourceType
+ * @param tags
+ * @return
+ */
+ List<ResourceTag> createTags(List<String> resourceIds, TaggedResourceType resourceType, Map<String, String> tags);
+
+ /**
+ * @param resourceId
+ * @param resourceType
+ * @return
+ */
+ String getUuid(String resourceId, TaggedResourceType resourceType);
+
+ /**
+ * @param listTagsCmd
+ * @return
+ */
+ List<? extends ResourceTag> listTags(ListTagsCmd listTagsCmd);
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index a939eb7..08c175b 100755
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -331,4 +331,9 @@ updateStorageNetworkIpRange=com.cloud.api.commands.UpdateStorageNetworkIpRangeCm
### Network Devices commands
addNetworkDevice=com.cloud.api.commands.AddNetworkDeviceCmd;1
listNetworkDevice=com.cloud.api.commands.ListNetworkDeviceCmd;1
-deleteNetworkDevice=com.cloud.api.commands.DeleteNetworkDeviceCmd;1
+deleteNetworkDevice=com.cloud.api.commands.DeleteNetworkDeviceCmd;1
+
+#### Tags commands
+createTags=com.cloud.api.commands.CreateTagsCmd;15
+deleteTags=com.cloud.api.commands.DeleteTagsCmd;15
+listTags=com.cloud.api.commands.ListTagsCmd;15
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/server/src/com/cloud/api/ApiDBUtils.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java
index 4d2eea4..d75ab73 100755
--- a/server/src/com/cloud/api/ApiDBUtils.java
+++ b/server/src/com/cloud/api/ApiDBUtils.java
@@ -25,6 +25,7 @@ import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationService;
import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.configuration.Resource.TaggedResourceType;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.AccountVlanMapVO;
import com.cloud.dc.ClusterVO;
@@ -78,6 +79,7 @@ import com.cloud.resource.ResourceManager;
import com.cloud.server.Criteria;
import com.cloud.server.ManagementServer;
import com.cloud.server.StatsCollector;
+import com.cloud.server.TaggedResourceService;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.DiskOfferingVO;
@@ -189,6 +191,7 @@ public class ApiDBUtils {
private static AccountDetailsDao _accountDetailsDao;
private static NetworkDomainDao _networkDomainDao;
private static HighAvailabilityManager _haMgr;
+ private static TaggedResourceService _taggedResourceService;
static {
_ms = (ManagementServer) ComponentLocator.getComponent(ManagementServer.Name);
@@ -242,6 +245,7 @@ public class ApiDBUtils {
_accountDetailsDao = locator.getDao(AccountDetailsDao.class);
_networkDomainDao = locator.getDao(NetworkDomainDao.class);
_haMgr = locator.getManager(HighAvailabilityManager.class);
+ _taggedResourceService = locator.getManager(TaggedResourceService.class);
// Note: stats collector should already have been initialized by this time, otherwise a null instance is returned
_statsCollector = StatsCollector.getInstance();
@@ -749,7 +753,13 @@ public class ApiDBUtils {
public static String getHaTag() {
return _haMgr.getHaTag();
}
+
public static boolean canUseForDeploy(Network network) {
return _networkMgr.canUseForDeploy(network);
}
+
+ public static String getUuid(String resourceId, TaggedResourceType resourceType) {
+ return _taggedResourceService.getUuid(resourceId, resourceType);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 1112dba..d3c91b8 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -70,6 +70,7 @@ import com.cloud.api.response.ProviderResponse;
import com.cloud.api.response.RemoteAccessVpnResponse;
import com.cloud.api.response.ResourceCountResponse;
import com.cloud.api.response.ResourceLimitResponse;
+import com.cloud.api.response.ResourceTagResponse;
import com.cloud.api.response.SecurityGroupResponse;
import com.cloud.api.response.SecurityGroupResultObject;
import com.cloud.api.response.SecurityGroupRuleResponse;
@@ -151,6 +152,7 @@ import com.cloud.projects.Project;
import com.cloud.projects.ProjectAccount;
import com.cloud.projects.ProjectInvitation;
import com.cloud.server.Criteria;
+import com.cloud.server.ResourceTag;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.GuestOS;
import com.cloud.storage.GuestOSCategoryVO;
@@ -2305,10 +2307,11 @@ public class ApiResponseHelper implements ResponseGenerator {
boolean savedValue = SerializationContext.current().getUuidTranslation();
SerializationContext.current().setUuidTranslation(false);
- jobResponse.setJobResult((ResponseObject) ApiSerializerHelper.fromSerializedString(job.getResult()));
- SerializationContext.current().setUuidTranslation(savedValue);
-
+
Object resultObject = ApiSerializerHelper.fromSerializedString(job.getResult());
+ jobResponse.setJobResult((ResponseObject) resultObject);
+ SerializationContext.current().setUuidTranslation(savedValue);
+
if (resultObject != null) {
Class<?> clz = resultObject.getClass();
if (clz.isPrimitive() || clz.getSuperclass() == Number.class || clz == String.class || clz == Date.class) {
@@ -3399,5 +3402,38 @@ public class ApiResponseHelper implements ResponseGenerator {
public Long getIdentiyId(String tableName, String token) {
return ApiDispatcher.getIdentiyId(tableName, token);
}
-
+
+ @Override
+ public ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag) {
+ ResourceTagResponse response = new ResourceTagResponse();
+ response.setKey(resourceTag.getKey());
+ response.setValue(resourceTag.getValue());
+ response.setResourceType(resourceTag.getResourceType().toString());
+ response.setId(ApiDBUtils.getUuid(String.valueOf(resourceTag.getResourceId()),resourceTag.getResourceType()));
+ Long accountId = resourceTag.getAccountId();
+ Long domainId = resourceTag.getDomainId();
+ if (accountId != null) {
+ Account account = ApiDBUtils.findAccountByIdIncludingRemoved(resourceTag.getAccountId());
+
+ if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+ // find the project
+ Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
+ response.setProjectId(project.getId());
+ response.setProjectName(project.getName());
+ } else {
+ response.setAccountName(account.getAccountName());
+ }
+ }
+
+ if (domainId != null) {
+ response.setDomainId(domainId);
+ response.setDomainName(ApiDBUtils.findDomainById(domainId).getName());
+ }
+
+ response.setObjectName("tag");
+
+ return response;
+ }
+
+
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/server/src/com/cloud/configuration/DefaultComponentLibrary.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java
index 150d7af..df833f4 100755
--- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java
+++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java
@@ -45,6 +45,7 @@ import com.cloud.dao.EntityManagerImpl;
import com.cloud.dc.ClusterDetailsDaoImpl;
import com.cloud.dc.dao.AccountVlanMapDaoImpl;
import com.cloud.dc.dao.ClusterDaoImpl;
+import com.cloud.dc.dao.ClusterVSMMapDaoImpl;
import com.cloud.dc.dao.DataCenterDaoImpl;
import com.cloud.dc.dao.DataCenterIpAddressDaoImpl;
import com.cloud.dc.dao.DcDetailsDaoImpl;
@@ -70,11 +71,9 @@ import com.cloud.maint.dao.AgentUpgradeDaoImpl;
import com.cloud.network.ExternalLoadBalancerUsageManagerImpl;
import com.cloud.network.NetworkManagerImpl;
import com.cloud.network.StorageNetworkManagerImpl;
+import com.cloud.network.dao.CiscoNexusVSMDeviceDaoImpl;
import com.cloud.network.dao.ExternalFirewallDeviceDaoImpl;
import com.cloud.network.dao.ExternalLoadBalancerDeviceDaoImpl;
-import com.cloud.network.dao.CiscoNexusVSMDeviceDaoImpl;
-import com.cloud.dc.dao.ClusterVSMMapDaoImpl;
-import com.cloud.network.dao.PortProfileDaoImpl;
import com.cloud.network.dao.FirewallRulesCidrsDaoImpl;
import com.cloud.network.dao.FirewallRulesDaoImpl;
import com.cloud.network.dao.IPAddressDaoImpl;
@@ -92,16 +91,17 @@ import com.cloud.network.dao.NetworkServiceMapDaoImpl;
import com.cloud.network.dao.PhysicalNetworkDaoImpl;
import com.cloud.network.dao.PhysicalNetworkServiceProviderDaoImpl;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeDaoImpl;
+import com.cloud.network.dao.PortProfileDaoImpl;
import com.cloud.network.dao.RemoteAccessVpnDaoImpl;
import com.cloud.network.dao.VirtualRouterProviderDaoImpl;
import com.cloud.network.dao.VpnUserDaoImpl;
+import com.cloud.network.element.CiscoNexusVSMElement;
+import com.cloud.network.element.CiscoNexusVSMElementService;
import com.cloud.network.element.F5ExternalLoadBalancerElement;
import com.cloud.network.element.F5ExternalLoadBalancerElementService;
import com.cloud.network.element.JuniperSRXExternalFirewallElement;
import com.cloud.network.element.JuniperSRXFirewallElementService;
import com.cloud.network.element.NetscalerElement;
-import com.cloud.network.element.CiscoNexusVSMElement;
-import com.cloud.network.element.CiscoNexusVSMElementService;
import com.cloud.network.element.NetscalerLoadBalancerElementService;
import com.cloud.network.element.VirtualRouterElement;
import com.cloud.network.element.VirtualRouterElementService;
@@ -160,6 +160,8 @@ import com.cloud.storage.snapshot.SnapshotManagerImpl;
import com.cloud.storage.snapshot.SnapshotSchedulerImpl;
import com.cloud.storage.swift.SwiftManagerImpl;
import com.cloud.storage.upload.UploadMonitorImpl;
+import com.cloud.tags.TaggedResourceManagerImpl;
+import com.cloud.tags.dao.ResourceTagsDaoImpl;
import com.cloud.template.HyervisorTemplateAdapter;
import com.cloud.template.TemplateAdapter;
import com.cloud.template.TemplateAdapter.TemplateAdapterType;
@@ -329,6 +331,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
addDao("NetworkServiceMapDao", NetworkServiceMapDaoImpl.class);
addDao("StorageNetworkIpAddressDao", StorageNetworkIpAddressDaoImpl.class);
addDao("StorageNetworkIpRangeDao", StorageNetworkIpRangeDaoImpl.class);
+ addDao("TagsDao", ResourceTagsDaoImpl.class);
}
@Override
@@ -385,6 +388,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
addManager("StorageNetworkManager", StorageNetworkManagerImpl.class);
addManager("ExternalLoadBalancerUsageManager", ExternalLoadBalancerUsageManagerImpl.class);
addManager("HA Manager", HighAvailabilityManagerImpl.class);
+ addManager("TaggedResourcesManager", TaggedResourceManagerImpl.class);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/server/src/com/cloud/tags/ResourceTagVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/tags/ResourceTagVO.java b/server/src/com/cloud/tags/ResourceTagVO.java
new file mode 100644
index 0000000..74786ba
--- /dev/null
+++ b/server/src/com/cloud/tags/ResourceTagVO.java
@@ -0,0 +1,139 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.tags;
+
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.cloud.api.Identity;
+import com.cloud.configuration.Resource;
+import com.cloud.configuration.Resource.TaggedResourceType;
+import com.cloud.server.ResourceTag;
+
+/**
+ * @author Alena Prokharchyk
+ */
+
+@Entity
+@Table(name="resource_tags")
+public class ResourceTagVO implements Identity, ResourceTag{
+
+ @Id
+ @GeneratedValue(strategy=GenerationType.IDENTITY)
+ @Column(name="id")
+ private long id;
+
+ @Column(name="uuid")
+ private String uuid;
+
+ @Column(name="key")
+ private String key;
+
+ @Column(name="value")
+ String value;
+
+ @Column(name="domain_id")
+ long domainId;
+
+ @Column(name="account_id")
+ long accountId;
+
+ @Column(name="resource_id")
+ long resourceId;
+
+ @Column(name="resource_type")
+ @Enumerated(value=EnumType.STRING)
+ private Resource.TaggedResourceType resourceType;
+
+
+ protected ResourceTagVO(){
+ this.uuid = UUID.randomUUID().toString();
+ }
+
+ /**
+ * @param key
+ * @param value
+ * @param accountId
+ * @param domainId
+ * @param resourceId
+ * @param resourceType
+ */
+ public ResourceTagVO(String key, String value, long accountId, long domainId, long resourceId, TaggedResourceType resourceType) {
+ super();
+ this.key = key;
+ this.value = value;
+ this.domainId = domainId;
+ this.accountId = accountId;
+ this.resourceId = resourceId;
+ this.resourceType = resourceType;
+ this.uuid = UUID.randomUUID().toString();
+ }
+
+
+ @Override
+ public String toString() {
+ StringBuilder buf = new StringBuilder("Tag[");
+ buf.append(id).append("|key=").append(key).append("|value=").append(domainId).append("|value=").
+ append("|resourceType=").append(resourceType).append("|resourceId=").append(resourceId)
+ .append("|accountId=").append(accountId).append("]");
+ return buf.toString();
+ }
+
+ @Override
+ public long getId() {
+ return id;
+ }
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+
+ @Override
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public long getDomainId() {
+ return domainId;
+ }
+
+ @Override
+ public long getAccountId() {
+ return accountId;
+ }
+
+ @Override
+ public long getResourceId() {
+ return resourceId;
+ }
+
+ @Override
+ public Resource.TaggedResourceType getResourceType() {
+ return resourceType;
+ }
+
+ @Override
+ public String getUuid() {
+ return uuid;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/server/src/com/cloud/tags/TaggedResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java
new file mode 100644
index 0000000..7e442a9
--- /dev/null
+++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java
@@ -0,0 +1,251 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.tags;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.api.commands.ListTagsCmd;
+import com.cloud.configuration.Resource;
+import com.cloud.configuration.Resource.TaggedResourceType;
+import com.cloud.domain.Domain;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.server.ResourceTag;
+import com.cloud.server.TaggedResourceService;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.DomainManager;
+import com.cloud.user.UserContext;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.component.Manager;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.DbUtil;
+import com.cloud.utils.db.Filter;
+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.uuididentity.dao.IdentityDao;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.dao.UserVmDao;
+
+/**
+ * @author Alena Prokharchyk
+ */
+@Local(value = { TaggedResourceService.class})
+public class TaggedResourceManagerImpl implements TaggedResourceService, Manager{
+ public static final Logger s_logger = Logger.getLogger(TaggedResourceManagerImpl.class);
+ private String _name;
+
+ private static Map<Resource.TaggedResourceType, String> _resourceMap=
+ new HashMap<Resource.TaggedResourceType, String>();
+
+ private static Map<Resource.TaggedResourceType, GenericDao<?, Long>> _daoMap=
+ new HashMap<Resource.TaggedResourceType, GenericDao<?, Long>>();
+
+ @Inject
+ AccountManager _accountMgr;
+ @Inject
+ ResourceTagDao _resourceTagDao;
+ @Inject
+ IdentityDao _identityDao;
+ @Inject
+ DomainManager _domainMgr;
+ @Inject
+ UserVmDao _userVmDao;
+
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ _name = name;
+ _resourceMap.put(TaggedResourceType.UserVm, DbUtil.getTableName(VMInstanceVO.class));
+ _daoMap.put(TaggedResourceType.UserVm, _userVmDao);
+
+
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return _name;
+ }
+
+
+ private Long getResourceId(String resourceId, Resource.TaggedResourceType resourceType) {
+ String tableName = _resourceMap.get(resourceType);
+
+ if (tableName == null) {
+ throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database");
+ }
+
+ return _identityDao.getIdentityId(tableName, resourceId);
+ }
+
+ private Pair<Long, Long> getAccountDomain(long resourceId, Resource.TaggedResourceType resourceType) {
+ String tableName = _resourceMap.get(resourceType);
+
+ if (tableName == null) {
+ throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database");
+ }
+
+ Pair<Long, Long> pair = _identityDao.getAccountDomainInfo(tableName, resourceId);
+ Long accountId = pair.first();
+ Long domainId = pair.second();
+
+ if (accountId == null) {
+ accountId = Account.ACCOUNT_ID_SYSTEM;
+ }
+
+ if (domainId == null) {
+ domainId = Domain.ROOT_DOMAIN;
+ }
+
+ return new Pair<Long, Long>(accountId, domainId);
+ }
+
+ @Override
+ public TaggedResourceType getResourceType(String resourceTypeStr) {
+ Resource.TaggedResourceType resourceType = null;
+ try {
+ resourceType = Resource.TaggedResourceType.valueOf(resourceTypeStr);
+ } catch (IllegalArgumentException ex) {
+ throw new InvalidParameterValueException("Invalid resource type " + resourceType);
+ }
+
+ return resourceType;
+ }
+
+ @Override
+ @DB
+ public List<ResourceTag> createTags(List<String> resourceIds, TaggedResourceType resourceType, Map<String, String> tags) {
+ Account caller = UserContext.current().getCaller();
+
+ List<ResourceTag> resourceTags = new ArrayList<ResourceTag>(tags.size());
+
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+
+ for (String tag : tags.keySet()) {
+ for (String resourceId : resourceIds) {
+ Long id = getResourceId(resourceId, resourceType);
+
+ //check if object exists
+ if (_daoMap.get(resourceType).findById(id) == null) {
+ throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType);
+ }
+
+ Pair<Long, Long> accountDomainPair = getAccountDomain(id, resourceType);
+ Long domainId = accountDomainPair.second();
+ Long accountId = accountDomainPair.first();
+ if (accountId != null) {
+ _accountMgr.checkAccess(caller, null, false, _accountMgr.getAccount(accountId));
+ } else if (domainId != null && caller.getType() != Account.ACCOUNT_TYPE_NORMAL) {
+ //check permissions;
+ _accountMgr.checkAccess(caller, _domainMgr.getDomain(domainId));
+ } else {
+ throw new PermissionDeniedException("Account " + caller + " doesn't have permissions to create tags" +
+ " for resource " + tag);
+ }
+
+ ResourceTagVO resourceTag = new ResourceTagVO(tag, tags.get(tag), accountDomainPair.first(),
+ accountDomainPair.second(),
+ id, resourceType);
+ resourceTag = _resourceTagDao.persist(resourceTag);
+ resourceTags.add(resourceTag);
+
+ }
+ }
+
+ txn.commit();
+
+ return resourceTags;
+ }
+
+ @Override
+ public String getUuid(String resourceId, TaggedResourceType resourceType) {
+ return _identityDao.getIdentityUuid(_resourceMap.get(resourceType), resourceId);
+ }
+
+ @Override
+ public List<? extends ResourceTag> listTags(ListTagsCmd cmd) {
+ Account caller = UserContext.current().getCaller();
+ List<Long> permittedAccounts = new ArrayList<Long>();
+ String key = cmd.getKey();
+ String value = cmd.getValue();
+ String resourceId = cmd.getResourceId();
+ String resourceType = cmd.getResourceType();
+ boolean listAll = cmd.listAll();
+
+ Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject =
+ new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+ _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(),
+ cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
+ Long domainId = domainIdRecursiveListProject.first();
+ Boolean isRecursive = domainIdRecursiveListProject.second();
+ ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+ Filter searchFilter = new Filter(ResourceTagVO.class, "resourceType", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+ SearchBuilder<ResourceTagVO> sb = _resourceTagDao.createSearchBuilder();
+ _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+ sb.and("key", sb.entity().getKey(), SearchCriteria.Op.EQ);
+ sb.and("value", sb.entity().getValue(), SearchCriteria.Op.EQ);
+ sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ);
+ sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ);
+
+ // now set the SC criteria...
+ SearchCriteria<ResourceTagVO> sc = sb.create();
+ _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+ if (key != null) {
+ sc.setParameters("key", key);
+ }
+
+ if (value != null) {
+ sc.setParameters("value", value);
+ }
+
+ if (resourceId != null) {
+ sc.setParameters("resourceId", resourceId);
+ }
+
+ if (resourceType != null) {
+ sc.setParameters("resourceType", resourceType);
+ }
+
+ return _resourceTagDao.search(sc, searchFilter);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/server/src/com/cloud/tags/dao/ResourceTagDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/tags/dao/ResourceTagDao.java b/server/src/com/cloud/tags/dao/ResourceTagDao.java
new file mode 100644
index 0000000..a2d3851
--- /dev/null
+++ b/server/src/com/cloud/tags/dao/ResourceTagDao.java
@@ -0,0 +1,23 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.tags.dao;
+
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.utils.db.GenericDao;
+
+/**
+ * @author Alena Prokharchyk
+ */
+public interface ResourceTagDao extends GenericDao<ResourceTagVO, Long>{
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java b/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java
new file mode 100644
index 0000000..0285dad
--- /dev/null
+++ b/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java
@@ -0,0 +1,29 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.tags.dao;
+
+import javax.ejb.Local;
+
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.utils.db.GenericDaoBase;
+
+/**
+ * @author Alena Prokharchyk
+ */
+
+@Local(value = { ResourceTagDao.class })
+public class ResourceTagsDaoImpl extends GenericDaoBase<ResourceTagVO, Long> implements ResourceTagDao{
+
+ protected ResourceTagsDaoImpl() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/server/src/com/cloud/uuididentity/dao/IdentityDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDao.java b/server/src/com/cloud/uuididentity/dao/IdentityDao.java
index f5acf71..769aebf 100644
--- a/server/src/com/cloud/uuididentity/dao/IdentityDao.java
+++ b/server/src/com/cloud/uuididentity/dao/IdentityDao.java
@@ -10,14 +10,22 @@
// limitations under the License.
//
// Automatically generated by addcopyright.py at 04/03/2012
-package com.cloud.uuididentity.dao;
-import com.cloud.api.IdentityMapper;
-import com.cloud.utils.db.GenericDao;
-
-public interface IdentityDao extends GenericDao<IdentityVO, Long> {
- Long getIdentityId(IdentityMapper mapper, String identityString);
- Long getIdentityId(String tableName, String identityString);
- String getIdentityUuid(String tableName, String identityString);
+package com.cloud.uuididentity.dao;
+
+import com.cloud.api.IdentityMapper;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.GenericDao;
+
+public interface IdentityDao extends GenericDao<IdentityVO, Long> {
+ Long getIdentityId(IdentityMapper mapper, String identityString);
+ Long getIdentityId(String tableName, String identityString);
+ String getIdentityUuid(String tableName, String identityString);
void initializeDefaultUuid(String tableName);
-}
+ /**
+ * @param tableName
+ * @param identityId
+ * @return
+ */
+ Pair<Long, Long> getAccountDomainInfo(String tableName, Long identityId);
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java b/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java
index abe2011..219ed90 100644
--- a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java
+++ b/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java
@@ -10,8 +10,8 @@
// limitations under the License.
//
// Automatically generated by addcopyright.py at 04/03/2012
-package com.cloud.uuididentity.dao;
-
+package com.cloud.uuididentity.dao;
+
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -25,147 +25,89 @@ import org.apache.log4j.Logger;
import com.cloud.api.IdentityMapper;
import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.utils.Pair;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.Transaction;
-
-@Local(value={IdentityDao.class})
-public class IdentityDaoImpl extends GenericDaoBase<IdentityVO, Long> implements IdentityDao {
- private static final Logger s_logger = Logger.getLogger(IdentityDaoImpl.class);
-
- public IdentityDaoImpl() {
- }
-
- @DB
- public Long getIdentityId(IdentityMapper mapper, String identityString) {
- assert(mapper.entityTableName() != null);
- return getIdentityId(mapper.entityTableName(), identityString);
- }
-
- @DB
- public Long getIdentityId(String tableName, String identityString) {
- assert(tableName != null);
- assert(identityString != null);
-
- PreparedStatement pstmt = null;
- Transaction txn = Transaction.open(Transaction.CLOUD_DB);
- try {
- try {
- pstmt = txn.prepareAutoCloseStatement(
- String.format("SELECT id FROM `%s` WHERE id=? OR uuid=?", tableName)
-
- // TODO : after graceful period, use following line turn on more secure check
- // String.format("SELECT id FROM %s WHERE (id=? AND uuid IS NULL) OR uuid=?", mapper.entityTableName())
- );
-
- long id = 0;
- try {
- // TODO : use regular expression to determine
- id = Long.parseLong(identityString);
- } catch(NumberFormatException e) {
- // this could happen when it is a uuid string, so catch and ignore it
- }
-
- pstmt.setLong(1, id);
- pstmt.setString(2, identityString);
-
- ResultSet rs = pstmt.executeQuery();
- if(rs.next()) {
- return rs.getLong(1);
- } else {
- if(id == -1L)
- return id;
-
- throw new InvalidParameterValueException("Object " + tableName + "(uuid: " + identityString + ") does not exist.");
- }
- } catch (SQLException e) {
- s_logger.error("Unexpected exception ", e);
- }
- } finally {
- txn.close();
- }
- return null;
+
+@Local(value={IdentityDao.class})
+public class IdentityDaoImpl extends GenericDaoBase<IdentityVO, Long> implements IdentityDao {
+ private static final Logger s_logger = Logger.getLogger(IdentityDaoImpl.class);
+
+ public IdentityDaoImpl() {
+ }
+
+ @DB
+ public Long getIdentityId(IdentityMapper mapper, String identityString) {
+ assert(mapper.entityTableName() != null);
+ return getIdentityId(mapper.entityTableName(), identityString);
+ }
+
+ @DB
+ public Long getIdentityId(String tableName, String identityString) {
+ assert(tableName != null);
+ assert(identityString != null);
+
+ PreparedStatement pstmt = null;
+ Transaction txn = Transaction.open(Transaction.CLOUD_DB);
+ try {
+ try {
+ pstmt = txn.prepareAutoCloseStatement(
+ String.format("SELECT id FROM `%s` WHERE id=? OR uuid=?", tableName)
+
+ // TODO : after graceful period, use following line turn on more secure check
+ // String.format("SELECT id FROM %s WHERE (id=? AND uuid IS NULL) OR uuid=?", mapper.entityTableName())
+ );
+
+ long id = 0;
+ try {
+ // TODO : use regular expression to determine
+ id = Long.parseLong(identityString);
+ } catch(NumberFormatException e) {
+ // this could happen when it is a uuid string, so catch and ignore it
+ }
+
+ pstmt.setLong(1, id);
+ pstmt.setString(2, identityString);
+
+ ResultSet rs = pstmt.executeQuery();
+ if(rs.next()) {
+ return rs.getLong(1);
+ } else {
+ if(id == -1L)
+ return id;
+
+ throw new InvalidParameterValueException("Object " + tableName + "(uuid: " + identityString + ") does not exist.");
+ }
+ } catch (SQLException e) {
+ s_logger.error("Unexpected exception ", e);
+ }
+ } finally {
+ txn.close();
+ }
+ return null;
}
-
- @DB
- public String getIdentityUuid(String tableName, String identityString) {
- assert(tableName != null);
- assert(identityString != null);
-
- PreparedStatement pstmt = null;
- Transaction txn = Transaction.open(Transaction.CLOUD_DB);
- try {
- try {
- pstmt = txn.prepareAutoCloseStatement(
- String.format("SELECT uuid FROM `%s` WHERE id=? OR uuid=?", tableName)
- // String.format("SELECT uuid FROM %s WHERE (id=? AND uuid IS NULL) OR uuid=?", tableName)
- );
-
- long id = 0;
- try {
- // TODO : use regular expression to determine
- id = Long.parseLong(identityString);
- } catch(NumberFormatException e) {
- // this could happen when it is a uuid string, so catch and ignore it
- }
-
- pstmt.setLong(1, id);
- pstmt.setString(2, identityString);
-
- ResultSet rs = pstmt.executeQuery();
- if(rs.next()) {
- String uuid = rs.getString(1);
- if(uuid != null && !uuid.isEmpty())
- return uuid;
- return identityString;
- }
- } catch (SQLException e) {
- s_logger.error("Unexpected exception ", e);
- }
- } finally {
- txn.close();
- }
-
- return identityString;
- }
@DB
- public void initializeDefaultUuid(String tableName) {
+ @Override
+ public Pair<Long, Long> getAccountDomainInfo(String tableName, Long identityId) {
assert(tableName != null);
- List<Long> l = getNullUuidRecords(tableName);
-
- Transaction txn = Transaction.open(Transaction.CLOUD_DB);
- try {
- try {
- txn.start();
- for(Long id : l) {
- setInitialUuid(tableName, id);
- }
- txn.commit();
- } catch (SQLException e) {
- txn.rollback();
- s_logger.error("Unexpected exception ", e);
- }
- } finally {
- txn.close();
- }
- }
-
- @DB
- List<Long> getNullUuidRecords(String tableName) {
- List<Long> l = new ArrayList<Long>();
PreparedStatement pstmt = null;
Transaction txn = Transaction.open(Transaction.CLOUD_DB);
try {
try {
pstmt = txn.prepareAutoCloseStatement(
- String.format("SELECT id FROM `%s` WHERE uuid IS NULL", tableName)
+ String.format("SELECT account_id, domain_id FROM `%s` WHERE id=?", tableName)
);
+ pstmt.setLong(1, identityId);
+
ResultSet rs = pstmt.executeQuery();
- while(rs.next()) {
- l.add(rs.getLong(1));
+ if(rs.next()) {
+ return new Pair<Long, Long>(rs.getLong(1), rs.getLong(2));
+ } else {
+ throw new InvalidParameterValueException("Object " + tableName + "(id: " + identityId + ") does not exist.");
}
} catch (SQLException e) {
s_logger.error("Unexpected exception ", e);
@@ -173,20 +115,110 @@ public class IdentityDaoImpl extends GenericDaoBase<IdentityVO, Long> implements
} finally {
txn.close();
}
- return l;
- }
-
+ return null;
+ }
+
@DB
- void setInitialUuid(String tableName, long id) throws SQLException {
- Transaction txn = Transaction.currentTxn();
-
- PreparedStatement pstmtUpdate = null;
- pstmtUpdate = txn.prepareAutoCloseStatement(
- String.format("UPDATE `%s` SET uuid=? WHERE id=?", tableName)
- );
-
- pstmtUpdate.setString(1, UUID.randomUUID().toString());
- pstmtUpdate.setLong(2, id);
- pstmtUpdate.executeUpdate();
- }
-}
+ @Override
+ public String getIdentityUuid(String tableName, String identityString) {
+ assert(tableName != null);
+ assert(identityString != null);
+
+ PreparedStatement pstmt = null;
+ Transaction txn = Transaction.open(Transaction.CLOUD_DB);
+ try {
+ try {
+ pstmt = txn.prepareAutoCloseStatement(
+ String.format("SELECT uuid FROM `%s` WHERE id=? OR uuid=?", tableName)
+ // String.format("SELECT uuid FROM %s WHERE (id=? AND uuid IS NULL) OR uuid=?", tableName)
+ );
+
+ long id = 0;
+ try {
+ // TODO : use regular expression to determine
+ id = Long.parseLong(identityString);
+ } catch(NumberFormatException e) {
+ // this could happen when it is a uuid string, so catch and ignore it
+ }
+
+ pstmt.setLong(1, id);
+ pstmt.setString(2, identityString);
+
+ ResultSet rs = pstmt.executeQuery();
+ if(rs.next()) {
+ String uuid = rs.getString(1);
+ if(uuid != null && !uuid.isEmpty())
+ return uuid;
+ return identityString;
+ }
+ } catch (SQLException e) {
+ s_logger.error("Unexpected exception ", e);
+ }
+ } finally {
+ txn.close();
+ }
+
+ return identityString;
+ }
+
+ @DB
+ public void initializeDefaultUuid(String tableName) {
+ assert(tableName != null);
+ List<Long> l = getNullUuidRecords(tableName);
+
+ Transaction txn = Transaction.open(Transaction.CLOUD_DB);
+ try {
+ try {
+ txn.start();
+ for(Long id : l) {
+ setInitialUuid(tableName, id);
+ }
+ txn.commit();
+ } catch (SQLException e) {
+ txn.rollback();
+ s_logger.error("Unexpected exception ", e);
+ }
+ } finally {
+ txn.close();
+ }
+ }
+
+ @DB
+ List<Long> getNullUuidRecords(String tableName) {
+ List<Long> l = new ArrayList<Long>();
+
+ PreparedStatement pstmt = null;
+ Transaction txn = Transaction.open(Transaction.CLOUD_DB);
+ try {
+ try {
+ pstmt = txn.prepareAutoCloseStatement(
+ String.format("SELECT id FROM `%s` WHERE uuid IS NULL", tableName)
+ );
+
+ ResultSet rs = pstmt.executeQuery();
+ while(rs.next()) {
+ l.add(rs.getLong(1));
+ }
+ } catch (SQLException e) {
+ s_logger.error("Unexpected exception ", e);
+ }
+ } finally {
+ txn.close();
+ }
+ return l;
+ }
+
+ @DB
+ void setInitialUuid(String tableName, long id) throws SQLException {
+ Transaction txn = Transaction.currentTxn();
+
+ PreparedStatement pstmtUpdate = null;
+ pstmtUpdate = txn.prepareAutoCloseStatement(
+ String.format("UPDATE `%s` SET uuid=? WHERE id=?", tableName)
+ );
+
+ pstmtUpdate.setString(1, UUID.randomUUID().toString());
+ pstmtUpdate.setLong(2, id);
+ pstmtUpdate.executeUpdate();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/setup/db/create-schema.sql
----------------------------------------------------------------------
diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql
index 488fb06..afcee3f 100755
--- a/setup/db/create-schema.sql
+++ b/setup/db/create-schema.sql
@@ -2132,4 +2132,22 @@ CREATE TABLE `cloud`.`netscaler_pod_ref` (
CONSTRAINT `fk_ns_pod_ref__device_id` FOREIGN KEY (`external_load_balancer_device_id`) REFERENCES `external_load_balancer_devices`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE `cloud`.`resource_tags` (
+ `id` bigint unsigned NOT NULL auto_increment COMMENT 'id',
+ `uuid` varchar(40),
+ `key` varchar(255),
+ `value` varchar(255),
+ `resource_id` bigint unsigned NOT NULL,
+ `resource_type` varchar(255),
+ `customer` varchar(255),
+ `domain_id` bigint unsigned NOT NULL COMMENT 'foreign key to domain id',
+ `account_id` bigint unsigned NOT NULL COMMENT 'owner of this network',
+ PRIMARY KEY (`id`),
+ CONSTRAINT `fk_tags__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`),
+ CONSTRAINT `fk_tags__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`),
+ UNIQUE `i_tags__resource_id__resource_type__key`(`resource_id`, `resource_type`, `key`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
SET foreign_key_checks = 1;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/62d45b96/wscript
----------------------------------------------------------------------
diff --git a/wscript b/wscript
index 1ead7af..7ff0de3 100644
--- a/wscript
+++ b/wscript
@@ -4,6 +4,7 @@
# the following two variables are used by the target "waf dist"
# if you change 'em here, you need to change it also in cloud.spec, add a %changelog entry there, and add an entry in debian/changelog
VERSION = '3.0.3.2012-05-15T19:32:03Z'
+
APPNAME = 'cloud'
import shutil,os