Daniel Erez has uploaded a new change for review. Change subject: restapi: openstack volume providers root collection ......................................................................
restapi: openstack volume providers root collection Introducing openstack volume providers resources: /api/openstackvolumeproviders * Support GET/POST/DELETE/UPDATE * Added openstack_volume_provider(s) elements to api.xsd. * Updated rsdl_metadata accordingly. * Updated FeaturesHelper. Feature Page: http://www.ovirt.org/Features/Cinder_Integration Change-Id: I89d2e9d975750d2ec22599079603bd48cff2603e Bug-Url: https://bugzilla.redhat.com/1185826 Signed-off-by: Daniel Erez <de...@redhat.com> --- A backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/openstack/OpenStackVolumeProviderResource.java A backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/openstack/OpenStackVolumeProvidersResource.java M backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/ApiRootLinksCreator.java M backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/LinkHelper.java M backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd M backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata.yaml M backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/BackendApplication.java A backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProviderResource.java A backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProvidersResource.java M backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/utils/FeaturesHelper.java M backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendApiResourceTest.java A backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProviderResourceTest.java A backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProvidersResourceTest.java A backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/openstack/OpenStackVolumeProviderMapper.java 14 files changed, 764 insertions(+), 0 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/03/39003/1 diff --git a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/openstack/OpenStackVolumeProviderResource.java b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/openstack/OpenStackVolumeProviderResource.java new file mode 100644 index 0000000..19d01f6 --- /dev/null +++ b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/openstack/OpenStackVolumeProviderResource.java @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2014 Red Hat, Inc. +* +* Licensed 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 org.ovirt.engine.api.resource.openstack; + +import org.ovirt.engine.api.model.OpenStackVolumeProvider; +import org.ovirt.engine.api.resource.ApiMediaType; +import org.ovirt.engine.api.resource.ExternalProviderResource; + +import javax.ws.rs.Produces; + +@Produces({ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, ApiMediaType.APPLICATION_X_YAML}) +public interface OpenStackVolumeProviderResource extends ExternalProviderResource<OpenStackVolumeProvider> { +} diff --git a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/openstack/OpenStackVolumeProvidersResource.java b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/openstack/OpenStackVolumeProvidersResource.java new file mode 100644 index 0000000..a4fbb3f --- /dev/null +++ b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/openstack/OpenStackVolumeProvidersResource.java @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2014 Red Hat, Inc. +* +* Licensed 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 org.ovirt.engine.api.resource.openstack; + +import org.ovirt.engine.api.model.OpenStackVolumeProvider; +import org.ovirt.engine.api.model.OpenStackVolumeProviders; +import org.ovirt.engine.api.resource.ApiMediaType; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; + +@Path("/openstackvolumeproviders") +@Produces({ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, ApiMediaType.APPLICATION_X_YAML}) +public interface OpenStackVolumeProvidersResource { + @GET + public OpenStackVolumeProviders list(); + + @POST + @Consumes({ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, ApiMediaType.APPLICATION_X_YAML}) + public Response add(OpenStackVolumeProvider provider); + + @DELETE + @Path("{id}") + public Response remove(@PathParam("id") String id); + + @Path("{id}") + public OpenStackVolumeProviderResource getOpenStackVolumeProvider(@PathParam("id") String id); +} diff --git a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/ApiRootLinksCreator.java b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/ApiRootLinksCreator.java index 7369fda..cd64a32 100644 --- a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/ApiRootLinksCreator.java +++ b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/ApiRootLinksCreator.java @@ -61,6 +61,7 @@ links.add(createLink("operatingsystems", baseUri)); links.add(createLink("externalhostproviders", baseUri)); links.add(createLink("openstackimageproviders", baseUri)); + links.add(createLink("openstackvolumeproviders", baseUri)); links.add(createLink("openstacknetworkproviders", baseUri)); links.add(createLink("katelloerrata", baseUri)); return links; diff --git a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/LinkHelper.java b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/LinkHelper.java index 49dfd1f7..8ebf97c 100644 --- a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/LinkHelper.java +++ b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/LinkHelper.java @@ -78,6 +78,7 @@ import org.ovirt.engine.api.model.OpenStackNetwork; import org.ovirt.engine.api.model.OpenStackNetworkProvider; import org.ovirt.engine.api.model.OpenStackSubnet; +import org.ovirt.engine.api.model.OpenStackVolumeProvider; import org.ovirt.engine.api.model.OperatingSystemInfo; import org.ovirt.engine.api.model.Parameter; import org.ovirt.engine.api.model.ParametersSet; @@ -264,6 +265,8 @@ import org.ovirt.engine.api.resource.openstack.OpenStackNetworksResource; import org.ovirt.engine.api.resource.openstack.OpenStackSubnetResource; import org.ovirt.engine.api.resource.openstack.OpenStackSubnetsResource; +import org.ovirt.engine.api.resource.openstack.OpenStackVolumeProviderResource; +import org.ovirt.engine.api.resource.openstack.OpenStackVolumeProvidersResource; /** * Contains a static addLinks() method which constructs any href attributes @@ -549,6 +552,10 @@ map.add(OpenStackImageResource.class, OpenStackImagesResource.class, OpenStackImageProvider.class); TYPES.put(OpenStackImage.class, map); + // OpenStack volume providers: + map = new ParentToCollectionMap(OpenStackVolumeProviderResource.class, OpenStackVolumeProvidersResource.class); + TYPES.put(OpenStackVolumeProvider.class, map); + // OpenStack network providers: map = new ParentToCollectionMap(OpenStackNetworkProviderResource.class, OpenStackNetworkProvidersResource.class); TYPES.put(OpenStackNetworkProvider.class, map); diff --git a/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd b/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd index 7a81124..2908879 100644 --- a/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd +++ b/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd @@ -5090,6 +5090,7 @@ <xs:element name="requires_authentication" type="xs:boolean" minOccurs="0" maxOccurs="1"/> <xs:element name="username" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="password" type="xs:string" minOccurs="0" maxOccurs="1"/> + <xs:element name="auth_url" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element ref="properties" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:extension> @@ -5325,6 +5326,37 @@ </xs:complexContent> </xs:complexType> + <!-- OpenStack volume providers: --> + <xs:element name="openstack_volume_provider" type="OpenStackVolumeProvider"/> + + <xs:complexType name="OpenStackVolumeProvider"> + <xs:complexContent> + <xs:extension base="OpenStackProvider"> + <xs:sequence> + <xs:element ref="data_center" minOccurs="0" maxOccurs="1"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:element name="openstack_volume_providers" type="OpenStackVolumeProviders"/> + + <xs:complexType name="OpenStackVolumeProviders"> + <xs:complexContent> + <xs:extension base="BaseResources"> + <xs:sequence> + <xs:element ref="openstack_volume_provider" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <jaxb:property name="OpenStackVolumeProviders"/> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <!-- OpenStack network providers: --> <xs:element name="openstack_network_provider" type="OpenStackNetworkProvider"/> diff --git a/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata.yaml b/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata.yaml index dd76285..129a994 100644 --- a/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata.yaml +++ b/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata.yaml @@ -6654,6 +6654,97 @@ Content-Type: {value: application/xml|json, required: true} Correlation-Id: {value: 'any string', required: false} +- name: /openstackvolumeproviders|rel=get + description: get the list of all OpenStack volume providers in the system + request: + body: + parameterType: null + signatures: [] + urlparams: + max: {context: matrix, type: 'xs:int', value: 'max results', required: false} + headers: {} +- name: /openstackvolumeproviders/{openstackvolumeprovider:id}|rel=get + description: get the details of the specified OpenStack volume provider in the system + request: + body: + parameterType: null + signatures: [] + urlparams: {} + headers: {} +- name: /openstackvolumeproviders/{openstackvolumeprovider:id}|rel=delete + description: delete the specified OpenStack volume provider in the system + request: + body: + parameterType: null + signatures: [] + urlparams: + async: {context: matrix, type: 'xs:boolean', value: true|false, required: false} + headers: + Correlation-Id: {value: 'any string', required: false} +- name: /openstackvolumeproviders/{openstackvolumeprovider:id}|rel=update + description: update the specified OpenStack volume provider in the system + request: + body: + parameterType: OpenStackVolumeProvider + signatures: + - mandatoryArguments: {} + optionalArguments: + openstack_volume_provider.name: xs:string + openstack_volume_provider.description: xs:string + openstack_volume_provider.data_center.id|name: xs:string, + openstack_volume_provider.requires_authentication: xs:boolean + openstack_volume_provider.username: xs:string + openstack_volume_provider.password: xs:string + openstack_volume_provider.properties.property--COLLECTION: + property.name: xs:string + property.value: xs:string + description: update the specified OpenStack image provider in the system + urlparams: {} + headers: + Content-Type: {value: application/xml|json, required: true} + Correlation-Id: {value: 'any string', required: false} +- name: /openstackvolumeproviders|rel=add + description: add a new OpenStack volume provider to the system + request: + body: + parameterType: OpenStackVolumeProvider + signatures: + - mandatoryArguments: + openstack_image_provider.name: xs:string + optionalArguments: + openstack_volume_provider.description: xs:string + openstack_volume_provider.url: xs:string + openstack_volume_provider.data_center.id|name: xs:string, + openstack_volume_provider.requires_authentication: xs:boolean + openstack_volume_provider.username: xs:string + openstack_volume_provider.password: xs:string + openstack_volume_provider.properties.property--COLLECTION: + property.name: xs:string + property.value: xs:string + description: add a new OpenStack image provider to the system + urlparams: {} + headers: + Content-Type: {value: application/xml|json, required: true} + Expect: {value: 201-created, required: false} + Correlation-Id: {value: 'any string', required: false} +- name: /openstackvolumeproviders/{openstackvolumeprovider:id}/images|rel=get + description: get the list of volumes from the OpenStack image provider + request: + body: + parameterType: null + signatures: [] + urlparams: + max: {context: matrix, type: 'xs:int', value: 'max results', required: false} + headers: {} +- name: /openstackvolumeproviders/{openstackvolumeprovider:id}/images/{image:id}|rel=get + description: get the details of the specified volume from the OpenStack image provider + request: + body: + parameterType: null + signatures: [] + urlparams: {} + headers: {} + - name: /openstacknetworkproviders|rel=get description: get the list of all OpenStack network providers in the system request: diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/BackendApplication.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/BackendApplication.java index 1e8a65c..5cfb24c 100644 --- a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/BackendApplication.java +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/BackendApplication.java @@ -61,6 +61,7 @@ import org.ovirt.engine.api.restapi.resource.externalhostproviders.BackendSystemKatelloErrataResource; import org.ovirt.engine.api.restapi.resource.openstack.BackendOpenStackImageProvidersResource; import org.ovirt.engine.api.restapi.resource.openstack.BackendOpenStackNetworkProvidersResource; +import org.ovirt.engine.api.restapi.resource.openstack.BackendOpenStackVolumeProvidersResource; import org.ovirt.engine.api.restapi.resource.validation.IOExceptionMapper; import org.ovirt.engine.api.restapi.resource.validation.JsonExceptionMapper; import org.ovirt.engine.api.restapi.resource.validation.MalformedIdExceptionMapper; @@ -155,6 +156,7 @@ addResource(new BackendExternalHostProvidersResource()); addResource(new BackendOpenStackImageProvidersResource()); addResource(new BackendOpenStackNetworkProvidersResource()); + addResource(new BackendOpenStackVolumeProvidersResource()); addResource(new BackendSystemKatelloErrataResource()); final SessionProcessor processor = new SessionProcessor(); diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProviderResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProviderResource.java new file mode 100644 index 0000000..7bbe1bd --- /dev/null +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProviderResource.java @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2014 Red Hat, Inc. +* +* Licensed 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 org.ovirt.engine.api.restapi.resource.openstack; + +import org.ovirt.engine.api.model.OpenStackVolumeProvider; +import org.ovirt.engine.api.resource.openstack.OpenStackVolumeProviderResource; +import org.ovirt.engine.api.restapi.resource.AbstractBackendExternalProviderResource; + +import static org.ovirt.engine.api.restapi.resource.openstack.BackendOpenStackVolumeProvidersResource.SUB_COLLECTIONS; + +public class BackendOpenStackVolumeProviderResource + extends AbstractBackendExternalProviderResource<OpenStackVolumeProvider> + implements OpenStackVolumeProviderResource { + public BackendOpenStackVolumeProviderResource(String id) { + super(id, OpenStackVolumeProvider.class, SUB_COLLECTIONS); + } +} diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProvidersResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProvidersResource.java new file mode 100644 index 0000000..ecb0765 --- /dev/null +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProvidersResource.java @@ -0,0 +1,141 @@ +/* +* Copyright (c) 2014 Red Hat, Inc. +* +* Licensed 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 org.ovirt.engine.api.restapi.resource.openstack; + +import org.apache.commons.lang.StringUtils; +import org.ovirt.engine.api.common.util.QueryHelper; +import org.ovirt.engine.api.model.DataCenter; +import org.ovirt.engine.api.model.OpenStackVolumeProvider; +import org.ovirt.engine.api.model.OpenStackVolumeProviders; +import org.ovirt.engine.api.resource.openstack.OpenStackVolumeProviderResource; +import org.ovirt.engine.api.resource.openstack.OpenStackVolumeProvidersResource; +import org.ovirt.engine.api.restapi.resource.AbstractBackendCollectionResource; +import org.ovirt.engine.api.restapi.resource.BackendExternalProviderHelper; +import org.ovirt.engine.api.restapi.resource.SingleEntityResource; +import org.ovirt.engine.api.restapi.types.DataCenterMapper; +import org.ovirt.engine.core.common.action.ProviderParameters; +import org.ovirt.engine.core.common.action.VdcActionType; +import org.ovirt.engine.core.common.businessentities.Provider; +import org.ovirt.engine.core.common.businessentities.ProviderType; +import org.ovirt.engine.core.common.businessentities.StoragePool; +import org.ovirt.engine.core.common.interfaces.SearchType; +import org.ovirt.engine.core.common.queries.GetAllProvidersParameters; +import org.ovirt.engine.core.common.queries.IdQueryParameters; +import org.ovirt.engine.core.common.queries.NameQueryParameters; +import org.ovirt.engine.core.common.queries.VdcQueryType; +import org.ovirt.engine.core.compat.Guid; + +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Response; +import java.util.List; + +public class BackendOpenStackVolumeProvidersResource + extends AbstractBackendCollectionResource<OpenStackVolumeProvider, Provider> + implements OpenStackVolumeProvidersResource { + static final String[] SUB_COLLECTIONS = { + "volumetypes", + "certificates" + }; + + public BackendOpenStackVolumeProvidersResource() { + super(OpenStackVolumeProvider.class, Provider.class, SUB_COLLECTIONS); + } + + @Override + public OpenStackVolumeProviders list() { + return mapCollection(getBackendCollection()); + } + + private OpenStackVolumeProviders mapCollection(List<Provider> entities) { + OpenStackVolumeProviders collection = new OpenStackVolumeProviders(); + for (Provider entity : entities) { + collection.getOpenStackVolumeProviders().add(addLinks(map(entity))); + } + return collection; + } + + private List<Provider> getBackendCollection() { + if (isFiltered()) { + return getBackendCollection( + VdcQueryType.GetAllProviders, + new GetAllProvidersParameters(ProviderType.OPENSTACK_VOLUME) + ); + } + else { + return getBackendCollection(SearchType.Provider, getConstraint()); + } + } + + private String getConstraint() { + StringBuilder buffer = new StringBuilder(); + buffer.append("Providers: type="); + buffer.append(ProviderType.OPENSTACK_VOLUME.name()); + String query = QueryHelper.getConstraint(getUriInfo(), null, modelType, false); + if (StringUtils.isNotBlank(query)) { + buffer.append(" AND ("); + buffer.append(query); + buffer.append(")"); + } + return buffer.toString(); + } + + @Override + public Response add(OpenStackVolumeProvider provider) { + validateParameters(provider, "name", "dataCenter.name|id"); + StoragePool storagePool = getStoragePool(provider.getDataCenter()); + provider.setDataCenter(DataCenterMapper.map(storagePool, null)); + return performCreate( + VdcActionType.AddProvider, + new ProviderParameters(map(provider)), + new QueryIdResolver<Guid>(VdcQueryType.GetProviderById, IdQueryParameters.class) + ); + } + + @Override + protected Response performRemove(String id) { + Provider provider = BackendExternalProviderHelper.getProvider(this, id); + ProviderParameters parameters = new ProviderParameters(provider); + return performAction(VdcActionType.RemoveProvider, parameters); + } + + @Override + protected OpenStackVolumeProvider doPopulate(OpenStackVolumeProvider model, Provider entity) { + return model; + } + + @Override + @SingleEntityResource + public OpenStackVolumeProviderResource getOpenStackVolumeProvider(@PathParam("id") String id) { + return inject(new BackendOpenStackVolumeProviderResource(id)); + } + + public StoragePool getStoragePool(DataCenter dataCenter) { + StoragePool pool = null; + if (dataCenter.isSetId()) { + Guid id = asGuid(dataCenter.getId()); + pool = getEntity(StoragePool.class, VdcQueryType.GetStoragePoolById, + new IdQueryParameters(id), "Datacenter: id=" + dataCenter.getId()); + } else if (dataCenter.isSetName()) { + pool = getEntity(StoragePool.class, VdcQueryType.GetStoragePoolByDatacenterName, + new NameQueryParameters(dataCenter.getName()), "Datacenter: name=" + dataCenter.getName()); + } + if (pool == null) { + notFound(DataCenter.class); + } + return pool; + } +} diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/utils/FeaturesHelper.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/utils/FeaturesHelper.java index a0a0183..eace5e3 100644 --- a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/utils/FeaturesHelper.java +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/utils/FeaturesHelper.java @@ -98,6 +98,7 @@ addErrataForHostsFeature(features); addCumulativeNetworkUsageFeature(features); addGuestMemoryBufferedCached(features); + addOpenStackVolumeProvidersFeature(features); } return features; } @@ -560,4 +561,11 @@ feature.setDescription("Report of used cached and buffered memory in the guest OS"); features.getFeature().add(feature); } + + private void addOpenStackVolumeProvidersFeature(Features features) { + Feature feature = new Feature(); + feature.setName("OpenStack Volume Providers"); + feature.setDescription("Add/modify/remove OpenStack volume providers."); + features.getFeature().add(feature); + } } diff --git a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendApiResourceTest.java b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendApiResourceTest.java index dfa9850..cf72733 100644 --- a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendApiResourceTest.java +++ b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendApiResourceTest.java @@ -130,6 +130,7 @@ "operatingsystems", "externalhostproviders", "openstackimageproviders", + "openstackvolumeproviders", "openstacknetworkproviders", "katelloerrata" }; @@ -197,6 +198,7 @@ BASE_PATH + "/operatingsystems", BASE_PATH + "/externalhostproviders", BASE_PATH + "/openstackimageproviders", + BASE_PATH + "/openstackvolumeproviders", BASE_PATH + "/openstacknetworkproviders", BASE_PATH + "/katelloerrata" }; diff --git a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProviderResourceTest.java b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProviderResourceTest.java new file mode 100644 index 0000000..8abf0fd --- /dev/null +++ b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProviderResourceTest.java @@ -0,0 +1,179 @@ +/* +* Copyright (c) 2014 Red Hat, Inc. +* +* Licensed 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 org.ovirt.engine.api.restapi.resource.openstack; + +import org.junit.Test; +import org.ovirt.engine.api.model.OpenStackVolumeProvider; +import org.ovirt.engine.api.restapi.resource.AbstractBackendSubResourceTest; +import org.ovirt.engine.core.common.action.ProviderParameters; +import org.ovirt.engine.core.common.action.VdcActionType; +import org.ovirt.engine.core.common.businessentities.Provider; +import org.ovirt.engine.core.common.queries.IdQueryParameters; +import org.ovirt.engine.core.common.queries.VdcQueryType; + +import javax.ws.rs.WebApplicationException; + +import static org.easymock.EasyMock.expect; + +public class BackendOpenStackVolumeProviderResourceTest + extends AbstractBackendSubResourceTest<OpenStackVolumeProvider, Provider, BackendOpenStackVolumeProviderResource> { + public BackendOpenStackVolumeProviderResourceTest() { + super(new BackendOpenStackVolumeProviderResource(GUIDS[0].toString())); + } + + @Test + public void testBadGuid() throws Exception { + control.replay(); + try { + new BackendOpenStackVolumeProviderResource("foo"); + fail("expected WebApplicationException"); + } + catch (WebApplicationException wae) { + verifyNotFoundException(wae); + } + } + + @Test + public void testGetNotFound() throws Exception { + setUriInfo(setUpBasicUriExpectations()); + setUpGetEntityExpectations(1, true); + control.replay(); + try { + resource.get(); + fail("expected WebApplicationException"); + } catch (WebApplicationException wae) { + verifyNotFoundException(wae); + } + } + + @Test + public void testGet() throws Exception { + setUriInfo(setUpBasicUriExpectations()); + setUpGetEntityExpectations(1); + control.replay(); + verifyModel(resource.get(), 0); + } + + @Test + public void testUpdateNotFound() throws Exception { + setUriInfo(setUpBasicUriExpectations()); + setUpGetEntityExpectations(1, true); + control.replay(); + try { + resource.update(getModel(0)); + fail("expected WebApplicationException"); + } catch (WebApplicationException wae) { + verifyNotFoundException(wae); + } + } + + @Test + public void testUpdate() throws Exception { + setUpGetEntityExpectations(2); + setUriInfo( + setUpActionExpectations( + VdcActionType.UpdateProvider, + ProviderParameters.class, + new String[] { "Provider.Id" }, + new Object[] { GUIDS[0] }, + true, + true + ) + ); + verifyModel(resource.update(getModel(0)), 0); + } + + @Test + public void testUpdateCantDo() throws Exception { + doTestBadUpdate(false, true, CANT_DO); + } + + @Test + public void testUpdateFailed() throws Exception { + doTestBadUpdate(true, false, FAILURE); + } + + private void doTestBadUpdate(boolean canDo, boolean success, String detail) throws Exception { + setUpGetEntityExpectations(1); + setUriInfo( + setUpActionExpectations( + VdcActionType.UpdateProvider, + ProviderParameters.class, + new String[] { "Provider.Id" }, + new Object[] { GUIDS[0] }, + canDo, + success + ) + ); + try { + resource.update(getModel(0)); + fail("expected WebApplicationException"); + } + catch (WebApplicationException wae) { + verifyFault(wae, detail); + } + } + + @Test + public void testConflictedUpdate() throws Exception { + setUriInfo(setUpBasicUriExpectations()); + setUpGetEntityExpectations(1); + control.replay(); + + OpenStackVolumeProvider model = getModel(1); + model.setId(GUIDS[1].toString()); + try { + resource.update(model); + fail("expected WebApplicationException"); + } + catch (WebApplicationException wae) { + verifyImmutabilityConstraint(wae); + } + } + + private OpenStackVolumeProvider getModel(int index) { + OpenStackVolumeProvider model = new OpenStackVolumeProvider(); + model.setName(NAMES[index]); + model.setDescription(DESCRIPTIONS[index]); + return model; + } + + @Override + protected Provider getEntity(int index) { + Provider provider = control.createMock(Provider.class); + expect(provider.getId()).andReturn(GUIDS[index]).anyTimes(); + expect(provider.getName()).andReturn(NAMES[index]).anyTimes(); + expect(provider.getDescription()).andReturn(DESCRIPTIONS[index]).anyTimes(); + return provider; + } + + protected void setUpGetEntityExpectations(int times) throws Exception { + setUpGetEntityExpectations(times, false); + } + + protected void setUpGetEntityExpectations(int times, boolean notFound) throws Exception { + while (times-- > 0) { + setUpGetEntityExpectations( + VdcQueryType.GetProviderById, + IdQueryParameters.class, + new String[] { "Id" }, + new Object[] { GUIDS[0] }, + notFound? null: getEntity(0) + ); + } + } +} diff --git a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProvidersResourceTest.java b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProvidersResourceTest.java new file mode 100644 index 0000000..6d2fdeb --- /dev/null +++ b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/openstack/BackendOpenStackVolumeProvidersResourceTest.java @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2014 Red Hat, Inc. +* +* Licensed 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 org.ovirt.engine.api.restapi.resource.openstack; + +import org.apache.commons.lang.StringUtils; +import org.ovirt.engine.api.model.OpenStackVolumeProvider; +import org.ovirt.engine.api.restapi.resource.AbstractBackendCollectionResourceTest; +import org.ovirt.engine.core.common.businessentities.Provider; +import org.ovirt.engine.core.common.businessentities.ProviderType; +import org.ovirt.engine.core.common.interfaces.SearchType; + +import java.util.List; + +import static org.easymock.EasyMock.expect; + +public class BackendOpenStackVolumeProvidersResourceTest extends + AbstractBackendCollectionResourceTest<OpenStackVolumeProvider, Provider, BackendOpenStackVolumeProvidersResource> { + + public BackendOpenStackVolumeProvidersResourceTest() { + super( + new BackendOpenStackVolumeProvidersResource(), + SearchType.Provider, + "Providers: type=" + ProviderType.OPENSTACK_VOLUME.name() + ); + } + + @Override + protected List<OpenStackVolumeProvider> getCollection() { + return collection.list().getOpenStackVolumeProviders(); + } + + @Override + protected void setUpQueryExpectations(String query) throws Exception { + if (StringUtils.isNotBlank(query)) { + query = " AND (" + query + ")"; + } + super.setUpQueryExpectations(query); + } + + @Override + protected Provider getEntity(int index) { + Provider provider = control.createMock(Provider.class); + expect(provider.getId()).andReturn(GUIDS[index]).anyTimes(); + expect(provider.getName()).andReturn(NAMES[index]).anyTimes(); + expect(provider.getDescription()).andReturn(DESCRIPTIONS[index]).anyTimes(); + return provider; + } +} diff --git a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/openstack/OpenStackVolumeProviderMapper.java b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/openstack/OpenStackVolumeProviderMapper.java new file mode 100644 index 0000000..23d2ed5 --- /dev/null +++ b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/openstack/OpenStackVolumeProviderMapper.java @@ -0,0 +1,133 @@ +/* +* Copyright (c) 2014 Red Hat, Inc. +* +* Licensed 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 org.ovirt.engine.api.restapi.types.openstack; + +import org.ovirt.engine.api.model.DataCenter; +import org.ovirt.engine.api.model.OpenStackVolumeProvider; +import org.ovirt.engine.api.model.Properties; +import org.ovirt.engine.api.model.Property; +import org.ovirt.engine.api.restapi.types.Mapping; +import org.ovirt.engine.api.restapi.utils.GuidUtils; +import org.ovirt.engine.core.common.businessentities.Provider; +import org.ovirt.engine.core.common.businessentities.ProviderType; +import org.ovirt.engine.core.common.businessentities.storage.OpenStackVolumeProviderProperties; +import org.ovirt.engine.core.compat.Guid; + +import java.util.HashMap; +import java.util.Map; + +public class OpenStackVolumeProviderMapper { + @Mapping(from = OpenStackVolumeProvider.class, to = Provider.class) + public static Provider<OpenStackVolumeProviderProperties> map(OpenStackVolumeProvider model, + Provider<OpenStackVolumeProviderProperties> template) { + Provider<OpenStackVolumeProviderProperties> entity = + template != null? template: new Provider<OpenStackVolumeProviderProperties>(); + entity.setType(ProviderType.OPENSTACK_VOLUME); + if (model.isSetId()) { + entity.setId(GuidUtils.asGuid(model.getId())); + } + if (model.isSetName()) { + entity.setName(model.getName()); + } + if (model.isSetDescription()) { + entity.setDescription(model.getDescription()); + } + if (model.isSetUrl()) { + entity.setUrl(model.getUrl()); + } + if (model.isSetRequiresAuthentication()) { + entity.setRequiringAuthentication(model.isRequiresAuthentication()); + } + if (model.isSetUsername()) { + entity.setUsername(model.getUsername()); + } + if (model.isSetPassword()) { + entity.setPassword(model.getPassword()); + } + if (model.isSetAuthUrl()) { + entity.setAuthUrl(model.getAuthUrl()); + } + if (model.isSetProperties()) { + Map<String, String> map = new HashMap<>(); + for (Property property : model.getProperties().getProperties()) { + map.put(property.getName(), property.getValue()); + } + entity.setCustomProperties(map); + } + OpenStackVolumeProviderProperties additionalProperties = new OpenStackVolumeProviderProperties(); + if (model.isSetTenantName()) { + additionalProperties.setTenantName(model.getTenantName()); + } + if (model.isSetDataCenter()) { + additionalProperties.setStoragePoolId(Guid.createGuidFromString(model.getDataCenter().getId())); + } + entity.setAdditionalProperties(additionalProperties); + return entity; + } + + @Mapping(from = Provider.class, to = OpenStackVolumeProvider.class) + public static OpenStackVolumeProvider map(Provider<OpenStackVolumeProviderProperties> entity, + OpenStackVolumeProvider template) { + OpenStackVolumeProvider model = template != null? template: new OpenStackVolumeProvider(); + if (entity.getId() != null) { + model.setId(entity.getId().toString()); + } + if (entity.getName() != null) { + model.setName(entity.getName()); + } + if (entity.getDescription() != null) { + model.setDescription(entity.getDescription()); + } + if (entity.getUrl() != null) { + model.setUrl(entity.getUrl()); + } + if (entity.getAuthUrl() != null) { + model.setAuthUrl(entity.getAuthUrl()); + } + model.setRequiresAuthentication(entity.isRequiringAuthentication()); + if (entity.getUsername() != null) { + model.setUsername(entity.getUsername()); + } + // The password isn't mapped for security reasons. + // if (entity.getPassword() != null) { + // model.setPassword(entity.getPassword()); + // } + Map<String, String> customProperties = entity.getCustomProperties(); + if (customProperties != null) { + Properties properties = new Properties(); + for (Map.Entry<String, String> entry : customProperties.entrySet()) { + Property property = new Property(); + property.setName(entry.getKey()); + property.setValue(entry.getValue()); + properties.getProperties().add(property); + } + model.setProperties(properties); + } + OpenStackVolumeProviderProperties additionalProperties = entity.getAdditionalProperties(); + if (additionalProperties != null) { + if (additionalProperties.getTenantName() != null) { + model.setTenantName(additionalProperties.getTenantName()); + } + if (additionalProperties.getStoragePoolId() != null) { + DataCenter dataCenter = new DataCenter(); + dataCenter.setId(additionalProperties.getStoragePoolId().toString()); + model.setDataCenter(dataCenter); + } + } + return model; + } +} -- To view, visit https://gerrit.ovirt.org/39003 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I89d2e9d975750d2ec22599079603bd48cff2603e Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Daniel Erez <de...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches