Modifying filter support in 3 EC2 Describe* API's(DescribeInstances, DescribeVolumes and DescribeSnapshots) to include tags. Component: AWSAPI.

Tags support has been added to 3 EC2Describe* API's(DescribeInstances, DescribeVolumes and DescribeSnapshots). Hence for the same 3 EC2Describe* API's filter support has been modified to included 3 tag related filters: tag-key,
tag-value and tag:key.
This commit is contained in:
Likitha Shetty 2012-07-23 15:24:28 -07:00 committed by prachi
parent aef09e1b20
commit 59462cd825
9 changed files with 300 additions and 139 deletions

View File

@ -413,11 +413,10 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
if (null != items) { // -> can be empty
for( int i=0; i < items.length; i++ ) request.addInstanceId( items[i].getInstanceId());
}
if (null != fst) {
request.setFilterSet( toInstanceFilterSet( fst ));
}
if (null != fst)
request = toInstanceFilterSet( request, fst );
return toDescribeInstancesResponse( engine.describeInstances( request ), engine );
}
@ -518,7 +517,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
{
String[] timeFilters = new String[1];
timeFilters[0] = new String( "start-time" );
request.setFilterSet( toSnapshotFilterSet( fst, timeFilters ));
request = toSnapshotFilterSet( request, fst, timeFilters );
}
return toDescribeSnapshotsResponse(engine.handleRequest(request));
@ -557,7 +556,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
String[] timeFilters = new String[2];
timeFilters[0] = new String( "attachment.attach-time" );
timeFilters[1] = new String( "create-time" );
request.setFilterSet( toVolumeFilterSet( fst, timeFilters ));
request = toVolumeFilterSet( request, fst, timeFilters );
}
return toDescribeVolumesResponse( engine.handleRequest( request ));
@ -1045,8 +1044,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
return vfs;
}
private EC2VolumeFilterSet toVolumeFilterSet( FilterSetType fst, String[] timeStrs )
private EC2DescribeVolumes toVolumeFilterSet( EC2DescribeVolumes request, FilterSetType fst, String[] timeStrs )
{
EC2VolumeFilterSet vfs = new EC2VolumeFilterSet();
boolean timeFilter = false;
@ -1057,73 +1055,94 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
// -> each filter can have one or more values associated with it
for( int j=0; j < items.length; j++ )
{
EC2Filter oneFilter = new EC2Filter();
String filterName = items[j].getName();
oneFilter.setName( filterName );
// -> is the filter one of the xsd:dateTime filters?
timeFilter = false;
for( int m=0; m < timeStrs.length; m++ )
{
timeFilter = filterName.equalsIgnoreCase( timeStrs[m] );
if (timeFilter) break;
}
ValueSetType vst = items[j].getValueSet();
ValueType[] valueItems = vst.getItem();
for( int k=0; k < valueItems.length; k++ )
{
// -> time values are not encoded as regexes
if ( timeFilter )
oneFilter.addValue( valueItems[k].getValue());
else oneFilter.addValueEncoded( valueItems[k].getValue());
}
vfs.addFilter( oneFilter );
}
}
return vfs;
}
String filterName = items[j].getName();
ValueSetType vst = items[j].getValueSet();
ValueType[] valueItems = vst.getItem();
private EC2SnapshotFilterSet toSnapshotFilterSet( FilterSetType fst, String[] timeStrs )
{
EC2SnapshotFilterSet vfs = new EC2SnapshotFilterSet();
if (filterName.startsWith("tag:")) {
String key= filterName.split(":")[1];
for (ValueType valueItem : valueItems) {
EC2TagKeyValue tag = new EC2TagKeyValue();
tag.setKey(key);
tag.setValue(valueItem.getValue());
request.addResourceTag(tag);
}
} else {
EC2Filter oneFilter = new EC2Filter();
oneFilter.setName( filterName );
// -> is the filter one of the xsd:dateTime filters?
timeFilter = false;
for( int m=0; m < timeStrs.length; m++ ) {
timeFilter = filterName.equalsIgnoreCase( timeStrs[m] );
if (timeFilter) break;
}
for( int k=0; k < valueItems.length; k++ ) {
// -> time values are not encoded as regexes
if ( timeFilter )
oneFilter.addValue( valueItems[k].getValue());
else
oneFilter.addValueEncoded( valueItems[k].getValue());
}
vfs.addFilter( oneFilter );
}
}
request.setFilterSet(vfs);
}
return request;
}
private EC2DescribeSnapshots toSnapshotFilterSet( EC2DescribeSnapshots request, FilterSetType fst, String[] timeStrs )
{
EC2SnapshotFilterSet sfs = new EC2SnapshotFilterSet();
boolean timeFilter = false;
FilterType[] items = fst.getItem();
if (null != items)
{
// -> each filter can have one or more values associated with it
for( int j=0; j < items.length; j++ )
{
EC2Filter oneFilter = new EC2Filter();
String filterName = items[j].getName();
oneFilter.setName( filterName );
// -> is the filter one of the xsd:dateTime filters?
timeFilter = false;
for( int m=0; m < timeStrs.length; m++ )
{
timeFilter = filterName.equalsIgnoreCase( timeStrs[m] );
if (timeFilter) break;
}
ValueSetType vst = items[j].getValueSet();
ValueType[] valueItems = vst.getItem();
for( int k=0; k < valueItems.length; k++ )
{
// -> time values are not encoded as regexes
if ( timeFilter )
oneFilter.addValue( valueItems[k].getValue());
else oneFilter.addValueEncoded( valueItems[k].getValue());
}
vfs.addFilter( oneFilter );
}
}
return vfs;
}
String filterName = items[j].getName();
ValueSetType vst = items[j].getValueSet();
ValueType[] valueItems = vst.getItem();
if (filterName.startsWith("tag:")) {
String key= filterName.split(":")[1];
for (ValueType valueItem : valueItems) {
EC2TagKeyValue tag = new EC2TagKeyValue();
tag.setKey(key);
tag.setValue(valueItem.getValue());
request.addResourceTag(tag);
}
}
else {
EC2Filter oneFilter = new EC2Filter();
oneFilter.setName( filterName );
// -> is the filter one of the xsd:dateTime filters?
timeFilter = false;
for( int m=0; m < timeStrs.length; m++ ) {
timeFilter = filterName.equalsIgnoreCase( timeStrs[m] );
if (timeFilter) break;
}
for( int k=0; k < valueItems.length; k++ ) {
// -> time values are not encoded as regexes
if ( timeFilter )
oneFilter.addValue( valueItems[k].getValue());
else
oneFilter.addValueEncoded( valueItems[k].getValue());
}
sfs.addFilter( oneFilter );
}
}
request.setFilterSet(sfs);
}
return request;
}
// TODO make these filter set functions use generics
private EC2GroupFilterSet toGroupFilterSet( FilterSetType fst )
{
@ -1151,8 +1170,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
return gfs;
}
private EC2InstanceFilterSet toInstanceFilterSet( FilterSetType fst )
private EC2DescribeInstances toInstanceFilterSet( EC2DescribeInstances request, FilterSetType fst )
{
EC2InstanceFilterSet ifs = new EC2InstanceFilterSet();
@ -1162,22 +1180,30 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
// -> each filter can have one or more values associated with it
for( int j=0; j < items.length; j++ )
{
EC2Filter oneFilter = new EC2Filter();
String filterName = items[j].getName();
oneFilter.setName( filterName );
ValueSetType vst = items[j].getValueSet();
ValueType[] valueItems = vst.getItem();
for( int k=0; k < valueItems.length; k++ )
{
oneFilter.addValueEncoded( valueItems[k].getValue());
}
ifs.addFilter( oneFilter );
}
}
return ifs;
}
String filterName = items[j].getName();
ValueSetType vst = items[j].getValueSet();
ValueType[] valueItems = vst.getItem();
if (filterName.startsWith("tag:")) {
String key= filterName.split(":")[1];
for (ValueType valueItem : valueItems) {
EC2TagKeyValue tag = new EC2TagKeyValue();
tag.setKey(key);
tag.setValue(valueItem.getValue());
request.addResourceTag(tag);
}
} else {
EC2Filter oneFilter = new EC2Filter();
oneFilter.setName( filterName );
for( int k=0; k < valueItems.length; k++ )
oneFilter.addValueEncoded( valueItems[k].getValue());
ifs.addFilter( oneFilter );
}
}
request.setFilterSet(ifs);
}
return request;
}
private EC2AvailabilityZonesFilterSet toAvailabiltyZonesFilterSet( FilterSetType fst ) {
EC2AvailabilityZonesFilterSet azfs = new EC2AvailabilityZonesFilterSet();

View File

@ -23,6 +23,7 @@ public class EC2DescribeInstances {
private List<String> instancesSet = new ArrayList<String>(); // a list of strings identifying instances
private EC2InstanceFilterSet ifs = null;
private List<EC2TagKeyValue> resourceTagSet = new ArrayList<EC2TagKeyValue>();
public EC2DescribeInstances() {
}
@ -42,4 +43,12 @@ public class EC2DescribeInstances {
public void setFilterSet( EC2InstanceFilterSet param ) {
ifs = param;
}
public void addResourceTag( EC2TagKeyValue param ) {
resourceTagSet.add( param );
}
public EC2TagKeyValue[] getResourceTagSet() {
return resourceTagSet.toArray(new EC2TagKeyValue[0]);
}
}

View File

@ -23,6 +23,7 @@ public class EC2DescribeSnapshots {
private List<String> snapshotSet = new ArrayList<String>(); // a list of strings identifying snapshots
private EC2SnapshotFilterSet sfs = null;
private List<EC2TagKeyValue> resourceTagSet = new ArrayList<EC2TagKeyValue>();
public EC2DescribeSnapshots() {
}
@ -42,4 +43,12 @@ public class EC2DescribeSnapshots {
public void setFilterSet( EC2SnapshotFilterSet param ) {
sfs = param;
}
public void addResourceTag( EC2TagKeyValue param ) {
resourceTagSet.add( param );
}
public EC2TagKeyValue[] getResourceTagSet() {
return resourceTagSet.toArray(new EC2TagKeyValue[0]);
}
}

View File

@ -23,6 +23,7 @@ public class EC2DescribeVolumes {
private List<String> volumeSet = new ArrayList<String>(); // a list of strings identifying volume ids
private EC2VolumeFilterSet vfs = null;
private List<EC2TagKeyValue> resourceTagSet = new ArrayList<EC2TagKeyValue>();
public EC2DescribeVolumes() {
}
@ -42,4 +43,12 @@ public class EC2DescribeVolumes {
public void setFilterSet( EC2VolumeFilterSet param ) {
vfs = param;
}
public void addResourceTag( EC2TagKeyValue param ) {
resourceTagSet.add( param );
}
public EC2TagKeyValue[] getResourceTagSet() {
return resourceTagSet.toArray(new EC2TagKeyValue[0]);
}
}

View File

@ -418,20 +418,22 @@ public class EC2Engine {
* @param request
* @return
*/
public EC2DescribeSnapshotsResponse handleRequest( EC2DescribeSnapshots request )
public EC2DescribeSnapshotsResponse handleRequest( EC2DescribeSnapshots request )
{
EC2DescribeVolumesResponse volumes = new EC2DescribeVolumesResponse();
EC2SnapshotFilterSet sfs = request.getFilterSet();
EC2TagKeyValue[] tagKeyValueSet = request.getResourceTagSet();
try {
// -> query to get the volume size for each snapshot
EC2DescribeSnapshotsResponse response = listSnapshots( request.getSnapshotSet());
EC2DescribeSnapshotsResponse response = listSnapshots( request.getSnapshotSet(),
getResourceTags(tagKeyValueSet));
if (response == null) {
return new EC2DescribeSnapshotsResponse();
}
EC2Snapshot[] snapshots = response.getSnapshotSet();
for (EC2Snapshot snap : snapshots) {
volumes = listVolumes(snap.getVolumeId(), null, volumes);
volumes = listVolumes(snap.getVolumeId(), null, volumes, null);
EC2Volume[] volSet = volumes.getVolumeSet();
if (0 < volSet.length) snap.setVolumeSize(volSet[0].getSize());
volumes.reset();
@ -473,7 +475,7 @@ public class EC2Engine {
ec2Snapshot.setCreated(snap.getCreated());
ec2Snapshot.setVolumeId(snap.getVolumeId());
List<CloudStackVolume> vols = getApi().listVolumes(null, null, null, snap.getVolumeId(), null, null, null, null, null, null, null);
List<CloudStackVolume> vols = getApi().listVolumes(null, null, null, snap.getVolumeId(), null, null, null, null, null, null, null, null);
if(vols.size() > 0) {
assert(vols.get(0).getSize() != null);
@ -630,17 +632,18 @@ public class EC2Engine {
*
* @param interestedShots - can be null, should be a subset of all snapshots
*/
private EC2DescribeSnapshotsResponse listSnapshots( String[] interestedShots ) throws Exception {
private EC2DescribeSnapshotsResponse listSnapshots( String[] interestedShots, List<CloudStackKeyValue> resourceTagSet ) throws Exception {
EC2DescribeSnapshotsResponse snapshots = new EC2DescribeSnapshotsResponse();
List<CloudStackSnapshot> cloudSnaps;
if (interestedShots == null || interestedShots.length == 0) {
cloudSnaps = getApi().listSnapshots(null, null, null, null, null, null, null, null, null);
cloudSnaps = getApi().listSnapshots(null, null, null, null, null, null, null, null, null, resourceTagSet);
} else {
cloudSnaps = new ArrayList<CloudStackSnapshot>();
for(String id : interestedShots) {
List<CloudStackSnapshot> tmpList = getApi().listSnapshots(null, null, id, null, null, null, null, null, null);
List<CloudStackSnapshot> tmpList = getApi().listSnapshots(null, null, id, null, null, null, null,
null, null, resourceTagSet);
cloudSnaps.addAll(tmpList);
}
}
@ -880,7 +883,7 @@ public class EC2Engine {
public boolean associateAddress( EC2AssociateAddress request ) {
try {
CloudStackIpAddress cloudIp = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null).get(0);
CloudStackUserVm cloudVm = getApi().listVirtualMachines(null, null, true, null, null, null, null, request.getInstanceId(), null, null, null, null, null, null, null, null).get(0);
CloudStackUserVm cloudVm = getApi().listVirtualMachines(null, null, true, null, null, null, null, request.getInstanceId(), null, null, null, null, null, null, null, null, null).get(0);
CloudStackInfoResponse resp = getApi().enableStaticNat(cloudIp.getId(), cloudVm.getId());
if (resp != null) {
@ -1005,7 +1008,7 @@ public class EC2Engine {
// [A] Creating a template from a VM volume should be from the ROOT volume
// Also for this to work the VM must be in a Stopped state so we 'reboot' it if its not
EC2DescribeVolumesResponse volumes = new EC2DescribeVolumesResponse();
volumes = listVolumes( null, request.getInstanceId(), volumes );
volumes = listVolumes( null, request.getInstanceId(), volumes, null );
EC2Volume[] volSet = volumes.getVolumeSet();
for (EC2Volume vol : volSet) {
if (vol.getType().equalsIgnoreCase( "ROOT" )) {
@ -1022,7 +1025,7 @@ public class EC2Engine {
// [B] The parameters must be in sorted order for proper signature generation
EC2DescribeInstancesResponse instances = new EC2DescribeInstancesResponse();
instances = lookupInstances( request.getInstanceId(), instances );
instances = lookupInstances( request.getInstanceId(), instances, null );
EC2Instance[] instanceSet = instances.getInstanceSet();
String templateId = instanceSet[0].getTemplateId();
@ -1116,7 +1119,9 @@ public class EC2Engine {
*/
public EC2DescribeInstancesResponse describeInstances(EC2DescribeInstances request ) {
try {
return listVirtualMachines( request.getInstancesSet(), request.getFilterSet());
EC2TagKeyValue[] tagKeyValueSet = request.getResourceTagSet();
return listVirtualMachines( request.getInstancesSet(), request.getFilterSet(),
getResourceTags(tagKeyValueSet));
} catch( Exception e ) {
logger.error( "EC2 DescribeInstances - " ,e);
throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
@ -1160,14 +1165,14 @@ public class EC2Engine {
public EC2DescribeVolumesResponse handleRequest( EC2DescribeVolumes request ) {
EC2DescribeVolumesResponse volumes = new EC2DescribeVolumesResponse();
EC2VolumeFilterSet vfs = request.getFilterSet();
EC2TagKeyValue[] tagKeyValueSet = request.getResourceTagSet();
try {
String[] volumeIds = request.getVolumeSet();
if ( 0 == volumeIds.length ){
volumes = listVolumes( null, null, volumes );
volumes = listVolumes( null, null, volumes, getResourceTags(tagKeyValueSet) );
} else {
for (String s : volumeIds)
volumes = listVolumes(s, null, volumes );
volumes = listVolumes(s, null, volumes, getResourceTags(tagKeyValueSet) );
}
if ( null == vfs )
@ -1408,7 +1413,7 @@ public class EC2Engine {
// -> reboot is not allowed on destroyed (i.e., terminated) instances
try {
String[] instanceSet = request.getInstancesSet();
EC2DescribeInstancesResponse previousState = listVirtualMachines( instanceSet, null );
EC2DescribeInstancesResponse previousState = listVirtualMachines( instanceSet, null, null );
vms = previousState.getInstanceSet();
// -> send reboot requests for each found VM
@ -1545,7 +1550,7 @@ public class EC2Engine {
// -> first determine the current state of each VM (becomes it previous state)
try {
EC2DescribeInstancesResponse previousState = listVirtualMachines( request.getInstancesSet(), null );
EC2DescribeInstancesResponse previousState = listVirtualMachines( request.getInstancesSet(), null, null );
vms = previousState.getInstanceSet();
// -> send start requests for each item
@ -1587,7 +1592,7 @@ public class EC2Engine {
try {
String[] instanceSet = request.getInstancesSet();
EC2DescribeInstancesResponse previousState = listVirtualMachines( instanceSet, null );
EC2DescribeInstancesResponse previousState = listVirtualMachines( instanceSet, null, null );
virtualMachines = previousState.getInstanceSet();
// -> send stop requests for each item
@ -1654,7 +1659,7 @@ public class EC2Engine {
if (maxAllowed == -1)
return -1; // no limit
EC2DescribeInstancesResponse existingVMS = listVirtualMachines( null, null );
EC2DescribeInstancesResponse existingVMS = listVirtualMachines( null, null, null );
EC2Instance[] vmsList = existingVMS.getInstanceSet();
return (maxAllowed - vmsList.length);
} else {
@ -1668,15 +1673,16 @@ public class EC2Engine {
* @param virtualMachineIds - an array of instances we are interested in getting information on
* @param ifs - filter out unwanted instances
*/
private EC2DescribeInstancesResponse listVirtualMachines( String[] virtualMachineIds, EC2InstanceFilterSet ifs ) throws Exception
private EC2DescribeInstancesResponse listVirtualMachines( String[] virtualMachineIds, EC2InstanceFilterSet ifs,
List<CloudStackKeyValue> resourceTags ) throws Exception
{
EC2DescribeInstancesResponse instances = new EC2DescribeInstancesResponse();
if (null == virtualMachineIds || 0 == virtualMachineIds.length) {
instances = lookupInstances( null, instances );
instances = lookupInstances( null, instances, resourceTags );
} else {
for( int i=0; i < virtualMachineIds.length; i++ ) {
instances = lookupInstances( virtualMachineIds[i], instances );
instances = lookupInstances( virtualMachineIds[i], instances, resourceTags );
}
}
@ -1691,9 +1697,11 @@ public class EC2Engine {
* @param volumeId - if interested in one specific volume, null if want to list all volumes
* @param instanceId - if interested in volumes for a specific instance, null if instance is not important
*/
private EC2DescribeVolumesResponse listVolumes(String volumeId, String instanceId, EC2DescribeVolumesResponse volumes)throws Exception {
private EC2DescribeVolumesResponse listVolumes(String volumeId, String instanceId, EC2DescribeVolumesResponse volumes,
List<CloudStackKeyValue> resourceTagSet)throws Exception {
List<CloudStackVolume> vols = getApi().listVolumes(null, null, null, volumeId, null, null, null, null, null, instanceId, null);
List<CloudStackVolume> vols = getApi().listVolumes(null, null, null, volumeId, null, null, null, null, null,
instanceId, null, resourceTagSet);
if(vols != null && vols.size() > 0) {
for(CloudStackVolume vol : vols) {
EC2Volume ec2Vol = new EC2Volume();
@ -1872,12 +1880,13 @@ public class EC2Engine {
* @return the same object passed in as the "instances" parameter modified with one or more
* EC2Instance objects loaded.
*/
private EC2DescribeInstancesResponse lookupInstances( String instanceId, EC2DescribeInstancesResponse instances )
private EC2DescribeInstancesResponse lookupInstances( String instanceId, EC2DescribeInstancesResponse instances,
List<CloudStackKeyValue> resourceTagSet )
throws Exception {
String instId = instanceId != null ? instanceId : null;
List<CloudStackUserVm> vms = getApi().listVirtualMachines(null, null, true, null, null, null, null,
instId, null, null, null, null, null, null, null, null);
instId, null, null, null, null, null, null, null, null, resourceTagSet);
if(vms != null && vms.size() > 0) {
for(CloudStackUserVm cloudVm : vms) {
@ -2439,4 +2448,15 @@ public class EC2Engine {
}
return elementList.toString();
}
private List<CloudStackKeyValue> getResourceTags(EC2TagKeyValue[] tagKeyValueSet) {
List<CloudStackKeyValue> resourceTags = new ArrayList<CloudStackKeyValue>();
for (EC2TagKeyValue tagKeyValue : tagKeyValueSet) {
CloudStackKeyValue resourceTag = new CloudStackKeyValue();
resourceTag.setKeyValue(tagKeyValue.getKey(), tagKeyValue.getValue());
resourceTags.add(resourceTag);
}
return resourceTags;
}
}

View File

@ -48,20 +48,21 @@ public class EC2InstanceFilterSet {
filterTypes.put( "root-device-name", "string" );
filterTypes.put( "private-ip-address", "string" );
filterTypes.put( "group-id", "string" );
filterTypes.put( "tag-key", "string" );
filterTypes.put( "tag-value", "string" );
}
public void addFilter( EC2Filter param )
{
String filterName = param.getName();
String value = (String) filterTypes.get( filterName );
if (null == value)
throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 );
if (null != value && value.equalsIgnoreCase( "null" ))
throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 );
String value = (String) filterTypes.get( filterName );
if (null == value)
throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 );
if (null != value && value.equalsIgnoreCase( "null" ))
throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 );
// ToDo we could add checks to make sure the type of a filters value is correct (e.g., an integer)
filterSet.add( param );
}
@ -162,6 +163,26 @@ public class EC2InstanceFilterSet {
for (String group : groupSet)
if (containsString(group, valueSet)) return true;
return false;
}
else if (filterName.equalsIgnoreCase("tag-key"))
{
EC2TagKeyValue[] tagSet = vm.getResourceTags();
for (EC2TagKeyValue tag : tagSet)
if (containsString(tag.getKey(), valueSet)) return true;
return false;
}
else if (filterName.equalsIgnoreCase("tag-value"))
{
EC2TagKeyValue[] tagSet = vm.getResourceTags();
for (EC2TagKeyValue tag : tagSet) {
if (tag.getValue() == null) {
if (containsEmptyValue(valueSet)) return true;
}
else {
if (containsString(tag.getValue(), valueSet)) return true;
}
}
return false;
}
else return false;
}
@ -178,8 +199,14 @@ public class EC2InstanceFilterSet {
}
return false;
}
private boolean containsEmptyValue( String[] set )
{
for( int i=0; i < set.length; i++ )
if (set[i].isEmpty()) return true;
return false;
}
private boolean containsInteger( int lookingFor, String[] set )
{
for( int i=0; i < set.length; i++ )

View File

@ -46,20 +46,23 @@ public class EC2SnapshotFilterSet {
filterTypes.put( "status", "string" );
filterTypes.put( "volume-id", "string" );
filterTypes.put( "volume-size", "string" );
filterTypes.put( "tag-key", "string" );
filterTypes.put( "tag-value", "string" );
}
public void addFilter( EC2Filter param )
{
String filterName = param.getName();
String value = (String) filterTypes.get( filterName );
if (null == value)
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
if (null != value && value.equalsIgnoreCase( "null" ))
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
if (!filterName.startsWith("tag:")) {
String value = (String) filterTypes.get( filterName );
if (null == value)
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
if (null != value && value.equalsIgnoreCase( "null" ))
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
}
// ToDo we could add checks to make sure the type of a filters value is correct (e.g., an integer)
filterSet.add( param );
}
@ -140,6 +143,26 @@ public class EC2SnapshotFilterSet {
{
return containsLong( snap.getVolumeSize(), valueSet );
}
else if (filterName.equalsIgnoreCase("tag-key"))
{
EC2TagKeyValue[] tagSet = snap.getResourceTags();
for (EC2TagKeyValue tag : tagSet)
if (containsString(tag.getKey(), valueSet)) return true;
return false;
}
else if (filterName.equalsIgnoreCase("tag-value"))
{
EC2TagKeyValue[] tagSet = snap.getResourceTags();
for (EC2TagKeyValue tag : tagSet){
if (tag.getValue() == null) {
if (containsEmptyValue(valueSet)) return true;
}
else {
if (containsString(tag.getValue(), valueSet)) return true;
}
}
return false;
}
else return false;
}
@ -155,7 +178,13 @@ public class EC2SnapshotFilterSet {
return false;
}
private boolean containsEmptyValue( String[] set )
{
for( int i=0; i < set.length; i++ )
if (set[i].isEmpty()) return true;
return false;
}
private boolean containsLong( long lookingFor, String[] set )
{
for (String s : set) {

View File

@ -49,8 +49,8 @@ public class EC2VolumeFilterSet {
filterTypes.put( "size", "integer" );
filterTypes.put( "snapshot-id", "string" );
filterTypes.put( "status", "set:creating|available|in-use|deleting|deleted|error" );
filterTypes.put( "tag-key", "null" );
filterTypes.put( "tag-value", "null" );
filterTypes.put( "tag-key", "string" );
filterTypes.put( "tag-value", "string" );
filterTypes.put( "volume-id", "string" );
// filterTypes.put( "tag:*", "null" );
}
@ -59,14 +59,13 @@ public class EC2VolumeFilterSet {
public void addFilter( EC2Filter param )
{
String filterName = param.getName();
String value = (String) filterTypes.get( filterName );
String value = (String) filterTypes.get( filterName );
if (null == value)
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
if (null != value && value.equalsIgnoreCase( "null" ))
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
if (null == value)
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
if (null != value && value.equalsIgnoreCase( "null" ))
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
// ToDo we could add checks to make sure the type of a filters value is correct (e.g., an integer)
filterSet.add( param );
}
@ -136,7 +135,27 @@ public class EC2VolumeFilterSet {
else if (filterName.equalsIgnoreCase( "attachment.device" ))
return containsDevice(vol.getDeviceId(), valueSet );
else if (filterName.equalsIgnoreCase( "attachment.instance-id" ))
return containsString(String.valueOf(vol.getInstanceId()), valueSet );
return containsString(String.valueOf(vol.getInstanceId()), valueSet );
else if (filterName.equalsIgnoreCase("tag-key"))
{
EC2TagKeyValue[] tagSet = vol.getResourceTags();
for (EC2TagKeyValue tag : tagSet)
if (containsString(tag.getKey(), valueSet)) return true;
return false;
}
else if (filterName.equalsIgnoreCase("tag-value"))
{
EC2TagKeyValue[] tagSet = vol.getResourceTags();
for (EC2TagKeyValue tag : tagSet){
if (tag.getValue() == null) {
if (containsEmptyValue(valueSet)) return true;
}
else {
if (containsString(tag.getValue(), valueSet)) return true;
}
}
return false;
}
else return false;
}
@ -150,6 +169,12 @@ public class EC2VolumeFilterSet {
return false;
}
private boolean containsEmptyValue( String[] set )
{
for( int i=0; i < set.length; i++ )
if (set[i].isEmpty()) return true;
return false;
}
private boolean containsLong( long lookingFor, String[] set )
{

View File

@ -314,7 +314,7 @@ public class CloudStackApi {
*/
public List<CloudStackUserVm> listVirtualMachines(String account, String accountId, Boolean listAll, Boolean forVirtualNetwork, String groupId, String hostId,
String hypervisor, String id, Boolean isRecursive, String keyWord, String name, String networkId, String podId, String state, String storageId,
String zoneId) throws Exception {
String zoneId, List<CloudStackKeyValue> resourceTags) throws Exception {
CloudStackCommand cmd = new CloudStackCommand(ApiConstants.LIST_VIRTUAL_MACHINES);
if (cmd != null) {
if (account != null) cmd.setParam(ApiConstants.ACCOUNT, account);
@ -333,6 +333,8 @@ public class CloudStackApi {
if (state != null) cmd.setParam(ApiConstants.STATE, state);
if (storageId != null) cmd.setParam(ApiConstants.STORAGE_ID, storageId);
if (zoneId != null) cmd.setParam(ApiConstants.ZONE_ID, zoneId);
if (resourceTags != null && resourceTags.size() > 0)
cmd = setParams(cmd, null, null, resourceTags);
}
return _client.listCall(cmd, apiKey, secretKey, ApiConstants.LIST_VIRTUAL_MACHINES_RESPONSE, ApiConstants.VIRTUAL_MACHINE,
new TypeToken<List<CloudStackUserVm>>() {}.getType());
@ -935,7 +937,7 @@ public class CloudStackApi {
* @throws Exception
*/
public List<CloudStackVolume> listVolumes(String account, String domainId, String hostId, String id, Boolean isRecursive, String keyWord, String name,
String podId, String type, String virtualMachineId, String zoneId) throws Exception {
String podId, String type, String virtualMachineId, String zoneId, List<CloudStackKeyValue> resourceTags) throws Exception {
CloudStackCommand cmd = new CloudStackCommand(ApiConstants.LIST_VOLUMES);
if (cmd != null) {
if (account != null) cmd.setParam(ApiConstants.ACCOUNT, account);
@ -949,6 +951,8 @@ public class CloudStackApi {
if (type != null) cmd.setParam(ApiConstants.TYPE, type);
if (virtualMachineId != null) cmd.setParam(ApiConstants.VIRTUAL_MACHINE_ID, virtualMachineId);
if (zoneId != null) cmd.setParam(ApiConstants.ZONE_ID, zoneId);
if (resourceTags != null && resourceTags.size() > 0)
cmd = setParams(cmd, null, null, resourceTags);
}
return _client.listCall(cmd, apiKey, secretKey, ApiConstants.LIST_VOLUMES_RESPONSE, ApiConstants.VOLUME,
new TypeToken<List<CloudStackVolume>>() {}.getType());
@ -1029,7 +1033,8 @@ public class CloudStackApi {
private CloudStackCommand setParams(CloudStackCommand cmd, String resourceType, List<String>resourceIds,
List<CloudStackKeyValue> resourceTags) {
if (cmd != null) {
cmd.setParam(ApiConstants.RESOURCE_TYPE, resourceType);
if (resourceType != null)
cmd.setParam(ApiConstants.RESOURCE_TYPE, resourceType);
if (resourceIds != null && resourceIds.size() > 0) {
String resourceIdList = resourceIds.get(0);
for (int i=1 ; i<resourceIds.size(); i++)
@ -1243,7 +1248,7 @@ public class CloudStackApi {
* @throws Exception
*/
public List<CloudStackSnapshot> listSnapshots(String account, String domainId, String id, String intervalType, Boolean isRecursive,
String keyWord, String name, String snapshotType, String volumeId) throws Exception {
String keyWord, String name, String snapshotType, String volumeId, List<CloudStackKeyValue> resourceTags) throws Exception {
CloudStackCommand cmd = new CloudStackCommand(ApiConstants.LIST_SNAPSHOTS);
if (cmd != null) {
if (account != null) cmd.setParam(ApiConstants.ACCOUNT, account);
@ -1255,6 +1260,8 @@ public class CloudStackApi {
if (name != null) cmd.setParam(ApiConstants.NAME, name);
if (snapshotType != null) cmd.setParam(ApiConstants.SNAPSHOT_TYPE, snapshotType);
if (volumeId != null) cmd.setParam(ApiConstants.VOLUME_ID, volumeId);
if (resourceTags != null && resourceTags.size() > 0)
cmd = setParams(cmd, null, null, resourceTags);
}
return _client.listCall(cmd, apiKey, secretKey, ApiConstants.LIST_SNAPSHOTS_RESPONSE, ApiConstants.SNAPSHOT,
new TypeToken<List<CloudStackSnapshot>>() {}.getType());