Michael Pasternak has uploaded a new change for review.

Change subject: restapi: add /disks sub-collection to /storagedomain resource
......................................................................

restapi: add /disks sub-collection to /storagedomain resource

- This patch is preparation for the NetApp external cloning integration support,
added new /disks sub-collections under /storagedomain & 
dataceneter/storagedomain,
new URIs are:

/api/storagedomains/{storagedomain:id}/disks|rel=get
/api/storagedomains/{storagedomain:id}/disks/{disk:id}|rel=get
/api/storagedomains/{storagedomain:id}/disks/{disk:id}|rel=delete
/api/storagedomains/{storagedomain:id}/disks|rel=add

/api/datacenters/{datacenter:id}/storagedomains/{storagedomain:id}/disks|rel=get
/api/datacenters/{datacenter:id}/storagedomains/{storagedomain:id}/disks/{disk:id}|rel=get
/api/datacenters/{datacenter:id}/storagedomains/{storagedomain:id}/disks/{disk:id}|rel=delete
/api/datacenters/{datacenter:id}/storagedomains/{storagedomain:id}/disks|rel=add

- 'scan' for yet imported disks will be performed via [1], NetApp will 
implement /import
action on the disk.

[1]
/api/storagedomains/{storagedomain:id}/disks;unregistered|rel=get
/api/datacenters/{datacenter:id}/storagedomains/{storagedomain:id}/disks;unregistered|rel=get

Change-Id: If6c18e5b28e81f13b44e9431efd623a5627379a1
Signed-off-by: Michael Pasternak <[email protected]>
---
M 
backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/LinkHelper.java
M 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AttachedStorageDomainResource.java
M 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/StorageDomainResource.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_v-3.1.yaml
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAttachedStorageDomainResource.java
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAttachedStorageDomainsResource.java
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDisksResource.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDiskResource.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDisksResource.java
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainResource.java
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainsResource.java
A 
backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDiskResourceTest.java
A 
backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDisksResourceTest.java
M 
backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainsResourceTest.java
15 files changed, 516 insertions(+), 11 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/37/10337/1

diff --git 
a/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/LinkHelper.java
 
b/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/LinkHelper.java
index 87b031e..00bc44c 100644
--- 
a/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/LinkHelper.java
+++ 
b/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/LinkHelper.java
@@ -197,6 +197,7 @@
         map = new ParentToCollectionMap(DiskResource.class, 
DisksResource.class);
         map.add(VmDiskResource.class, VmDisksResource.class, VM.class);
         map.add(TemplateDiskResource.class, TemplateDisksResource.class, 
Template.class);
+        map.add(DiskResource.class, DisksResource.class, StorageDomain.class);
         TYPES.put(Disk.class, map);
 
         map = new ParentToCollectionMap(HostResource.class, 
HostsResource.class);
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AttachedStorageDomainResource.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AttachedStorageDomainResource.java
index 826e0ce..efb58d6 100644
--- 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AttachedStorageDomainResource.java
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AttachedStorageDomainResource.java
@@ -52,4 +52,7 @@
     @Actionable
     @Path("deactivate")
     public Response deactivate(Action action);
+
+    @Path("disks")
+    public DisksResource getDisksResource();
 }
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/StorageDomainResource.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/StorageDomainResource.java
index af46570..bf800e9 100644
--- 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/StorageDomainResource.java
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/StorageDomainResource.java
@@ -39,4 +39,7 @@
 
     @Path("files")
     public FilesResource getFilesResource();
+
+    @Path("disks")
+    public DisksResource getDisksResource();
 }
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 967e7b6..2c63af4 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
@@ -2192,6 +2192,8 @@
           <!-- name is deprecated, use alias instead. -->
           <xs:element name="alias" type="xs:string" minOccurs="0" 
maxOccurs="1"/>
           <xs:element name="image_id" type="xs:string" minOccurs="0" 
maxOccurs="1"/>
+          <!-- storage_domain element requiered for back-linking -->
+          <xs:element ref="storage_domain" minOccurs="0" maxOccurs="1"/>
           <xs:element ref="storage_domains" minOccurs="0" maxOccurs="1"/>
           <xs:element name="size" type="xs:long" minOccurs="0"/> <!-- 
Deprecated, replaced by 'provisioned_size' -->
           <xs:element name="type" type="xs:string" minOccurs="0"/> <!-- 
Deprecated, will be removed at 4.0 -->
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata_v-3.1.yaml
 
b/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata_v-3.1.yaml
index cd79e5c..3c28a3c 100644
--- 
a/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata_v-3.1.yaml
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata_v-3.1.yaml
@@ -2690,4 +2690,116 @@
     headers:
       Content-Type: {value: application/xml|json, required: true}
       Correlation-Id: {value: 'any string', required: false}
+- name: /api/storagedomains/{storagedomain:id}/disks|rel=get
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: 
+      search: {context: query, type: 'xs:string', value: query, required: 
false}
+      case_sensitive: {context: matrix, type: 'xs:boolean', value: true|false, 
required: false}
+      max: {context: matrix, type: 'xs:int', value: 'max results', required: 
false}
+    headers: {}
+- name: /api/storagedomains/{storagedomain:id}/disks/{disk:id}|rel=get
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: {}
+    headers: {}
+- name: /api/storagedomains/{storagedomain:id}/disks/{disk:id}|rel=delete
+  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: /api/storagedomains/{storagedomain:id}/disks|rel=add
+  request:
+    body:
+      parameterType: Disk
+      signatures:
+      - mandatoryArguments: {provisioned_size: 'xs:int', disk.interface: 
'xs:string', disk.format: 'xs:string'}
+        optionalArguments:
+          disk.alias: xs:string
+          disk.name: xs:string
+          disk.size: xs:int #deprecated, replaced by 'provisioned_size'
+          disk.sparse: xs:boolean
+          disk.bootable: xs:boolean
+          disk.shareable: xs:boolean
+          disk.propagate_errors: xs:boolean
+          disk.wipe_after_delete: xs:boolean
+        #the signature below is for direct-LUN disk, which doesn't require 
size, but requires the lun id, the lun type, and the lun connection-details.
+      - mandatoryArguments: {disk.interface: 'xs:string', disk.format: 
'xs:string', disk.lun_storage.type: 'xs:string',
+          disk.lun_storage.logical_unit--COLLECTION: {logical_unit.id: 
'xs:string', logical_unit.address: 'xs:string', logical_unit.port: 'xs:int', 
logical_unit.target: 'xs:string'}}
+        optionalArguments:
+          disk.alias: xs:string
+          disk.sparse: xs:boolean
+          disk.bootable: xs:boolean
+          disk.shareable: xs:boolean
+          disk.propagate_errors: xs:boolean
+          disk.wipe_after_delete: xs:boolean
+    urlparams: {}
+    headers:
+      Content-Type: {value: application/xml|json, required: true}
+      Expect: {value: 201-created, required: false}
+      Correlation-Id: {value: 'any string', required: false}
+- name: 
/api/datacenters/{datacenter:id}/storagedomains/{storagedomain:id}/disks|rel=get
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: 
+      search: {context: query, type: 'xs:string', value: query, required: 
false}
+      case_sensitive: {context: matrix, type: 'xs:boolean', value: true|false, 
required: false}
+      max: {context: matrix, type: 'xs:int', value: 'max results', required: 
false}
+    headers: {}
+- name: 
/api/datacenters/{datacenter:id}/storagedomains/{storagedomain:id}/disks/{disk:id}|rel=get
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: {}
+    headers: {}
+- name: 
/api/datacenters/{datacenter:id}/storagedomains/{storagedomain:id}/disks/{disk:id}|rel=delete
+  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: 
/api/datacenters/{datacenter:id}/storagedomains/{storagedomain:id}/disks|rel=add
+  request:
+    body:
+      parameterType: Disk
+      signatures:
+      - mandatoryArguments: {provisioned_size: 'xs:int', disk.interface: 
'xs:string', disk.format: 'xs:string'}
+        optionalArguments:
+          disk.alias: xs:string
+          disk.name: xs:string
+          disk.size: xs:int #deprecated, replaced by 'provisioned_size'
+          disk.sparse: xs:boolean
+          disk.bootable: xs:boolean
+          disk.shareable: xs:boolean
+          disk.propagate_errors: xs:boolean
+          disk.wipe_after_delete: xs:boolean
+        #the signature below is for direct-LUN disk, which doesn't require 
size, but requires the lun id, the lun type, and the lun connection-details.
+      - mandatoryArguments: {disk.interface: 'xs:string', disk.format: 
'xs:string', disk.lun_storage.type: 'xs:string',
+          disk.lun_storage.logical_unit--COLLECTION: {logical_unit.id: 
'xs:string', logical_unit.address: 'xs:string', logical_unit.port: 'xs:int', 
logical_unit.target: 'xs:string'}}
+        optionalArguments:
+          disk.alias: xs:string
+          disk.sparse: xs:boolean
+          disk.bootable: xs:boolean
+          disk.shareable: xs:boolean
+          disk.propagate_errors: xs:boolean
+          disk.wipe_after_delete: xs:boolean
+    urlparams: {}
+    headers:
+      Content-Type: {value: application/xml|json, required: true}
+      Expect: {value: 201-created, required: false}
+      Correlation-Id: {value: 'any string', required: false}
 
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAttachedStorageDomainResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAttachedStorageDomainResource.java
index bdf9ce6..e50b1c5 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAttachedStorageDomainResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAttachedStorageDomainResource.java
@@ -7,6 +7,7 @@
 import org.ovirt.engine.api.model.StorageDomain;
 import org.ovirt.engine.api.resource.ActionResource;
 import org.ovirt.engine.api.resource.AttachedStorageDomainResource;
+import org.ovirt.engine.api.resource.DisksResource;
 import org.ovirt.engine.core.common.action.StorageDomainPoolParametersBase;
 import org.ovirt.engine.core.common.businessentities.storage_domains;
 import 
org.ovirt.engine.core.common.queries.StorageDomainAndPoolQueryParameters;
@@ -20,8 +21,8 @@
 
     protected Guid dataCenterId;
 
-    public BackendAttachedStorageDomainResource(String id, Guid dataCenterId) {
-        super(id, StorageDomain.class, storage_domains.class);
+    public BackendAttachedStorageDomainResource(String id, Guid dataCenterId, 
String... subCollections) {
+        super(id, StorageDomain.class, storage_domains.class, subCollections);
         this.dataCenterId = dataCenterId;
     }
 
@@ -63,4 +64,9 @@
         inject(resource);
         return resource.map(entity, template);
     }
+
+    @Override
+    public DisksResource getDisksResource() {
+        return inject(new BackendStorageDomainDisksResource(asGuid(id), 
subCollections));
+    }
 }
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAttachedStorageDomainsResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAttachedStorageDomainsResource.java
index d55bb5f..43ca8ae 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAttachedStorageDomainsResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAttachedStorageDomainsResource.java
@@ -19,14 +19,18 @@
 import org.ovirt.engine.core.common.queries.VdcQueryType;
 import org.ovirt.engine.core.compat.Guid;
 
+import static 
org.ovirt.engine.api.restapi.resource.BackendStorageDomainResource.isIsoDomain;
+
 public class BackendAttachedStorageDomainsResource
     extends AbstractBackendCollectionResource<StorageDomain, storage_domains>
     implements AttachedStorageDomainsResource {
 
+    static final String[] SUB_COLLECTIONS = { "disks" };
+
     protected Guid dataCenterId;
 
     public BackendAttachedStorageDomainsResource(String dataCenterId) {
-        super(StorageDomain.class, storage_domains.class);
+        super(StorageDomain.class, storage_domains.class, SUB_COLLECTIONS);
         this.dataCenterId = asGuid(dataCenterId);
     }
 
@@ -37,7 +41,7 @@
         for (storage_domains entity : 
getBackendCollection(storage_domains.class,
                                                            
VdcQueryType.GetStorageDomainsByStoragePoolId,
                                                            new 
StoragePoolQueryParametersBase(dataCenterId))) {
-            storageDomains.getStorageDomains().add(addLinks(map(entity)));
+            storageDomains.getStorageDomains().add(addLinks(map(entity), 
getLinksToExclude(entity)));
         }
 
         return storageDomains;
@@ -46,7 +50,7 @@
     @Override
     @SingleEntityResource
     public AttachedStorageDomainResource 
getAttachedStorageDomainSubResource(String id) {
-        return inject(new BackendAttachedStorageDomainResource(id, 
dataCenterId));
+        return inject(new BackendAttachedStorageDomainResource(id, 
dataCenterId, SUB_COLLECTIONS));
     }
 
     @Override
@@ -119,4 +123,10 @@
         inject(resource);
         return resource.map(entity, template);
     }
+
+    public String[] getLinksToExclude(storage_domains storageDomain) {
+        return isIsoDomain(storageDomain) ? new String[] { "disks" }
+                                            :
+                                            new String[] {};
+    }
 }
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDisksResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDisksResource.java
index 612bb6d..1ca3a24 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDisksResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDisksResource.java
@@ -94,13 +94,13 @@
 
     @Override
     protected Response performRemove(String id) {
-        return performAction(VdcActionType.RemoveDisk, new 
RemoveDiskParameters(Guid.createGuidFromString(id)));
+        return performAction(VdcActionType.RemoveDisk, new 
RemoveDiskParameters(asGuid(id)));
     }
 
     protected Disks 
mapCollection(List<org.ovirt.engine.core.common.businessentities.Disk> 
entities) {
         Disks collection = new Disks();
         for (org.ovirt.engine.core.common.businessentities.Disk disk : 
entities) {
-            collection.getDisks().add(addLinks(map(disk)));
+            collection.getDisks().add(addLinks(populate(map(disk), disk)));
         }
         return collection;
     }
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDiskResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDiskResource.java
new file mode 100644
index 0000000..0b97200
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDiskResource.java
@@ -0,0 +1,41 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import org.ovirt.engine.api.model.Disk;
+import org.ovirt.engine.api.model.StorageDomain;
+import org.ovirt.engine.core.common.queries.GetDiskByDiskIdParameters;
+import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
+
+public class BackendStorageDomainDiskResource extends BackendDiskResource {
+
+    final private String storageDomainId;;
+
+    protected BackendStorageDomainDiskResource(String id, String 
storageDomainId) {
+        super(id);
+        this.storageDomainId = storageDomainId;
+    }
+
+    @Override
+    protected Disk performGet(VdcQueryType query, VdcQueryParametersBase 
params) {
+        Disk disk = super.performGet(VdcQueryType.GetDiskByDiskId, new 
GetDiskByDiskIdParameters(guid));
+        if (disk.isSetStorageDomains() && 
!disk.getStorageDomains().getStorageDomains().isEmpty()) {
+            for (StorageDomain sd : 
disk.getStorageDomains().getStorageDomains()) {
+                if (sd.isSetId() && sd.getId().equals(this.storageDomainId)) {
+                    return disk;
+                }
+            }
+        }
+        return notFound();
+    }
+
+    @Override
+    protected Disk populate(Disk model, 
org.ovirt.engine.core.common.businessentities.Disk entity) {
+        Disk populatedDisk = super.populate(model, entity);
+
+        // this code generates back-link to the corresponding SD
+        populatedDisk.setStorageDomain(new StorageDomain());
+        populatedDisk.getStorageDomain().setId(this.storageDomainId);
+
+        return model;
+    }
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDisksResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDisksResource.java
new file mode 100644
index 0000000..a6b0bdb
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDisksResource.java
@@ -0,0 +1,76 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import javax.ws.rs.core.Response;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.ovirt.engine.api.common.util.QueryHelper;
+import org.ovirt.engine.api.model.Disk;
+import org.ovirt.engine.api.model.Disks;
+import org.ovirt.engine.api.model.StorageDomain;
+import org.ovirt.engine.api.resource.DiskResource;
+import org.ovirt.engine.core.common.action.AddDiskParameters;
+import org.ovirt.engine.core.common.action.RemoveDiskParameters;
+import org.ovirt.engine.core.common.action.VdcActionType;
+import org.ovirt.engine.core.common.queries.GetDiskByDiskIdParameters;
+import org.ovirt.engine.core.common.queries.StorageDomainQueryParametersBase;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
+import org.ovirt.engine.core.compat.Guid;
+
+
+public class BackendStorageDomainDisksResource extends BackendDisksResource {
+
+    public static final String UNREGISTERED_CONSTRAINT_PARAMETER = 
"unregistered";
+
+    Guid storageDomainId;
+
+    public BackendStorageDomainDisksResource(Guid storageDomainId, String... 
subCollections) {
+        super();
+        this.storageDomainId = storageDomainId;
+    }
+
+    @Override
+    public Disks list() {
+        if (QueryHelper.hasMatrixParam(getUriInfo(), 
UNREGISTERED_CONSTRAINT_PARAMETER)) {
+            // TODO: add "unregistered" disks lookup
+            throw new NotImplementedException("\"unregistered\" disks lookup 
yet not implemented.");
+        } else {
+            return 
mapCollection(getBackendCollection(VdcQueryType.GetAllDisksByStorageDomainId,
+                    new 
StorageDomainQueryParametersBase(this.storageDomainId)));
+        }
+    }
+
+    @Override
+    public Response add(Disk disk) {
+        validateDiskForCreation(disk);
+        AddDiskParameters params = new AddDiskParameters();
+        params.setDiskInfo(getMapper(Disk.class,
+                                     
org.ovirt.engine.core.common.businessentities.Disk.class)
+                           .map(disk, null));
+        params.setStorageDomainId(this.storageDomainId);
+        return performCreation(VdcActionType.AddDisk, params,
+                new QueryIdResolver(VdcQueryType.GetDiskByDiskId, 
GetDiskByDiskIdParameters.class));
+    }
+
+    @Override
+    protected Response performRemove(String id) {
+        RemoveDiskParameters params = new RemoveDiskParameters(asGuid(id));
+        params.setStorageDomainId(this.storageDomainId);
+        return performAction(VdcActionType.RemoveDisk, params);
+    }
+
+    @Override
+    public DiskResource getDeviceSubResource(String id) {
+        return inject(new BackendStorageDomainDiskResource(id, 
this.storageDomainId.toString()));
+    }
+
+    @Override
+    protected Disk populate(Disk model, 
org.ovirt.engine.core.common.businessentities.Disk entity) {
+        Disk populatedDisk = super.populate(model, entity);
+
+        // this code generates back-link to the corresponding SD
+        populatedDisk.setStorageDomain(new StorageDomain());
+        
populatedDisk.getStorageDomain().setId(this.storageDomainId.toString());
+
+        return model;
+    }
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainResource.java
index bc0999d..ded82fd 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainResource.java
@@ -15,6 +15,7 @@
 import org.ovirt.engine.api.model.VM;
 import org.ovirt.engine.api.model.VMs;
 import org.ovirt.engine.api.resource.AssignedPermissionsResource;
+import org.ovirt.engine.api.resource.DisksResource;
 import org.ovirt.engine.api.resource.RemovableStorageDomainContentsResource;
 import org.ovirt.engine.api.resource.FilesResource;
 import org.ovirt.engine.api.resource.StorageDomainResource;
@@ -108,7 +109,7 @@
     }
 
     public static synchronized String[] getLinksToExclude(StorageDomain 
storageDomain) {
-        return isIsoDomain(storageDomain) ? new String[]{"templates", "vms"}
+        return isIsoDomain(storageDomain) ? new String[] { "templates", "vms", 
"disks" }
                                             :
                                             isExportDomain(storageDomain) ? 
new String[]{"files"}
                                                                             :
@@ -257,4 +258,9 @@
     public RemovableStorageDomainContentsResource<VMs, VM> 
getStorageDomainVmsResource() {
         return inject(new BackendStorageDomainVmsResource(guid));
     }
+
+    @Override
+    public DisksResource getDisksResource() {
+        return inject(new BackendStorageDomainDisksResource(guid));
+    }
 }
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainsResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainsResource.java
index 3fbf29d..cee3925 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainsResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainsResource.java
@@ -49,7 +49,7 @@
     extends AbstractBackendCollectionResource<StorageDomain, storage_domains>
     implements StorageDomainsResource {
 
-    static final String[] SUB_COLLECTIONS = { "permissions", "files", 
"templates", "vms"};
+    static final String[] SUB_COLLECTIONS = { "permissions", "files", 
"templates", "vms", "disks" };
 
     private StorageDomain storageDomain = null; //utility variable; used in 
the context of a single activation of remove()
 
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDiskResourceTest.java
 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDiskResourceTest.java
new file mode 100644
index 0000000..8a7427f
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDiskResourceTest.java
@@ -0,0 +1,77 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import org.junit.Test;
+import org.ovirt.engine.api.model.Disk;
+import org.ovirt.engine.core.common.businessentities.DiskImage;
+import org.ovirt.engine.core.common.businessentities.DiskInterface;
+import org.ovirt.engine.core.common.businessentities.ImageStatus;
+import org.ovirt.engine.core.common.businessentities.PropagateErrors;
+import org.ovirt.engine.core.common.businessentities.VolumeFormat;
+import org.ovirt.engine.core.common.businessentities.VolumeType;
+import org.ovirt.engine.core.common.queries.GetDiskByDiskIdParameters;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
+import org.ovirt.engine.core.compat.Guid;
+
+public class BackendStorageDomainDiskResourceTest extends 
AbstractBackendSubResourceTest<Disk, 
org.ovirt.engine.core.common.businessentities.Disk, BackendDiskResource> {
+
+    protected static final Guid DISK_ID = GUIDS[1];
+
+    protected static BackendVmDisksResource collection;
+
+    public BackendStorageDomainDiskResourceTest() {
+        super(new BackendDiskResource(DISK_ID.toString()));
+    }
+
+    @Test
+    public void testGet() {
+        setUriInfo(setUpBasicUriExpectations());
+        setUpEntityQueryExpectations(
+                VdcQueryType.GetDiskByDiskId,
+                GetDiskByDiskIdParameters.class,
+                new String[]{"DiskId"},
+                new Object[]{DISK_ID},
+                getEntity(1));
+        control.replay();
+
+        Disk disk = resource.get();
+        verifyModelSpecific(disk, 1);
+        verifyLinks(disk);
+    }
+
+    @Override
+    protected org.ovirt.engine.core.common.businessentities.Disk getEntity(int 
index) {
+        DiskImage entity = new DiskImage();
+        entity.setId(GUIDS[index]);
+        entity.setvolume_format(VolumeFormat.RAW);
+        entity.setDiskInterface(DiskInterface.VirtIO);
+        entity.setimageStatus(ImageStatus.OK);
+        entity.setvolume_type(VolumeType.Sparse);
+        entity.setBoot(false);
+        entity.setShareable(false);
+        entity.setPropagateErrors(PropagateErrors.On);
+        return setUpStatisticalEntityExpectations(entity);
+    }
+    static org.ovirt.engine.core.common.businessentities.Disk 
setUpStatisticalEntityExpectations(DiskImage entity) {
+        entity.setread_rate(1);
+        entity.setwrite_rate(2);
+        entity.setReadLatency(3.0);
+        entity.setWriteLatency(4.0);
+        entity.setFlushLatency(5.0);
+        return entity;
+    }
+
+    @Override
+    protected void verifyModel(Disk model, int index) {
+        verifyModelSpecific(model, index);
+        verifyLinks(model);
+    }
+
+    static void verifyModelSpecific(Disk model, int index) {
+        assertEquals(GUIDS[index].toString(), model.getId());
+        assertFalse(model.isSetVm());
+        assertTrue(model.isSparse());
+        assertTrue(!model.isBootable());
+        assertTrue(model.isPropagateErrors());
+    }
+
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDisksResourceTest.java
 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDisksResourceTest.java
new file mode 100644
index 0000000..ed83fac
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainDisksResourceTest.java
@@ -0,0 +1,168 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.ws.rs.core.Response;
+
+import org.junit.Test;
+import org.ovirt.engine.api.model.Disk;
+import org.ovirt.engine.api.model.DiskFormat;
+import org.ovirt.engine.api.model.StorageDomain;
+import org.ovirt.engine.api.model.StorageDomains;
+import org.ovirt.engine.core.common.action.AddDiskParameters;
+import org.ovirt.engine.core.common.action.VdcActionType;
+import org.ovirt.engine.core.common.businessentities.AsyncTaskStatus;
+import org.ovirt.engine.core.common.businessentities.AsyncTaskStatusEnum;
+import org.ovirt.engine.core.common.businessentities.DiskImage;
+import org.ovirt.engine.core.common.businessentities.DiskInterface;
+import org.ovirt.engine.core.common.businessentities.ImageStatus;
+import org.ovirt.engine.core.common.businessentities.PropagateErrors;
+import org.ovirt.engine.core.common.businessentities.VolumeFormat;
+import org.ovirt.engine.core.common.businessentities.VolumeType;
+import org.ovirt.engine.core.common.businessentities.storage_domains;
+import org.ovirt.engine.core.common.interfaces.SearchType;
+import org.ovirt.engine.core.common.queries.GetDiskByDiskIdParameters;
+import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
+
+public class BackendStorageDomainDisksResourceTest extends 
AbstractBackendCollectionResourceTest<Disk, 
org.ovirt.engine.core.common.businessentities.Disk, BackendDisksResource> {
+
+    public BackendStorageDomainDisksResourceTest() {
+        super(new BackendDisksResource(), SearchType.Disk, "Disks : ");
+    }
+
+    @Override
+    protected List<Disk> getCollection() {
+        return collection.list().getDisks();
+    }
+
+    @Override
+    protected org.ovirt.engine.core.common.businessentities.Disk getEntity(int 
index) {
+        DiskImage entity = new DiskImage();
+        entity.setId(GUIDS[index]);
+        entity.setvolume_format(VolumeFormat.RAW);
+        entity.setDiskInterface(DiskInterface.VirtIO);
+        entity.setimageStatus(ImageStatus.OK);
+        entity.setvolume_type(VolumeType.Sparse);
+        entity.setBoot(false);
+        entity.setShareable(false);
+        entity.setPropagateErrors(PropagateErrors.On);
+        return setUpStatisticalEntityExpectations(entity);    }
+
+    static org.ovirt.engine.core.common.businessentities.Disk 
setUpStatisticalEntityExpectations(DiskImage entity) {
+        entity.setread_rate(1);
+        entity.setwrite_rate(2);
+        entity.setReadLatency(3.0);
+        entity.setWriteLatency(4.0);
+        entity.setFlushLatency(5.0);
+        return entity;
+    }
+
+    @Test
+    public void testAdd() throws Exception {
+        setUriInfo(setUpBasicUriExpectations());
+        setUpHttpHeaderExpectations("Expect", "201-created");
+        setUpEntityQueryExpectations(VdcQueryType.GetDiskByDiskId,
+                GetDiskByDiskIdParameters.class,
+                new String[] { "DiskId" },
+                new Object[] { GUIDS[0] },
+                getEntity(0));
+        Disk model = getModel(0);
+        setUpCreationExpectations(VdcActionType.AddDisk,
+                AddDiskParameters.class,
+                new String[] {"StorageDomainId"},
+                new Object[] {GUIDS[2]},
+                true,
+                true,
+                GUIDS[0],
+                asList(GUIDS[3]),
+                asList(new AsyncTaskStatus(AsyncTaskStatusEnum.finished)),
+                VdcQueryType.GetDiskByDiskId,
+                GetDiskByDiskIdParameters.class,
+                new String[] {"DiskId"},
+                new Object[] {GUIDS[0]},
+                getEntity(0));
+        Response response = collection.add(model);
+        assertEquals(201, response.getStatus());
+        assertTrue(response.getEntity() instanceof Disk);
+        verifyModel((Disk)response.getEntity(), 0);
+        assertNull(((Disk)response.getEntity()).getCreationStatus());
+    }
+
+    @Test
+    public void testAddIdentifyStorageDomainByName() throws Exception {
+        setUriInfo(setUpBasicUriExpectations());
+        setUpHttpHeaderExpectations("Expect", "201-created");
+        setUpEntityQueryExpectations(VdcQueryType.GetDiskByDiskId,
+                GetDiskByDiskIdParameters.class,
+                new String[] { "DiskId" },
+                new Object[] { GUIDS[0] },
+                getEntity(0));
+        Disk model = getModel(0);
+        model.getStorageDomains().getStorageDomains().get(0).setId(null);
+        
model.getStorageDomains().getStorageDomains().get(0).setName("Storage_Domain_1");
+        setUpEntityQueryExpectations(VdcQueryType.GetAllStorageDomains,
+                VdcQueryParametersBase.class,
+                new String[] {},
+                new Object[] {},
+                getStorageDomains());
+        setUpCreationExpectations(VdcActionType.AddDisk,
+                AddDiskParameters.class,
+                new String[] {},
+                new Object[] {},
+                true,
+                true,
+                GUIDS[0],
+                asList(GUIDS[3]),
+                asList(new AsyncTaskStatus(AsyncTaskStatusEnum.finished)),
+                VdcQueryType.GetDiskByDiskId,
+                GetDiskByDiskIdParameters.class,
+                new String[] {"DiskId"},
+                new Object[] {GUIDS[0]},
+                getEntity(0));
+        Response response = collection.add(model);
+        assertEquals(201, response.getStatus());
+        assertTrue(response.getEntity() instanceof Disk);
+        verifyModel((Disk)response.getEntity(), 0);
+        assertNull(((Disk)response.getEntity()).getCreationStatus());
+    }
+
+    private Object getStorageDomains() {
+        List<storage_domains> sds = new LinkedList<storage_domains>();
+        storage_domains sd = new storage_domains();
+        sd.setstorage_name("Storage_Domain_1");
+        sd.setId(GUIDS[2]);
+        sds.add(sd);
+        return sds;
+    }
+
+    static Disk getModel(int index) {
+        Disk model = new Disk();
+        model.setSize(1024 * 1024L);
+        model.setFormat(DiskFormat.COW.value());
+        
model.setInterface(org.ovirt.engine.api.model.DiskInterface.IDE.value());
+        model.setSparse(true);
+        model.setBootable(false);
+        model.setShareable(false);
+        model.setPropagateErrors(true);
+        model.setStorageDomains(new StorageDomains());
+        model.getStorageDomains().getStorageDomains().add(new StorageDomain());
+        
model.getStorageDomains().getStorageDomains().get(0).setId(GUIDS[2].toString());
+        return model;
+    }
+
+    @Override
+    protected void verifyModel(Disk model, int index) {
+        verifyModelSpecific(model, index);
+        verifyLinks(model);
+    }
+
+    static void verifyModelSpecific(Disk model, int index) {
+        assertEquals(GUIDS[index].toString(), model.getId());
+        assertFalse(model.isSetVm());
+        assertTrue(model.isSparse());
+        assertTrue(!model.isBootable());
+        assertTrue(model.isPropagateErrors());
+    }
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainsResourceTest.java
 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainsResourceTest.java
index 4bca4d1..6bce3ee 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainsResourceTest.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendStorageDomainsResourceTest.java
@@ -735,7 +735,7 @@
             assertEquals("files", model.getLinks().get(1).getRel());
 
         } else if(model.getType().equals(TYPES[2].value())){
-            assertEquals(3, model.getLinks().size());
+            assertEquals(4, model.getLinks().size());
             assertEquals("templates", model.getLinks().get(1).getRel());
             assertEquals("vms", model.getLinks().get(2).getRel());
         }
@@ -771,7 +771,7 @@
         assertEquals(TARGET, 
model.getStorage().getVolumeGroup().getLogicalUnits().get(0).getTarget());
         assertEquals(ADDRESSES[0], 
model.getStorage().getVolumeGroup().getLogicalUnits().get(0).getAddress());
         assertEquals(PORT, 
model.getStorage().getVolumeGroup().getLogicalUnits().get(0).getPort());
-        assertEquals(1, model.getLinks().size());
+        assertEquals(2, model.getLinks().size());
         assertEquals("permissions", model.getLinks().get(0).getRel());
         assertNotNull(model.getLinks().get(0).getHref());
         verifyLinks(model);


--
To view, visit http://gerrit.ovirt.org/10337
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: If6c18e5b28e81f13b44e9431efd623a5627379a1
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Michael Pasternak <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to