Skip to content

Commit 5033921

Browse files
author
Likitha Shetty
committed
CLOUDSTACK-2599. Fix EC2 Rest to support tag related EC2 API's - CreateTags/DeleteTags/DescribeTags
1 parent eb7c321 commit 5033921

2 files changed

Lines changed: 168 additions & 58 deletions

File tree

awsapi/src/com/cloud/bridge/service/EC2RestServlet.java

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@
3535
import java.util.Calendar;
3636
import java.util.Date;
3737
import java.util.Enumeration;
38+
import java.util.HashMap;
3839
import java.util.List;
40+
import java.util.Map;
3941
import java.util.Properties;
42+
import java.util.Set;
4043
import java.util.UUID;
4144

4245
import javax.inject.Inject;
@@ -68,10 +71,12 @@
6871
import com.amazon.ec2.CreateKeyPairResponse;
6972
import com.amazon.ec2.CreateSecurityGroupResponse;
7073
import com.amazon.ec2.CreateSnapshotResponse;
74+
import com.amazon.ec2.CreateTagsResponse;
7175
import com.amazon.ec2.CreateVolumeResponse;
7276
import com.amazon.ec2.DeleteKeyPairResponse;
7377
import com.amazon.ec2.DeleteSecurityGroupResponse;
7478
import com.amazon.ec2.DeleteSnapshotResponse;
79+
import com.amazon.ec2.DeleteTagsResponse;
7580
import com.amazon.ec2.DeleteVolumeResponse;
7681
import com.amazon.ec2.DeregisterImageResponse;
7782
import com.amazon.ec2.DescribeAvailabilityZonesResponse;
@@ -82,6 +87,7 @@
8287
import com.amazon.ec2.DescribeKeyPairsResponse;
8388
import com.amazon.ec2.DescribeSecurityGroupsResponse;
8489
import com.amazon.ec2.DescribeSnapshotsResponse;
90+
import com.amazon.ec2.DescribeTagsResponse;
8591
import com.amazon.ec2.DescribeVolumesResponse;
8692
import com.amazon.ec2.DetachVolumeResponse;
8793
import com.amazon.ec2.DisassociateAddressResponse;
@@ -122,6 +128,7 @@
122128
import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairs;
123129
import com.cloud.bridge.service.core.ec2.EC2DescribeSecurityGroups;
124130
import com.cloud.bridge.service.core.ec2.EC2DescribeSnapshots;
131+
import com.cloud.bridge.service.core.ec2.EC2DescribeTags;
125132
import com.cloud.bridge.service.core.ec2.EC2DescribeVolumes;
126133
import com.cloud.bridge.service.core.ec2.EC2DisassociateAddress;
127134
import com.cloud.bridge.service.core.ec2.EC2Engine;
@@ -143,6 +150,10 @@
143150
import com.cloud.bridge.service.core.ec2.EC2SnapshotFilterSet;
144151
import com.cloud.bridge.service.core.ec2.EC2StartInstances;
145152
import com.cloud.bridge.service.core.ec2.EC2StopInstances;
153+
import com.cloud.bridge.service.core.ec2.EC2TagKeyValue;
154+
import com.cloud.bridge.service.core.ec2.EC2TagTypeId;
155+
import com.cloud.bridge.service.core.ec2.EC2Tags;
156+
import com.cloud.bridge.service.core.ec2.EC2TagsFilterSet;
146157
import com.cloud.bridge.service.core.ec2.EC2Volume;
147158
import com.cloud.bridge.service.core.ec2.EC2VolumeFilterSet;
148159
import com.cloud.bridge.service.exception.EC2ServiceException;
@@ -294,6 +305,9 @@ protected void doGetOrPost(HttpServletRequest request, HttpServletResponse respo
294305
else if (action.equalsIgnoreCase( "ImportKeyPair" )) importKeyPair(request, response);
295306
else if (action.equalsIgnoreCase( "DeleteKeyPair" )) deleteKeyPair(request, response);
296307
else if (action.equalsIgnoreCase( "DescribeKeyPairs" )) describeKeyPairs(request, response);
308+
else if (action.equalsIgnoreCase( "CreateTags" )) createTags(request, response);
309+
else if (action.equalsIgnoreCase( "DeleteTags" )) deleteTags(request, response);
310+
else if (action.equalsIgnoreCase( "DescribeTags" )) describeTags(request, response);
297311
else if (action.equalsIgnoreCase( "GetPasswordData" )) getPasswordData(request, response);
298312
else {
299313
logger.error("Unsupported action " + action);
@@ -1824,6 +1838,83 @@ private void getPasswordData(HttpServletRequest request, HttpServletResponse res
18241838
serializeResponse(response, EC2Response);
18251839
}
18261840

1841+
private void createTags(HttpServletRequest request, HttpServletResponse response)
1842+
throws ADBException, XMLStreamException, IOException {
1843+
EC2Tags ec2Request = createTagsRequest(request, response);
1844+
if (ec2Request == null) return;
1845+
CreateTagsResponse EC2Response = EC2SoapServiceImpl.toCreateTagsResponse(
1846+
ServiceProvider.getInstance().getEC2Engine().modifyTags( ec2Request, "create"));
1847+
serializeResponse(response, EC2Response);
1848+
}
1849+
1850+
private void deleteTags(HttpServletRequest request, HttpServletResponse response)
1851+
throws ADBException, XMLStreamException, IOException {
1852+
EC2Tags ec2Request = createTagsRequest(request, response);
1853+
if (ec2Request == null) return;
1854+
DeleteTagsResponse EC2Response = EC2SoapServiceImpl.toDeleteTagsResponse(
1855+
ServiceProvider.getInstance().getEC2Engine().modifyTags( ec2Request, "delete"));
1856+
serializeResponse(response, EC2Response);
1857+
}
1858+
1859+
private EC2Tags createTagsRequest(HttpServletRequest request, HttpServletResponse response)
1860+
throws IOException {
1861+
EC2Tags ec2Request = new EC2Tags();
1862+
ArrayList<String> resourceIdList = new ArrayList<String>();
1863+
Map<String, String> resourceTagList = new HashMap<String, String>();
1864+
1865+
int nCount = 1;
1866+
do {
1867+
String[] resourceIds = request.getParameterValues( "ResourceId." + nCount );
1868+
if (resourceIds != null && resourceIds.length > 0)
1869+
resourceIdList.add(resourceIds[0]);
1870+
else break;
1871+
nCount++;
1872+
} while (true);
1873+
if ( resourceIdList.isEmpty() ) {
1874+
response.sendError(530, "At least one Resource is required" );
1875+
return null;
1876+
}
1877+
ec2Request = EC2SoapServiceImpl.toResourceTypeAndIds(ec2Request, resourceIdList);
1878+
1879+
nCount = 1;
1880+
do {
1881+
String[] tagKey = request.getParameterValues( "Tag." + nCount + ".Key" );
1882+
if ( tagKey != null && tagKey.length > 0 ) {
1883+
String[] tagValue = request.getParameterValues( "Tag." + nCount + ".Value" );
1884+
if ( tagValue != null && tagValue.length > 0 ) {
1885+
resourceTagList.put(tagKey[0], tagValue[0]);
1886+
} else
1887+
resourceTagList.put(tagKey[0], null);
1888+
} else break;
1889+
nCount++;
1890+
} while (true);
1891+
if ( resourceTagList.isEmpty() ) {
1892+
response.sendError(530, "At least one Tag is required" );
1893+
return null;
1894+
}
1895+
ec2Request = EC2SoapServiceImpl.toResourceTag(ec2Request, resourceTagList);
1896+
1897+
return ec2Request;
1898+
}
1899+
1900+
private void describeTags(HttpServletRequest request, HttpServletResponse response)
1901+
throws ADBException, XMLStreamException, IOException {
1902+
EC2DescribeTags ec2Request = new EC2DescribeTags();
1903+
1904+
EC2Filter[] filterSet = extractFilters( request );
1905+
if (null != filterSet) {
1906+
EC2TagsFilterSet tfs = new EC2TagsFilterSet();
1907+
for( int i=0; i < filterSet.length; i++ )
1908+
tfs.addFilter( filterSet[i] );
1909+
ec2Request.setFilterSet( tfs );
1910+
}
1911+
DescribeTagsResponse EC2Response = EC2SoapServiceImpl.toDescribeTagsResponse(
1912+
ServiceProvider.getInstance().getEC2Engine().describeTags( ec2Request));
1913+
serializeResponse(response, EC2Response);
1914+
}
1915+
1916+
1917+
18271918
/**
18281919
* This function implements the EC2 REST authentication algorithm. It uses the given
18291920
* "AWSAccessKeyId" parameter to look up the Cloud.com account holder's secret key which is

awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java

Lines changed: 77 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818

1919
import java.util.ArrayList;
2020
import java.util.Calendar;
21+
import java.util.HashMap;
2122
import java.util.List;
23+
import java.util.Map;
24+
import java.util.Set;
2225
import java.util.UUID;
2326

2427
import org.apache.commons.codec.binary.Base64;
@@ -210,88 +213,104 @@ public CreateVolumeResponse createVolume(CreateVolume createVolume) {
210213

211214
public CreateTagsResponse createTags(CreateTags createTags) {
212215
EC2Tags request = new EC2Tags();
216+
ArrayList<String> resourceIdList = new ArrayList<String>();
217+
Map<String, String> resourceTagList = new HashMap<String, String>();
218+
213219
CreateTagsType ctt = createTags.getCreateTags();
214220

215221
ResourceIdSetType resourceIds = ctt.getResourcesSet();
216222
ResourceTagSetType resourceTags = ctt.getTagSet();
217-
request = toResourceTypeAndIds(resourceIds);
223+
224+
ResourceIdSetItemType[] resourceIdItems = resourceIds.getItem();
225+
if (resourceIdItems != null) {
226+
for( int i=0; i < resourceIdItems.length; i++ )
227+
resourceIdList.add(resourceIdItems[i].getResourceId());
228+
}
229+
request = toResourceTypeAndIds(request, resourceIdList);
230+
218231
//add resource tag's to the request
219-
if (resourceTags != null) {
220-
ResourceTagSetItemType[] items = resourceTags.getItem();
221-
if (items != null) {
222-
for( int i=0; i < items.length; i++ ) {
223-
EC2TagKeyValue param1 = new EC2TagKeyValue();
224-
param1.setKey(items[i].getKey());
225-
param1.setValue(items[i].getValue());
226-
request.addResourceTag(param1);
227-
}
228-
}
232+
ResourceTagSetItemType[] resourceTagItems = resourceTags.getItem();
233+
if (resourceTagItems != null) {
234+
for( int i=0; i < resourceTagItems.length; i++ )
235+
resourceTagList.put(resourceTagItems[i].getKey(), resourceTagItems[i].getValue());
229236
}
237+
request = toResourceTag(request, resourceTagList);
238+
230239
return toCreateTagsResponse( engine.modifyTags( request, "create"));
231240
}
232241

233242
public DeleteTagsResponse deleteTags(DeleteTags deleteTags) {
234243
EC2Tags request = new EC2Tags();
244+
ArrayList<String> resourceIdList = new ArrayList<String>();
245+
Map<String, String> resourceTagList = new HashMap<String, String>();
246+
235247
DeleteTagsType dtt = deleteTags.getDeleteTags();
236248

237249
ResourceIdSetType resourceIds = dtt.getResourcesSet();
238250
DeleteTagsSetType resourceTags = dtt.getTagSet();
239-
request = toResourceTypeAndIds(resourceIds);
251+
252+
ResourceIdSetItemType[] resourceIdItems = resourceIds.getItem();
253+
254+
if (resourceIdItems != null) {
255+
for( int i=0; i < resourceIdItems.length; i++ )
256+
resourceIdList.add(resourceIdItems[i].getResourceId());
257+
}
258+
request = toResourceTypeAndIds(request, resourceIdList);
259+
240260
//add resource tag's to the request
241-
if (resourceTags != null) {
242-
DeleteTagsSetItemType[] items = resourceTags.getItem();
243-
if (items != null) {
244-
for( int i=0; i < items.length; i++ ) {
245-
EC2TagKeyValue param1 = new EC2TagKeyValue();
246-
param1.setKey(items[i].getKey());
247-
if (items[i].getValue() != null)
248-
param1.setValue(items[i].getValue());
249-
request.addResourceTag(param1);
250-
}
251-
}
261+
DeleteTagsSetItemType[] resourceTagItems = resourceTags.getItem();
262+
if (resourceTagItems != null) {
263+
for( int i=0; i < resourceTagItems.length; i++ )
264+
resourceTagList.put(resourceTagItems[i].getKey(), resourceTagItems[i].getValue());
252265
}
266+
request = toResourceTag(request, resourceTagList);
267+
253268
return toDeleteTagsResponse( engine.modifyTags( request, "delete"));
254269
}
255270

256-
private EC2Tags toResourceTypeAndIds(ResourceIdSetType resourceIds) {
257-
EC2Tags request = new EC2Tags();
258-
//add resource-type and resource-id's to the request
259-
if (resourceIds != null) {
260-
ResourceIdSetItemType[] items = resourceIds.getItem();
261-
List<String> resourceTypeList = new ArrayList<String>();
262-
if (items != null) {
263-
for( int i=0; i < items.length; i++ ) {
264-
if (!items[i].getResourceId().contains(":") || items[i].getResourceId().split(":").length != 2) {
265-
throw new EC2ServiceException( ClientError.InvalidResourceId_Format,
266-
"Invalid Format. ResourceId format is resource-type:resource-uuid");
267-
}
268-
String resourceType = items[i].getResourceId().split(":")[0];
269-
if (resourceTypeList.isEmpty())
270-
resourceTypeList.add(resourceType);
271-
else {
272-
Boolean existsInList = false;
273-
for (String addedResourceType : resourceTypeList) {
274-
if (addedResourceType.equalsIgnoreCase(resourceType)) {
275-
existsInList = true;
276-
break;
277-
}
278-
}
279-
if (!existsInList)
280-
resourceTypeList.add(resourceType);
281-
}
282-
}
283-
for (String resourceType : resourceTypeList){
284-
EC2TagTypeId param1 = new EC2TagTypeId();
285-
param1.setResourceType(resourceType);
286-
for( int i=0; i < items.length; i++ ) {
287-
String[] resourceTag = items[i].getResourceId().split(":");
288-
if (resourceType.equals(resourceTag[0]))
289-
param1.addResourceId(resourceTag[1]);
271+
public static EC2Tags toResourceTypeAndIds( EC2Tags request, ArrayList<String> resourceIdList ) {
272+
List<String> resourceTypeList = new ArrayList<String>();
273+
for (String resourceId : resourceIdList) {
274+
if (!resourceId.contains(":") || resourceId.split(":").length != 2) {
275+
throw new EC2ServiceException( ClientError.InvalidResourceId_Format,
276+
"Invalid Format. ResourceId format is resource-type:resource-uuid");
277+
}
278+
String resourceType = resourceId.split(":")[0];
279+
if (resourceTypeList.isEmpty())
280+
resourceTypeList.add(resourceType);
281+
else {
282+
Boolean existsInList = false;
283+
for (String addedResourceType : resourceTypeList) {
284+
if (addedResourceType.equalsIgnoreCase(resourceType)) {
285+
existsInList = true;
286+
break;
290287
}
291-
request.addResourceType(param1);
292288
}
289+
if (!existsInList)
290+
resourceTypeList.add(resourceType);
293291
}
294292
}
293+
for (String resourceType : resourceTypeList) {
294+
EC2TagTypeId param1 = new EC2TagTypeId();
295+
param1.setResourceType(resourceType);
296+
for (String resourceId : resourceIdList) {
297+
String[] resourceTag = resourceId.split(":");
298+
if (resourceType.equals(resourceTag[0]))
299+
param1.addResourceId(resourceTag[1]);
300+
}
301+
request.addResourceType(param1);
302+
}
303+
return request;
304+
}
305+
306+
public static EC2Tags toResourceTag( EC2Tags request, Map<String, String> resourceTagList ) {
307+
Set<String> resourceTagKeySet = resourceTagList.keySet();
308+
for (String resourceTagKey : resourceTagKeySet) {
309+
EC2TagKeyValue param1 = new EC2TagKeyValue();
310+
param1.setKey(resourceTagKey);
311+
param1.setValue(resourceTagList.get(resourceTagKey));
312+
request.addResourceTag(param1);
313+
}
295314
return request;
296315
}
297316

0 commit comments

Comments
 (0)