Ori Liel has uploaded a new change for review. Change subject: restapi: Enable search on 2nd-level collections - WIP ......................................................................
restapi: Enable search on 2nd-level collections - WIP Until now search in API was only possible on rool-level collections. This patch makes search possible for 2nd level collections as well Change-Id: I3edd6ce6dbef351a0ba00b1a7a4c67476e67f778 Signed-off-by: Ori Liel <[email protected]> --- A backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/search/SearchTermsEnum.java M backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/QueryHelper.java A backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/UrlHelper.java M backend/manager/modules/restapi/interface/definition/pom.xml M backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/AbstractBackendCollectionResource.java M backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCenterClustersResource.java M backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendVmResource.java M backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/ClusterConditionFieldAutoCompleter.java M backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/StorageDomainFieldAutoCompleter.java M backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/StoragePoolFieldAutoCompleter.java M backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/VdcUserConditionFieldAutoCompleter.java M backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/VdsConditionFieldAutoCompleter.java 12 files changed, 138 insertions(+), 4 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/71/38371/1 diff --git a/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/search/SearchTermsEnum.java b/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/search/SearchTermsEnum.java new file mode 100644 index 0000000..5b1beea --- /dev/null +++ b/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/search/SearchTermsEnum.java @@ -0,0 +1,61 @@ +package org.ovirt.engine.api.common.search; + +import java.util.HashMap; +import java.util.Map; + +import org.ovirt.engine.core.searchbackend.ClusterConditionFieldAutoCompleter; +import org.ovirt.engine.core.searchbackend.DiskConditionFieldAutoCompleter; +import org.ovirt.engine.core.searchbackend.SearchObjects; +import org.ovirt.engine.core.searchbackend.StorageDomainFieldAutoCompleter; +import org.ovirt.engine.core.searchbackend.StoragePoolFieldAutoCompleter; +import org.ovirt.engine.core.searchbackend.VdcUserConditionFieldAutoCompleter; +import org.ovirt.engine.core.searchbackend.VdsConditionFieldAutoCompleter; +import org.ovirt.engine.core.searchbackend.VmConditionFieldAutoCompleter; +import org.ovirt.engine.core.searchbackend.VmTemplateConditionFieldAutoCompleter; + +public enum SearchTermsEnum { + + DATACENTER("datacenters", SearchObjects.VDC_STORAGE_POOL_OBJ_NAME, StoragePoolFieldAutoCompleter.ID), + CLUSTER("clusters", SearchObjects.VDC_CLUSTER_OBJ_NAME, ClusterConditionFieldAutoCompleter.ID), + HOST("hosts", SearchObjects.VDS_OBJ_NAME, VdsConditionFieldAutoCompleter.ID), + VM("vms", SearchObjects.VM_OBJ_NAME, VmConditionFieldAutoCompleter.ID), + STORAGE_DOMAIN("storagedomains", SearchObjects.VDC_STORAGE_DOMAIN_OBJ_NAME, StorageDomainFieldAutoCompleter.ID), + USER("users", SearchObjects.VDC_USER_OBJ_NAME, VdcUserConditionFieldAutoCompleter.ID), + DISK("disks", SearchObjects.DISK_OBJ_NAME, DiskConditionFieldAutoCompleter.ID), + TEMPLATE("templates", SearchObjects.TEMPLATE_OBJ_NAME, VmTemplateConditionFieldAutoCompleter.VMT_ID); + + private String uriName; + private String searchCollectionName; + private String idField; + + private SearchTermsEnum(String uriName, String searchCollectionName, String idField) { + this.uriName = uriName; + this.searchCollectionName = searchCollectionName; + this.idField = idField; + } + + private static Map<String, SearchTermsEnum> map = new HashMap<>(); + + static { + for (SearchTermsEnum entry : SearchTermsEnum.values()) { + map.put(entry.uriName, entry); + } + } + + public static SearchTermsEnum getByUriName(String uriName) { + return map.get(uriName); + } + + public String getUriName() { + return uriName; + } + + public String getSearchCollectionName() { + return searchCollectionName; + } + + public String getIdField() { + return idField; + } + +} diff --git a/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/QueryHelper.java b/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/QueryHelper.java index b3fa5c5..a2e9885 100644 --- a/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/QueryHelper.java +++ b/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/QueryHelper.java @@ -25,6 +25,7 @@ import javax.ws.rs.core.PathSegment; import javax.ws.rs.core.UriInfo; +import org.ovirt.engine.api.common.search.SearchTermsEnum; import org.ovirt.engine.api.model.Cluster; import org.ovirt.engine.api.model.DataCenter; import org.ovirt.engine.api.model.Disk; @@ -210,4 +211,35 @@ (hasMatrixParam(uriInfo, CURRENT_CONSTRAINT_PARAMETER) && !"false".equalsIgnoreCase(QueryHelper.getMatrixConstraint(uriInfo, CURRENT_CONSTRAINT_PARAMETER))); } + + /** + * Returns the search constraint of the query in the format that the engine expects to receive it. Search is + * currently supported for root and 2nd level collections, e.g: /api/datacenters and api/datacenters/xxx/cluster. + */ + public static String getSearchConstraint(UriInfo uriInfo, Class<?> modelType) { + List<PathSegment> pathSegments = uriInfo.getPathSegments(); + assert pathSegments.size() == 1 || pathSegments.size() == 3; + StringBuilder searchConstraints = new StringBuilder(getConstraint(uriInfo, "", modelType)); + // Implicit ID-constraints are only appended for 2nd-level collections + if (pathSegments.size() == 3) { + appendImplicitIdConstraints(pathSegments, searchConstraints); + } + return searchConstraints.toString(); + } + + private static void appendImplicitIdConstraints(List<PathSegment> pathSegments, StringBuilder searchConstraints) { + SearchTermsEnum joinCollection = SearchTermsEnum.getByUriName(pathSegments.get(0).getPath()); + if (otherSearchConditionsExist(searchConstraints)) { + searchConstraints.append(" and "); + } + searchConstraints.append(joinCollection.getSearchCollectionName()) + .append(".") + .append(joinCollection.getIdField()) + .append(" = ") + .append(pathSegments.get(1).getPath()); + } + + private static boolean otherSearchConditionsExist(StringBuilder searchConstraints) { + return !(searchConstraints.toString().trim().endsWith(":")); + } } diff --git a/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/UrlHelper.java b/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/UrlHelper.java new file mode 100644 index 0000000..45ffc4d --- /dev/null +++ b/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/UrlHelper.java @@ -0,0 +1,5 @@ +package org.ovirt.engine.api.common.util; + +public class UrlHelper { + +} diff --git a/backend/manager/modules/restapi/interface/definition/pom.xml b/backend/manager/modules/restapi/interface/definition/pom.xml index aa196d2..c39b32d 100644 --- a/backend/manager/modules/restapi/interface/definition/pom.xml +++ b/backend/manager/modules/restapi/interface/definition/pom.xml @@ -14,6 +14,12 @@ <dependencies> + <dependency> + <groupId>org.ovirt.engine.core</groupId> + <artifactId>searchbackend</artifactId> + <version>${engine.version}</version> + </dependency> + <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jaxrs</artifactId> diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/AbstractBackendCollectionResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/AbstractBackendCollectionResource.java index 9b072f8..64353fa 100644 --- a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/AbstractBackendCollectionResource.java +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/AbstractBackendCollectionResource.java @@ -49,7 +49,7 @@ protected abstract Response performRemove(String id); protected List<Q> getBackendCollection(SearchType searchType) { - return getBackendCollection(searchType, QueryHelper.getConstraint(getUriInfo(), "", modelType)); + return getBackendCollection(searchType, QueryHelper.getSearchConstraint(uriInfo, modelType)); } protected List<Q> getBackendCollection(SearchType searchType, String constraint) { diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCenterClustersResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCenterClustersResource.java index 5d23d4f..7c5e60b 100644 --- a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCenterClustersResource.java +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCenterClustersResource.java @@ -10,6 +10,7 @@ import org.ovirt.engine.api.resource.ClusterResource; import org.ovirt.engine.core.common.businessentities.StoragePool; import org.ovirt.engine.core.common.businessentities.VDSGroup; +import org.ovirt.engine.core.common.interfaces.SearchType; import org.ovirt.engine.core.common.queries.IdQueryParameters; import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.compat.Guid; @@ -24,7 +25,11 @@ @Override public Clusters list() { - return mapCollection(getVdsGroups()); + if (isFiltered()) { + return mapCollection(getVdsGroups()); + } else { + return mapCollection(getBackendCollection(SearchType.Cluster)); + } } protected List<VDSGroup> getVdsGroups() { diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendVmResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendVmResource.java index 0f53f82..ac4cd3b 100644 --- a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendVmResource.java +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendVmResource.java @@ -8,6 +8,7 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; + import org.ovirt.engine.api.common.util.DetailHelper; import org.ovirt.engine.api.common.util.QueryHelper; import org.ovirt.engine.api.model.Action; diff --git a/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/ClusterConditionFieldAutoCompleter.java b/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/ClusterConditionFieldAutoCompleter.java index 9aadd4c..999e7e5 100644 --- a/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/ClusterConditionFieldAutoCompleter.java +++ b/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/ClusterConditionFieldAutoCompleter.java @@ -1,5 +1,7 @@ package org.ovirt.engine.core.searchbackend; +import java.util.UUID; + import org.ovirt.engine.core.common.businessentities.ArchitectureType; public class ClusterConditionFieldAutoCompleter extends BaseConditionFieldAutoCompleter { @@ -7,6 +9,7 @@ public static final String DESCRIPTION = "DESCRIPTION"; public static final String COMMENT = "COMMENT"; public static final String ARCHITECTURE = "ARCHITECTURE"; + public static final String ID = "ID"; public ClusterConditionFieldAutoCompleter() { // Building the basic vervs Dict @@ -14,6 +17,7 @@ mVerbs.add(DESCRIPTION); mVerbs.add(COMMENT); mVerbs.add(ARCHITECTURE); + mVerbs.add(ID); // Building the autoCompletion Dict buildCompletions(); @@ -22,12 +26,14 @@ getTypeDictionary().put(DESCRIPTION, String.class); getTypeDictionary().put(COMMENT, String.class); getTypeDictionary().put(ARCHITECTURE, ArchitectureType.class); + getTypeDictionary().put(ID, UUID.class); // building the ColumnName Dict columnNameDict.put(NAME, "name"); columnNameDict.put(DESCRIPTION, "description"); columnNameDict.put(COMMENT, "free_text_comment"); columnNameDict.put(ARCHITECTURE, "architecture"); + columnNameDict.put(ID, "vds_group_id"); // Building the validation dict buildBasicValidationTable(); diff --git a/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/StorageDomainFieldAutoCompleter.java b/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/StorageDomainFieldAutoCompleter.java index 0b6fac9..d197f76 100644 --- a/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/StorageDomainFieldAutoCompleter.java +++ b/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/StorageDomainFieldAutoCompleter.java @@ -1,11 +1,14 @@ package org.ovirt.engine.core.searchbackend; +import java.util.UUID; + import org.ovirt.engine.core.common.businessentities.StorageDomainSharedStatus; import org.ovirt.engine.core.common.businessentities.StorageDomainStatus; import org.ovirt.engine.core.common.businessentities.StorageType; public class StorageDomainFieldAutoCompleter extends BaseConditionFieldAutoCompleter { public static final String NAME = "NAME"; + public static final String ID = "ID"; public static final String STATUS = "STATUS"; public static final String DATACENTER = "DATACENTER"; public static final String TYPE = "TYPE"; @@ -20,6 +23,7 @@ // Building the basic vervs Dict mVerbs.add(NAME); mVerbs.add(STATUS); + mVerbs.add(ID); mVerbs.add(DATACENTER); mVerbs.add(TYPE); mVerbs.add(SIZE); @@ -33,6 +37,7 @@ buildCompletions(); // Building the types dict getTypeDictionary().put(NAME, String.class); + getTypeDictionary().put(ID, UUID.class); getTypeDictionary().put(STATUS, StorageDomainStatus.class); getTypeDictionary().put(DATACENTER, String.class); getTypeDictionary().put(TYPE, StorageType.class); @@ -45,6 +50,7 @@ // building the ColumnName Dict columnNameDict.put(NAME, "storage_name"); + columnNameDict.put(ID, "id"); columnNameDict.put(STATUS, "storage_domain_shared_status"); columnNameDict.put(DATACENTER, "storage_pool_name::text"); columnNameDict.put(TYPE, "storage_type"); diff --git a/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/StoragePoolFieldAutoCompleter.java b/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/StoragePoolFieldAutoCompleter.java index 84cfeab..9feccbc 100644 --- a/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/StoragePoolFieldAutoCompleter.java +++ b/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/StoragePoolFieldAutoCompleter.java @@ -1,5 +1,7 @@ package org.ovirt.engine.core.searchbackend; +import java.util.UUID; + import org.ovirt.engine.core.common.businessentities.StoragePoolStatus; public class StoragePoolFieldAutoCompleter extends BaseConditionFieldAutoCompleter { @@ -10,10 +12,12 @@ public static final String STATUS = "STATUS"; public static final String COMMENT = "COMMENT"; public static final String COMPATIBILITY_VERSION = "COMPATIBILITY_VERSION"; + public static final String ID = "ID"; public StoragePoolFieldAutoCompleter() { // Building the basic vervs Dict mVerbs.add(NAME); + mVerbs.add(ID); mVerbs.add(DESCRIPTION); mVerbs.add(LOCAL); mVerbs.add(STATUS); @@ -24,6 +28,7 @@ buildCompletions(); // Building the types dict getTypeDictionary().put(NAME, String.class); + getTypeDictionary().put(ID, UUID.class); getTypeDictionary().put(DESCRIPTION, String.class); getTypeDictionary().put(COMMENT, String.class); getTypeDictionary().put(LOCAL, Boolean.class); @@ -32,6 +37,7 @@ // building the ColumnName Dict columnNameDict.put(NAME, "name"); + columnNameDict.put(ID, "id"); columnNameDict.put(DESCRIPTION, "description"); columnNameDict.put(COMMENT, "free_text_comment"); columnNameDict.put(LOCAL, "is_local"); diff --git a/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/VdcUserConditionFieldAutoCompleter.java b/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/VdcUserConditionFieldAutoCompleter.java index da867c4..fc050ae 100644 --- a/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/VdcUserConditionFieldAutoCompleter.java +++ b/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/VdcUserConditionFieldAutoCompleter.java @@ -1,8 +1,10 @@ package org.ovirt.engine.core.searchbackend; +import java.util.UUID; public class VdcUserConditionFieldAutoCompleter extends BaseConditionFieldAutoCompleter { public static final String FIRST_NAME = "NAME"; + public static final String ID = "ID"; public static final String LAST_NAME = "LASTNAME"; public static final String USER_NAME = "USRNAME"; public static final String GROUP = "GROUP"; @@ -18,6 +20,7 @@ // Building the basic verbs dictionary. mVerbs.add(FIRST_NAME); mVerbs.add(LAST_NAME); + mVerbs.add(ID); mVerbs.add(USER_NAME); mVerbs.add("LOGIN"); mVerbs.add(DIRECTORY); @@ -36,6 +39,7 @@ // Building the types dictionary. getTypeDictionary().put(FIRST_NAME, String.class); getTypeDictionary().put(LAST_NAME, String.class); + getTypeDictionary().put(ID, UUID.class); getTypeDictionary().put(USER_NAME, String.class); getTypeDictionary().put("LOGIN", String.class); getTypeDictionary().put(DIRECTORY, String.class); @@ -51,6 +55,7 @@ // building the ColumnName Dict columnNameDict.put(FIRST_NAME, "name"); columnNameDict.put(LAST_NAME, "surname"); + columnNameDict.put(ID, "user_id"); columnNameDict.put(USER_NAME, "username"); columnNameDict.put("LOGIN", "username"); columnNameDict.put("DIRECTORY", "domain"); diff --git a/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/VdsConditionFieldAutoCompleter.java b/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/VdsConditionFieldAutoCompleter.java index fabef66..5f36a71 100644 --- a/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/VdsConditionFieldAutoCompleter.java +++ b/backend/manager/modules/searchbackend/src/main/java/org/ovirt/engine/core/searchbackend/VdsConditionFieldAutoCompleter.java @@ -9,6 +9,7 @@ public class VdsConditionFieldAutoCompleter extends BaseConditionFieldAutoCompleter { public static final String NAME = "NAME"; + public static final String ID = "ID"; public static final String ADDRESS = "ADDRESS"; public static final String CLUSTER = "CLUSTER"; public static final String DATACENTER = "DATACENTER"; @@ -43,7 +44,7 @@ mVerbs.add("ARCHITECTURE"); // mVerbs.Add("NOTE", "NOTE"); buildCompletions(); - mVerbs.add("ID"); + mVerbs.add(ID); // Building the types dict getTypeDictionary().put(NAME, String.class); getTypeDictionary().put("COMMENT", String.class); @@ -65,7 +66,7 @@ getTypeDictionary().put("TAG", String.class); getTypeDictionary().put("TYPE", VDSNiceType.class); getTypeDictionary().put(DATACENTER, String.class); - getTypeDictionary().put("ID", UUID.class); + getTypeDictionary().put(ID, UUID.class); getTypeDictionary().put("ARCHITECTURE", ArchitectureType.class); // mTypeDict.Add("NOTE", typeof(string)); // building the ColumnName Dict -- To view, visit https://gerrit.ovirt.org/38371 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3edd6ce6dbef351a0ba00b1a7a4c67476e67f778 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Ori Liel <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
