CLOUDSTACK-2600. Fix CS AWSAPI to add the below filters that are missing in DescribeImages API-

architecture
description
image-id
image-type
is-public
name
owner-id
state
tag-key
tag-value
tag:key
hypervisor
This commit is contained in:
Likitha Shetty 2013-05-21 11:58:01 +05:30
parent 218d26be60
commit 6217b0fb4c
6 changed files with 290 additions and 36 deletions

View File

@ -135,6 +135,7 @@ import com.cloud.bridge.service.core.ec2.EC2Engine;
import com.cloud.bridge.service.core.ec2.EC2Filter;
import com.cloud.bridge.service.core.ec2.EC2GroupFilterSet;
import com.cloud.bridge.service.core.ec2.EC2Image;
import com.cloud.bridge.service.core.ec2.EC2ImageFilterSet;
import com.cloud.bridge.service.core.ec2.EC2ImageAttributes.ImageAttribute;
import com.cloud.bridge.service.core.ec2.EC2ImageLaunchPermission;
import com.cloud.bridge.service.core.ec2.EC2ImportKeyPair;
@ -1380,6 +1381,15 @@ public class EC2RestServlet extends HttpServlet {
if (null != value && 0 < value.length) EC2request.addImageSet( value[0] );
}
}
// add filters
EC2Filter[] filterSet = extractFilters( request );
if ( filterSet != null ) {
EC2ImageFilterSet ifs = new EC2ImageFilterSet();
for( int i=0; i < filterSet.length; i++ ) {
ifs.addFilter(filterSet[i]);
}
EC2request.setFilterSet( ifs );
}
// -> execute the request
EC2Engine engine = ServiceProvider.getInstance().getEC2Engine();
DescribeImagesResponse EC2response = EC2SoapServiceImpl.toDescribeImagesResponse( engine.describeImages( EC2request ));

View File

@ -51,6 +51,7 @@ import com.cloud.bridge.service.core.ec2.EC2DescribeInstances;
import com.cloud.bridge.service.core.ec2.EC2DescribeInstancesResponse;
import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairs;
import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairsResponse;
import com.cloud.bridge.service.core.ec2.EC2ImageFilterSet;
import com.cloud.bridge.service.core.ec2.EC2ImageLaunchPermission;
import com.cloud.bridge.service.core.ec2.EC2ResourceTag;
import com.cloud.bridge.service.core.ec2.EC2DescribeSecurityGroups;
@ -407,7 +408,10 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
for( int i=0; i < items3.length; i++ ) request.addOwnersSet( items3[i].getOwner());
}
}
FilterSetType fst = dit.getFilterSet();
if ( fst != null) {
request.setFilterSet(toImageFilterSet(fst));
}
return toDescribeImagesResponse( engine.describeImages( request ));
}
@ -948,7 +952,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
DescribeImagesResponseItemType param3 = new DescribeImagesResponseItemType();
param3.setImageId( images[i].getId());
param3.setImageLocation( "" );
param3.setImageState( (images[i].getIsReady() ? "available" : "unavailable" ));
param3.setImageState( images[i].getState());
param3.setImageOwnerId(ownerId);
param3.setIsPublic( images[i].getIsPublic());
@ -960,16 +964,14 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
String description = images[i].getDescription();
param3.setDescription( (null == description ? "" : description));
if (null == description) param3.setArchitecture( "" );
else if (-1 != description.indexOf( "x86_64" )) param3.setArchitecture( "x86_64" );
else if (-1 != description.indexOf( "i386" )) param3.setArchitecture( "i386" );
else param3.setArchitecture( "" );
param3.setImageType( "machine" );
param3.setArchitecture( images[i].getArchitecture());
param3.setImageType( images[i].getImageType());
param3.setKernelId( "" );
param3.setRamdiskId( "" );
param3.setPlatform( "" );
param3.setHypervisor( images[i].getHypervisor());
StateReasonType param6 = new StateReasonType();
param6.setCode( "" );
@ -1287,6 +1289,27 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
return tfs;
}
private EC2ImageFilterSet toImageFilterSet( FilterSetType fst ) {
EC2ImageFilterSet ifs = new EC2ImageFilterSet();
FilterType[] items = fst.getItem();
if (items != null) {
for (FilterType item : items) {
EC2Filter oneFilter = new EC2Filter();
String filterName = item.getName();
oneFilter.setName( filterName );
ValueSetType vft = item.getValueSet();
ValueType[] valueItems = vft.getItem();
for (ValueType valueItem : valueItems) {
oneFilter.addValueEncoded( valueItem.getValue());
}
ifs.addFilter( oneFilter );
}
}
return ifs;
}
// toMethods
public static DescribeVolumesResponse toDescribeVolumesResponse( EC2DescribeVolumesResponse engineResponse )
{

View File

@ -24,6 +24,7 @@ public class EC2DescribeImages {
private List<String> executableBySet = new ArrayList<String>();; // a list of strings identifying users
private List<String> imageSet = new ArrayList<String>(); // a list of AMI id's
private List<String> ownersSet = new ArrayList<String>(); // a list of AMI owner id's
private EC2ImageFilterSet ifs = null;
public EC2DescribeImages() {
}
@ -51,4 +52,13 @@ public class EC2DescribeImages {
public String[] getOwnersSet() {
return ownersSet.toArray(new String[0]);
}
public EC2ImageFilterSet getFilterSet() {
return ifs;
}
public void setFilterSet( EC2ImageFilterSet param ) {
ifs = param;
}
}

View File

@ -902,15 +902,19 @@ public class EC2Engine extends ManagerBase {
try {
String[] templateIds = request.getImageSet();
EC2ImageFilterSet ifs = request.getFilterSet();
if ( 0 == templateIds.length ) {
return listTemplates(null, images);
if ( templateIds.length == 0 ) {
images = listTemplates(null, images);
} else {
for (String s : templateIds) {
images = listTemplates(s, images);
}
}
for (String s : templateIds) {
images = listTemplates(s, images);
}
return images;
if (ifs == null)
return images;
else
return ifs.evaluate(images);
} catch( Exception e ) {
logger.error( "EC2 DescribeImages - ", e);
throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
@ -1951,8 +1955,22 @@ public class EC2Engine extends ManagerBase {
ec2Image.setDescription(temp.getDisplayText());
ec2Image.setOsTypeId(temp.getOsTypeId().toString());
ec2Image.setIsPublic(temp.getIsPublic());
ec2Image.setIsReady(temp.getIsReady());
ec2Image.setState( temp.getIsReady() ? "available" : "pending");
ec2Image.setDomainId(temp.getDomainId());
if ( temp.getHyperVisor().equalsIgnoreCase("xenserver"))
ec2Image.setHypervisor("xen");
else if ( temp.getHyperVisor().equalsIgnoreCase("ovm"))
ec2Image.setHypervisor( "ovm"); // valid values for hypervisor is 'ovm' and 'xen'
else
ec2Image.setHypervisor("");
if (temp.getDisplayText() == null)
ec2Image.setArchitecture("");
else if (temp.getDisplayText().indexOf( "x86_64" ) != -1)
ec2Image.setArchitecture("x86_64");
else if (temp.getDisplayText().indexOf( "i386" ) != -1)
ec2Image.setArchitecture("i386");
else
ec2Image.setArchitecture("");
List<CloudStackKeyValue> resourceTags = temp.getTags();
for(CloudStackKeyValue resourceTag : resourceTags) {
EC2TagKeyValue param = new EC2TagKeyValue();

View File

@ -28,10 +28,13 @@ public class EC2Image {
private String name;
private String description;
private String osTypeId;
private boolean isPublic;
private boolean isReady;
private Boolean isPublic;
private String state;
private String accountName;
private String domainId;
private String domainId;
private String hypervisor;
private String architecture;
private String imageType;
private List<EC2TagKeyValue> tagsSet;
public EC2Image() {
@ -40,9 +43,12 @@ public class EC2Image {
description = null;
osTypeId = null;
isPublic = false;
isReady = false;
state = null;
accountName = null;
domainId = null;
domainId = null;
hypervisor = null;
architecture = null;
imageType = "machine";
tagsSet = new ArrayList<EC2TagKeyValue>();
}
@ -78,21 +84,21 @@ public class EC2Image {
return this.osTypeId;
}
public void setIsPublic( boolean isPublic ) {
this.isPublic = isPublic;
}
public boolean getIsPublic() {
return this.isPublic;
}
public void setIsPublic( Boolean isPublic ) {
this.isPublic = isPublic;
}
public void setIsReady( boolean isReady ) {
this.isReady = isReady;
}
public boolean getIsReady() {
return this.isReady;
}
public Boolean getIsPublic() {
return this.isPublic;
}
public void setState( String state ) {
this.state = state;
}
public String getState() {
return this.state;
}
public String getAccountName() {
return accountName;
@ -110,6 +116,25 @@ public class EC2Image {
this.domainId = domainId;
}
public String getHypervisor() {
return hypervisor;
}
public void setHypervisor(String hypervisor) {
this.hypervisor = hypervisor;
}
public String getArchitecture() {
return architecture;
}
public void setArchitecture(String architecture) {
this.architecture = architecture;
}
public String getImageType() {
return imageType;
}
public void addResourceTag( EC2TagKeyValue param ) {
tagsSet.add( param );

View File

@ -0,0 +1,168 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with 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.
package com.cloud.bridge.service.core.ec2;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.bridge.service.exception.EC2ServiceException;
public class EC2ImageFilterSet {
protected final static Logger logger = Logger.getLogger(EC2ImageFilterSet.class);
protected List<EC2Filter> filterSet = new ArrayList<EC2Filter>();
private Map<String,String> filterTypes = new HashMap<String,String>();
public EC2ImageFilterSet() {
// -> supported filters
filterTypes.put( "architecture", "string" );
filterTypes.put( "description", "string" );
filterTypes.put( "hypervisor", "string" );
filterTypes.put( "image-id", "string" );
filterTypes.put( "image-type", "string" );
filterTypes.put( "is-public", "Boolean" );
filterTypes.put( "name", "string" );
filterTypes.put( "owner-id", "string" );
filterTypes.put( "state", "string" );
filterTypes.put( "tag-key", "string" );
filterTypes.put( "tag-value", "string" );
}
public void addFilter( EC2Filter param ) {
String filterName = param.getName();
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 );
}
filterSet.add( param );
}
public EC2Filter[] getFilterSet() {
return filterSet.toArray(new EC2Filter[0]);
}
public EC2DescribeImagesResponse evaluate( EC2DescribeImagesResponse sampleList) throws ParseException {
EC2DescribeImagesResponse resultList = new EC2DescribeImagesResponse();
boolean matched;
EC2Image[] imageSet = sampleList.getImageSet();
EC2Filter[] filterSet = getFilterSet();
for (EC2Image image : imageSet) {
matched = true;
for (EC2Filter filter : filterSet) {
if (!filterMatched(image, filter)) {
matched = false;
break;
}
}
if (matched == true)
resultList.addImage(image);
}
return resultList;
}
private boolean filterMatched( EC2Image image, EC2Filter filter ) throws ParseException {
String filterName = filter.getName();
String[] valueSet = filter.getValueSet();
if ( filterName.equalsIgnoreCase( "architecture" ))
return containsString( image.getArchitecture(), valueSet );
if ( filterName.equalsIgnoreCase( "description" ))
return containsString( image.getDescription(), valueSet );
if ( filterName.equalsIgnoreCase( "hypervisor" ))
return containsString( image.getHypervisor(), valueSet );
if ( filterName.equalsIgnoreCase( "image-id" ))
return containsString( image.getId(), valueSet );
if ( filterName.equalsIgnoreCase( "image-type" ))
return containsString( image.getImageType(), valueSet );
if ( filterName.equalsIgnoreCase( "is-public" ))
return image.getIsPublic().toString().equalsIgnoreCase(valueSet[0]);
if ( filterName.equalsIgnoreCase( "name" ))
return containsString( image.getName(), valueSet );
if ( filterName.equalsIgnoreCase( "owner-id" )) {
String owner = new String( image.getDomainId() + ":" + image.getAccountName());
return containsString( owner, valueSet );
}
if ( filterName.equalsIgnoreCase( "state" ))
return containsString( image.getState(), valueSet );
else if (filterName.equalsIgnoreCase("tag-key"))
{
EC2TagKeyValue[] tagSet = image.getResourceTags();
for (EC2TagKeyValue tag : tagSet)
if (containsString(tag.getKey(), valueSet)) return true;
return false;
}
else if (filterName.equalsIgnoreCase("tag-value"))
{
EC2TagKeyValue[] tagSet = image.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 if (filterName.startsWith("tag:"))
{
String key = filterName.split(":")[1];
EC2TagKeyValue[] tagSet = image.getResourceTags();
for (EC2TagKeyValue tag : tagSet){
if (tag.getKey().equalsIgnoreCase(key)) {
if (tag.getValue() == null) {
if (containsEmptyValue(valueSet)) return true;
}
else {
if (containsString(tag.getValue(), valueSet)) return true;
}
}
}
return false;
}
else return false;
}
private boolean containsString( String lookingFor, String[] set ) {
if (lookingFor == null)
return false;
for (String filter: set) {
if (lookingFor.matches( filter )) return true;
}
return false;
}
private boolean containsEmptyValue( String[] set ) {
for( int i=0; i < set.length; i++ ) {
if (set[i].isEmpty()) return true;
}
return false;
}
}