Hello Sergey Gotliv,

I'd like you to do a code review.  Please visit

    http://gerrit.ovirt.org/31750

to review the following change.

Change subject: tapi: Add REST API support for iSCSI multipathing
......................................................................

tapi: Add REST API support for iSCSI multipathing

Enable getting, creating, updating and removing iSCSI Bonds through REST
API including adding/removing a storage target (Engine term is storage
connection is a little bit misleading) and adding/removing a logical
network.
In case of storage target and network the "add" acts more like
"attach" because its adding an already existing target or/and network to
the iscsi bond.
Usages:
Creating a new iSCSI Bond:
POST /api/datacenters/{datacenter_id}/iscsibonds HTTP/1.1
Accept: application/xml
Content-type: application/xml
<iscsi_bond>
  <name>fromRest</name>
  <storage_connections>
    <storage_connection id={storageconnection_id} />
    ....
  </storage_connections>
  <networks>
    <network id={network_id} />
    ....
  </networks>
</iscsi_bond>
Updating an iSCSI Bond, only name and description can be editing that
way:
PUT /api/datacenters/{datacenter_id}/iscsibonds/{iscsibond_id}  HTTP/1.1
Accept: application/xml
Content-type: application/xml
<iscsi_bond>
        <name>{name}</name>
        <description>{description}</description>
</iscsi_bond>
Removing an iSCSI Bond:
DELETE /api/datacenters/{datacenter_id}/iscsibonds/{iscsibond_id}
HTTP/1.1
Getting all iSCSI Bonds for the specified datacenter:
GET /api/datacenters/{datacenter_id}/iscsibonds HTTP/1.1
Accept: application/xml
Content-type: application/xml
Change-Id: Id8881110cbeb163e9fc09e98bf4497d894f40490
Signed-off-by: Maor Lipchuk <[email protected]>
Signed-off-by: Sergey Gotliv <[email protected]>
---
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetIscsiBondByIdQuery.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetNetworksByIscsiBondIdQuery.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetStorageServerConnectionByIscsiBondIdQuery.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AddIscsiBondCommand.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/AddIscsiBondParameters.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/interfaces/SearchType.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
M 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/DataCenterResource.java
A 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/IscsiBondResource.java
A 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/IscsiBondsResource.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/resource/BackendDataCenterResource.java
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCentersResource.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworkResource.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworksResource.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondResource.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondStorageConnectionsResource.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondStorageServerConnection.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondsResource.java
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/utils/FeaturesHelper.java
A 
backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworkResourceTest.java
A 
backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworksResourceTest.java
A 
backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondsResourceTest.java
A 
backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/IscsiBondMapper.java
A 
backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/IscsiBondMapperTest.java
27 files changed, 1,138 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/50/31750/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetIscsiBondByIdQuery.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetIscsiBondByIdQuery.java
new file mode 100644
index 0000000..0d91197
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetIscsiBondByIdQuery.java
@@ -0,0 +1,15 @@
+package org.ovirt.engine.core.bll;
+
+import org.ovirt.engine.core.common.queries.IdQueryParameters;
+
+public class GetIscsiBondByIdQuery <P extends IdQueryParameters> extends 
QueriesCommandBase<P> {
+
+    public GetIscsiBondByIdQuery(P parameters) {
+        super(parameters);
+    }
+
+    @Override
+    protected void executeQueryCommand() {
+        
getQueryReturnValue().setReturnValue(getDbFacade().getIscsiBondDao().get(getParameters().getId()));
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetNetworksByIscsiBondIdQuery.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetNetworksByIscsiBondIdQuery.java
new file mode 100644
index 0000000..8d372b5
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetNetworksByIscsiBondIdQuery.java
@@ -0,0 +1,30 @@
+package org.ovirt.engine.core.bll;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.ovirt.engine.core.common.businessentities.network.Network;
+import org.ovirt.engine.core.common.queries.IdQueryParameters;
+import org.ovirt.engine.core.compat.Guid;
+
+public class GetNetworksByIscsiBondIdQuery<P extends IdQueryParameters> 
extends QueriesCommandBase<P> {
+
+    public GetNetworksByIscsiBondIdQuery(P parameters) {
+        super(parameters);
+    }
+
+    @Override
+    protected void executeQueryCommand() {
+        List<Network> networks = new ArrayList<>();
+
+        for (Guid id : getNetworksIds()) {
+            networks.add(getDbFacade().getNetworkDao().get(id));
+        }
+
+        getQueryReturnValue().setReturnValue(networks);
+    }
+
+    private List<Guid> getNetworksIds() {
+        return 
getDbFacade().getIscsiBondDao().getNetworkIdsByIscsiBondId(getParameters().getId());
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetStorageServerConnectionByIscsiBondIdQuery.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetStorageServerConnectionByIscsiBondIdQuery.java
new file mode 100644
index 0000000..ac549be
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetStorageServerConnectionByIscsiBondIdQuery.java
@@ -0,0 +1,29 @@
+package org.ovirt.engine.core.bll;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.ovirt.engine.core.common.businessentities.StorageServerConnections;
+import org.ovirt.engine.core.common.queries.IdQueryParameters;
+
+public class GetStorageServerConnectionByIscsiBondIdQuery<P extends 
IdQueryParameters> extends QueriesCommandBase<P> {
+
+    public GetStorageServerConnectionByIscsiBondIdQuery(P parameters) {
+        super(parameters);
+    }
+
+    @Override
+    protected void executeQueryCommand() {
+        List<StorageServerConnections> conns = new ArrayList<>();
+
+        for (String id : getConnectionsIds()) {
+            conns.add(getDbFacade().getStorageServerConnectionDao().get(id));
+        }
+
+        getQueryReturnValue().setReturnValue(conns);
+    }
+
+    private List<String> getConnectionsIds() {
+        return 
getDbFacade().getIscsiBondDao().getStorageConnectionIdsByIscsiBondId(getParameters().getId());
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AddIscsiBondCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AddIscsiBondCommand.java
index 123d430..13958c4 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AddIscsiBondCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AddIscsiBondCommand.java
@@ -57,6 +57,7 @@
                     
getDbFacade().getIscsiBondDao().addStorageConnectionToIscsiBond(iscsiBond.getId(),
 connectionId);
                 }
 
+                getReturnValue().setActionReturnValue(iscsiBond.getId());
                 return null;
             }
         });
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/AddIscsiBondParameters.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/AddIscsiBondParameters.java
index e9f242b..800b7a8 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/AddIscsiBondParameters.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/AddIscsiBondParameters.java
@@ -21,4 +21,5 @@
     public IscsiBond getIscsiBond() {
         return iscsiBond;
     }
+
 }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/interfaces/SearchType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/interfaces/SearchType.java
index 1caed3f..aae9e02 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/interfaces/SearchType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/interfaces/SearchType.java
@@ -19,6 +19,7 @@
     Disk,
     GlusterVolume,
     Network,
+    IscsiBond,
     Provider,
     InstanceType,
     ImageType;
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
index 92d673a..8490f69 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
@@ -267,6 +267,9 @@
     GetPermittedStorageDomainsByStoragePoolId(VdcQueryAuthType.User),
     GetIscsiBondsByStoragePoolId,
     GetStorageTypesInPoolByPoolId,
+    GetIscsiBondById,
+    GetStorageServerConnectionByIscsiBondId,
+    GetNetworksByIscsiBondId,
 
     // Event Notification
     GetEventSubscribersBySubscriberIdGrouped,
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/DataCenterResource.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/DataCenterResource.java
index bb0970d..45275da 100644
--- 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/DataCenterResource.java
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/DataCenterResource.java
@@ -38,4 +38,7 @@
 
     @Path("quotas")
     public QuotasResource getQuotasResource();
+
+    @Path("iscsibonds")
+    public IscsiBondsResource getIscsiBondsResource();
 }
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/IscsiBondResource.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/IscsiBondResource.java
new file mode 100644
index 0000000..8805508
--- /dev/null
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/IscsiBondResource.java
@@ -0,0 +1,16 @@
+package org.ovirt.engine.api.resource;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
+import org.ovirt.engine.api.model.IscsiBond;
+
+@Produces({ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, 
ApiMediaType.APPLICATION_X_YAML})
+public interface IscsiBondResource extends UpdatableResource<IscsiBond> {
+
+    @Path("networks")
+    public NetworksResource getNetworksResource();
+
+    @Path("storageconnections")
+    public StorageServerConnectionsResource 
getStorageServerConnectionsResource();
+}
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/IscsiBondsResource.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/IscsiBondsResource.java
new file mode 100644
index 0000000..5957dcf
--- /dev/null
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/IscsiBondsResource.java
@@ -0,0 +1,31 @@
+package org.ovirt.engine.api.resource;
+
+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;
+
+import org.ovirt.engine.api.model.IscsiBond;
+import org.ovirt.engine.api.model.IscsiBonds;
+
+@Produces({ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, 
ApiMediaType.APPLICATION_X_YAML})
+public interface IscsiBondsResource {
+
+    @GET
+    public IscsiBonds list();
+
+    @POST
+    @Consumes({ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, 
ApiMediaType.APPLICATION_X_YAML})
+    public Response add(IscsiBond iscsiBond);
+
+    @DELETE
+    @Path("{id}")
+    public Response remove(@PathParam("id") String id);
+
+    @Path("{id}")
+    public IscsiBondResource getIscsiBondSubResource(@PathParam("id") String 
id);
+}
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 5b669dd..9995beb 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
@@ -55,6 +55,7 @@
 import org.ovirt.engine.api.model.HostNIC;
 import org.ovirt.engine.api.model.Image;
 import org.ovirt.engine.api.model.InstanceType;
+import org.ovirt.engine.api.model.IscsiBond;
 import org.ovirt.engine.api.model.Job;
 import org.ovirt.engine.api.model.Label;
 import org.ovirt.engine.api.model.Link;
@@ -135,6 +136,8 @@
 import org.ovirt.engine.api.resource.ImagesResource;
 import org.ovirt.engine.api.resource.InstanceTypeResource;
 import org.ovirt.engine.api.resource.InstanceTypesResource;
+import org.ovirt.engine.api.resource.IscsiBondResource;
+import org.ovirt.engine.api.resource.IscsiBondsResource;
 import org.ovirt.engine.api.resource.JobResource;
 import org.ovirt.engine.api.resource.JobsResource;
 import org.ovirt.engine.api.resource.LabelResource;
@@ -449,6 +452,8 @@
         map = new ParentToCollectionMap(BalanceResource.class, 
BalancesResource.class, SchedulingPolicy.class);
         TYPES.put(Balance.class, map);
 
+        map = new ParentToCollectionMap(IscsiBondResource.class, 
IscsiBondsResource.class, DataCenter.class);
+        TYPES.put(IscsiBond.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 9303a366..d875063 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
@@ -4633,4 +4633,35 @@
     <xs:attribute name="socket" type="xs:int" use="optional"/>
   </xs:complexType>
 
+  <xs:complexType name="IscsiBond">
+    <xs:complexContent>
+      <xs:extension base="BaseResource">
+        <xs:sequence>
+          <xs:element ref="data_center" minOccurs="0" maxOccurs="1" />
+          <xs:element ref="storage_connections" minOccurs="1" maxOccurs="1" />
+          <xs:element ref="networks" minOccurs="1" maxOccurs="1" />
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <xs:complexType name="IscsiBonds">
+    <xs:complexContent>
+      <xs:extension base="BaseResources">
+        <xs:sequence>
+          <xs:annotation>
+            <xs:appinfo>
+              <jaxb:property name="IscsiBonds" />
+            </xs:appinfo>
+          </xs:annotation>
+  <xs:element ref="iscsi_bond" minOccurs="0" maxOccurs="unbounded" />
+  </xs:sequence>
+  </xs:extension>
+  </xs:complexContent>
+  </xs:complexType>
+
+  <xs:element name="iscsi_bond" type="IscsiBond"/>
+
+  <xs:element name="iscsi_bonds" type="IscsiBonds"/>
+>>>>>>> restapi: Add REST API support for iSCSI multipathing
 </xs:schema>
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 f4cc4fd..329e65b 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
@@ -5518,3 +5518,93 @@
       Content-Type: {value: application/xml|json, required: true}
       Expect: {value: 201-created, required: false}
       Correlation-Id: {value: 'any string', required: false}
+- name: /datacenters/{datacenter:id}/iscsibonds|rel=get
+  description: get all iSCSI Bonds for the specified datacenter
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: {}
+    headers: {}
+- name: /datacenters/{datacenter:id}/iscsibonds|rel=add
+  description: add a new iSCSI Bond to the specified datacenter
+  request:
+    body:
+      parameterType: IscsiBond
+      signatures:
+      - mandatoryArguments: {iscsibond.name: 'xs:string'}
+        optionalArguments: {}
+        description: add a new iSCSI Bond to the datacenter
+    urlparams: {}
+    headers:
+      Content-Type: {value: application/xml|json, required: true}
+      Expect: {value: 201-created, required: false}
+- name: /datacenters/{datacenter:id}/iscsibonds/{iscsibond:id}|rel=update
+  description: update the specified iSCSI Bond
+  request:
+    body:
+     parameterType: IscsiBond
+     signatures:
+     - mandatoryArguments: {}
+       optionalArguments: {}
+       description: update the specified iSCSI Bond
+    urlparams: {}
+    headers:
+      Content-Type: {value: application/xml|json, required: true}
+      Expect: {value: 201-created, required: false}
+- name: /datacenters/{datacenter:id}/iscsibonds/{iscsibond:id}|rel=delete
+  description: remove the specified iSCSI Bond from the datacenter
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: {}
+    headers: {}
+- name: 
/datacenters/{datacenter:id}/iscsibonds/{iscsibond:id}/networks|rel=delete
+  description: remove the specified network from the iSCSI Bond
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: {}
+    headers: {}
+- name: /datacenters/{datacenter:id}/iscsibonds/{iscsibond:id}/networks|rel=get
+  description: gets the specified iSCSI Bond with the networks
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: {}
+    headers: {}
+- name: /datacenters/{datacenter:id}/iscsibonds/{iscsibond:id}/networks|rel=add
+  description: specify list of networks contained in the iSCSI Bond
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: {}
+    headers: {}
+- name: 
/datacenters/{datacenter:id}/iscsibonds/{iscsibond:id}/storagedomains|rel=delete
+  description: remove the specified storagedomain from the iSCSI Bond
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: {}
+    headers: {}
+- name: 
/datacenters/{datacenter:id}/iscsibonds/{iscsibond:id}/storagedomains|rel=get
+  description: gets the specified iSCSI Bond with the storagedomains
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: {}
+    headers: {}
+- name: 
/datacenters/{datacenter:id}/iscsibonds/{iscsibond:id}/storagedomains|rel=add
+  description: specify list of the storagedomains contained in the iSCSI Bond
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: {}
+    headers: {}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCenterResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCenterResource.java
index 8f31e97..b0cf716 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCenterResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCenterResource.java
@@ -11,6 +11,7 @@
 import org.ovirt.engine.api.resource.AttachedStorageDomainsResource;
 import org.ovirt.engine.api.resource.ClustersResource;
 import org.ovirt.engine.api.resource.DataCenterResource;
+import org.ovirt.engine.api.resource.IscsiBondsResource;
 import org.ovirt.engine.api.resource.NetworksResource;
 import org.ovirt.engine.api.resource.QuotasResource;
 import org.ovirt.engine.api.restapi.utils.MalformedIdException;
@@ -77,6 +78,11 @@
          return inject(new BackendQuotasResource(id));
     }
 
+    @Override
+    public IscsiBondsResource getIscsiBondsResource() {
+        return inject(new BackendIscsiBondsResource(id));
+    }
+
     public BackendDataCentersResource getParent() {
         return parent;
     }
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCentersResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCentersResource.java
index a13a56b..a0ff9ac 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCentersResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendDataCentersResource.java
@@ -24,7 +24,8 @@
 public class BackendDataCentersResource extends
         AbstractBackendCollectionResource<DataCenter, StoragePool> implements 
DataCentersResource {
 
-    static final String[] SUB_COLLECTIONS = {"storagedomains", "clusters", 
"networks", "permissions", "quotas"};
+    static final String[] SUB_COLLECTIONS =
+            { "storagedomains", "clusters", "networks", "permissions", 
"quotas", "iscsibonds" };
 
     public BackendDataCentersResource() {
         super(DataCenter.class, StoragePool.class, SUB_COLLECTIONS);
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworkResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworkResource.java
new file mode 100644
index 0000000..8d26925
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworkResource.java
@@ -0,0 +1,43 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import org.ovirt.engine.api.model.Network;
+import org.ovirt.engine.core.common.businessentities.IscsiBond;
+import org.ovirt.engine.core.common.queries.IdQueryParameters;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
+
+public class BackendIscsiBondNetworkResource extends BackendNetworkResource {
+
+    private BackendIscsiBondNetworksResource parent;
+
+    public BackendIscsiBondNetworkResource(String id, 
BackendIscsiBondNetworksResource parent) {
+        super(id, parent);
+        this.parent = parent;
+    }
+
+    @Override
+    public Network get() {
+        IscsiBond iscsiBond = parent.getIscsiBond();
+
+        if (!iscsiBond.getNetworkIds().contains(guid)) {
+            return notFound();
+        }
+
+        org.ovirt.engine.core.common.businessentities.network.Network entity = 
getNetwork();
+
+        if (entity == null) {
+            return notFound();
+        }
+
+        return addLinks(map(entity));
+    }
+
+    private org.ovirt.engine.core.common.businessentities.network.Network 
getNetwork() {
+        return 
getEntity(org.ovirt.engine.core.common.businessentities.network.Network.class,
+                VdcQueryType.GetNetworkById, new IdQueryParameters(guid), 
guid.toString());
+    }
+
+    @Override
+    public BackendIscsiBondNetworksResource getParent() {
+        return parent;
+    }
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworksResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworksResource.java
new file mode 100644
index 0000000..c92fd5f
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworksResource.java
@@ -0,0 +1,62 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import javax.ws.rs.core.Response;
+
+import org.ovirt.engine.api.model.Network;
+import org.ovirt.engine.api.model.Networks;
+import org.ovirt.engine.api.resource.NetworkResource;
+import org.ovirt.engine.api.restapi.types.NetworkMapper;
+import org.ovirt.engine.core.common.action.EditIscsiBondParameters;
+import org.ovirt.engine.core.common.action.VdcActionType;
+import org.ovirt.engine.core.common.businessentities.IscsiBond;
+import org.ovirt.engine.core.common.queries.IdQueryParameters;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
+import org.ovirt.engine.core.compat.Guid;
+
+public class BackendIscsiBondNetworksResource extends BackendNetworksResource {
+
+    private Guid iscsiBondId;
+
+    public BackendIscsiBondNetworksResource(String iscsiBondId) {
+        super(VdcQueryType.GetNetworksByIscsiBondId);
+        this.iscsiBondId = Guid.createGuidFromString(iscsiBondId);
+    }
+
+    @Override
+    public Networks list() {
+        return mapCollection(
+                getBackendCollection(VdcQueryType.GetNetworksByIscsiBondId, 
new IdQueryParameters(iscsiBondId))
+        );
+    }
+
+    @Override
+    public Response add(Network network) {
+        org.ovirt.engine.core.common.businessentities.network.Network entity = 
NetworkMapper.map(network, null);
+
+        IscsiBond iscsiBond = getIscsiBond();
+        iscsiBond.getNetworkIds().add(entity.getId());
+        return performAction(VdcActionType.EditIscsiBond, new 
EditIscsiBondParameters(iscsiBond));
+    }
+
+    @Override
+    public Response performRemove(String id) {
+        IscsiBond iscsiBond = getIscsiBond();
+        iscsiBond.getNetworkIds().remove(Guid.createGuidFromString(id));
+        return performAction(VdcActionType.EditIscsiBond, new 
EditIscsiBondParameters(iscsiBond));
+    }
+
+    @Override
+    protected Network doPopulate(Network model, 
org.ovirt.engine.core.common.businessentities.network.Network entity) {
+        return model;
+    }
+
+    @Override
+    @SingleEntityResource
+    public NetworkResource getNetworkSubResource(String id) {
+        return inject(new BackendIscsiBondNetworkResource(id, this));
+    }
+
+    public IscsiBond getIscsiBond() {
+        return getEntity(IscsiBond.class, VdcQueryType.GetIscsiBondById, new 
IdQueryParameters(iscsiBondId), iscsiBondId.toString());
+    }
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondResource.java
new file mode 100644
index 0000000..3adc4ba
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondResource.java
@@ -0,0 +1,57 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import static 
org.ovirt.engine.api.restapi.resource.BackendIscsiBondsResource.SUB_COLLECTIONS;
+
+import org.ovirt.engine.api.model.IscsiBond;
+import org.ovirt.engine.api.resource.IscsiBondResource;
+import org.ovirt.engine.api.resource.NetworksResource;
+import org.ovirt.engine.api.resource.StorageServerConnectionsResource;
+import org.ovirt.engine.core.common.action.EditIscsiBondParameters;
+import org.ovirt.engine.core.common.action.VdcActionParametersBase;
+import org.ovirt.engine.core.common.action.VdcActionType;
+import org.ovirt.engine.core.common.queries.IdQueryParameters;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
+import org.ovirt.engine.core.compat.Guid;
+
+public class BackendIscsiBondResource extends 
AbstractBackendActionableResource<IscsiBond, 
org.ovirt.engine.core.common.businessentities.IscsiBond>
+        implements IscsiBondResource {
+
+    public  BackendIscsiBondResource(String id) {
+        super(id, IscsiBond.class, 
org.ovirt.engine.core.common.businessentities.IscsiBond.class, SUB_COLLECTIONS);
+    }
+
+    @Override
+    public IscsiBond get() {
+        return performGet(VdcQueryType.GetIscsiBondById, new 
IdQueryParameters(guid));
+    }
+
+    @Override
+    public IscsiBond update(IscsiBond iscsiBond) {
+        return performUpdate(iscsiBond,
+                new QueryIdResolver<Guid>(VdcQueryType.GetIscsiBondById, 
IdQueryParameters.class),
+                VdcActionType.EditIscsiBond,
+                new ParametersProvider<IscsiBond, 
org.ovirt.engine.core.common.businessentities.IscsiBond>() {
+                    @Override
+                    public VdcActionParametersBase getParameters(IscsiBond 
incoming, org.ovirt.engine.core.common.businessentities.IscsiBond entity) {
+                        return new EditIscsiBondParameters(
+                                getMapper(modelType, 
org.ovirt.engine.core.common.businessentities.IscsiBond.class).map(incoming, 
entity)
+                        );
+                    }
+                });
+    }
+
+    @Override
+    public NetworksResource getNetworksResource() {
+        return inject(new BackendIscsiBondNetworksResource(id));
+    }
+
+    @Override
+    public StorageServerConnectionsResource 
getStorageServerConnectionsResource() {
+        return inject(new BackendIscsiBondStorageConnectionsResource(id));
+    }
+
+    @Override
+    protected IscsiBond doPopulate(IscsiBond model, 
org.ovirt.engine.core.common.businessentities.IscsiBond entity) {
+        return model;
+    }
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondStorageConnectionsResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondStorageConnectionsResource.java
new file mode 100644
index 0000000..11344ab
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondStorageConnectionsResource.java
@@ -0,0 +1,81 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import java.util.List;
+
+import javax.ws.rs.core.Response;
+
+import org.ovirt.engine.api.model.Host;
+import org.ovirt.engine.api.model.StorageConnection;
+import org.ovirt.engine.api.model.StorageConnections;
+import org.ovirt.engine.api.resource.StorageServerConnectionResource;
+import org.ovirt.engine.api.restapi.types.StorageDomainMapper;
+import org.ovirt.engine.core.common.action.EditIscsiBondParameters;
+import org.ovirt.engine.core.common.action.VdcActionType;
+import org.ovirt.engine.core.common.businessentities.IscsiBond;
+import org.ovirt.engine.core.common.businessentities.StorageServerConnections;
+import org.ovirt.engine.core.common.queries.IdQueryParameters;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
+import org.ovirt.engine.core.compat.Guid;
+
+public class BackendIscsiBondStorageConnectionsResource extends 
BackendStorageServerConnectionsResource {
+
+    private Guid iscsiBondId;
+
+    public BackendIscsiBondStorageConnectionsResource(String iscsiBondId) {
+        super();
+        this.iscsiBondId = Guid.createGuidFromString(iscsiBondId);
+    }
+
+    @Override
+    public StorageConnections list() {
+        return mapCollection(
+                
getBackendCollection(VdcQueryType.GetStorageServerConnectionByIscsiBondId, new 
IdQueryParameters(iscsiBondId))
+        );
+    }
+
+    @Override
+    public Response add(StorageConnection conn) {
+        StorageServerConnections entity = StorageDomainMapper.map(conn, null);
+
+        IscsiBond iscsiBond = getIscsiBond();
+        iscsiBond.getStorageConnectionIds().add(entity.getid());
+        return performAction(VdcActionType.EditIscsiBond, new 
EditIscsiBondParameters(iscsiBond));
+    }
+
+    @Override
+    public Response remove(String id, Host host) {
+        // TODO should return BadRequest error
+        return null;
+    }
+
+    public Response remove(String id) {
+        return performRemove(id);
+    }
+
+    @Override
+    public StorageServerConnectionResource 
getStorageConnectionSubResource(String id) {
+        return inject(new BackendIscsiBondStorageServerConnection(id, this));
+    }
+
+    @Override
+    protected Response performRemove(String id) {
+        IscsiBond iscsiBond = getIscsiBond();
+        iscsiBond.getStorageConnectionIds().remove(id);
+        return performAction(VdcActionType.EditIscsiBond, new 
EditIscsiBondParameters(iscsiBond));
+    }
+
+    private IscsiBond getIscsiBond() {
+        return getEntity(IscsiBond.class, VdcQueryType.GetIscsiBondById, new 
IdQueryParameters(iscsiBondId), iscsiBondId.toString());
+    }
+
+    private StorageConnections mapCollection(List<StorageServerConnections> 
entities) {
+        StorageConnections conns = new StorageConnections();
+
+        for (StorageServerConnections entity : entities) {
+            StorageConnection conn = StorageDomainMapper.map(entity, null);
+            conns.getStorageConnections().add(addLinks(populate(conn, 
entity)));
+        }
+
+        return conns;
+    }
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondStorageServerConnection.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondStorageServerConnection.java
new file mode 100644
index 0000000..a61c329
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondStorageServerConnection.java
@@ -0,0 +1,17 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import org.ovirt.engine.api.model.StorageConnection;
+import 
org.ovirt.engine.core.common.queries.StorageServerConnectionQueryParametersBase;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
+
+public class BackendIscsiBondStorageServerConnection extends 
BackendStorageServerConnectionResource {
+
+    public BackendIscsiBondStorageServerConnection(String id, 
BackendStorageServerConnectionsResource parent) {
+        super(id, parent);
+    }
+
+    @Override
+    public StorageConnection get() {
+        return 
performGet(VdcQueryType.GetStorageServerConnectionByIscsiBondId, new 
StorageServerConnectionQueryParametersBase(guid.toString()));
+    }
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondsResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondsResource.java
new file mode 100644
index 0000000..1fa32f2
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondsResource.java
@@ -0,0 +1,77 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import java.util.List;
+
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Response;
+
+import org.ovirt.engine.api.model.IscsiBond;
+import org.ovirt.engine.api.model.IscsiBonds;
+import org.ovirt.engine.api.resource.IscsiBondResource;
+import org.ovirt.engine.api.resource.IscsiBondsResource;
+import org.ovirt.engine.api.restapi.types.IscsiBondMapper;
+import org.ovirt.engine.core.common.action.AddIscsiBondParameters;
+import org.ovirt.engine.core.common.action.RemoveIscsiBondParameters;
+import org.ovirt.engine.core.common.action.VdcActionType;
+import org.ovirt.engine.core.common.queries.IdQueryParameters;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
+import org.ovirt.engine.core.compat.Guid;
+
+public class BackendIscsiBondsResource extends 
AbstractBackendCollectionResource<IscsiBond, 
org.ovirt.engine.core.common.businessentities.IscsiBond>
+        implements IscsiBondsResource {
+
+    static final String[] SUB_COLLECTIONS = {"storageconnections", "networks", 
"add", };
+
+    private Guid dataCenterId;
+
+    protected BackendIscsiBondsResource(String datacenterId) {
+        super(IscsiBond.class, 
org.ovirt.engine.core.common.businessentities.IscsiBond.class, SUB_COLLECTIONS);
+        this.dataCenterId = asGuid(datacenterId);
+    }
+
+    @Override
+    public IscsiBonds list() {
+        return mapCollection(
+                
getBackendCollection(VdcQueryType.GetIscsiBondsByStoragePoolId, new 
IdQueryParameters(dataCenterId))
+        );
+    }
+
+    @Override
+    public Response add(IscsiBond iscsiBond) {
+        validateParameters(iscsiBond, "name");
+        org.ovirt.engine.core.common.businessentities.IscsiBond entity =
+                getMapper(IscsiBond.class, 
org.ovirt.engine.core.common.businessentities.IscsiBond.class).map(iscsiBond, 
null);
+        entity.setStoragePoolId(dataCenterId);
+
+        return performCreate(VdcActionType.AddIscsiBond,
+                new AddIscsiBondParameters(entity),
+                new QueryIdResolver<Guid>(VdcQueryType.GetIscsiBondById, 
IdQueryParameters.class));
+    }
+
+    @Override
+    protected Response performRemove(String id) {
+        return performAction(VdcActionType.RemoveIscsiBond, new 
RemoveIscsiBondParameters(asGuid(id)));
+    }
+
+    @Override
+    @SingleEntityResource
+    public IscsiBondResource getIscsiBondSubResource(@PathParam("id") String 
id) {
+        return inject(new BackendIscsiBondResource(id));
+    }
+
+    @Override
+    protected IscsiBond doPopulate(IscsiBond model, 
org.ovirt.engine.core.common.businessentities.IscsiBond entity) {
+        return model;
+    }
+
+    private IscsiBonds 
mapCollection(List<org.ovirt.engine.core.common.businessentities.IscsiBond> 
entities) {
+        IscsiBonds iscsiBonds = new IscsiBonds();
+
+        for (org.ovirt.engine.core.common.businessentities.IscsiBond entity : 
entities) {
+            IscsiBond iscsiBond = IscsiBondMapper.map(entity, null);
+            iscsiBonds.getIscsiBonds().add(addLinks(populate(iscsiBond, 
entity)));
+        }
+
+        return iscsiBonds;
+    }
+}
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 3a46ae9..771fe72 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
@@ -79,6 +79,7 @@
             addNetworkLabelsFeature(features);
             addRebootFeature(features);
             addMaintenanceFeature(features);
+            addIscsiBondFeature(features);
         }
         if (VersionUtils.greaterOrEqual(version, 
BackendCapabilitiesResource.VERSION_3_5)) {
             addBookmarksFeature(features);
@@ -486,4 +487,11 @@
         feature.setDescription("Add/modify/remove numanodes.");
         features.getFeature().add(feature);
     }
+
+    private void addIscsiBondFeature(Features features) {
+        Feature feature = new Feature();
+        feature.setName("Manage iSCSI Bonds");
+        feature.setDescription("Add/modify/remove iSCSI Bonds.");
+        features.getFeature().add(feature);
+    }
 }
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworkResourceTest.java
 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworkResourceTest.java
new file mode 100644
index 0000000..b050840
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworkResourceTest.java
@@ -0,0 +1,97 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.Test;
+import org.ovirt.engine.core.common.businessentities.IscsiBond;
+import org.ovirt.engine.core.common.queries.IdQueryParameters;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
+import org.ovirt.engine.core.compat.Guid;
+
+public class BackendIscsiBondNetworkResourceTest
+        extends 
AbstractBackendNetworkResourceTest<BackendIscsiBondNetworkResource> {
+
+    protected static final Guid ISCSI_BOND_ID = GUIDS[1];
+    protected static final Guid NETWORK_ID = GUIDS[2];
+
+    public BackendIscsiBondNetworkResourceTest() {
+        super(new BackendIscsiBondNetworkResource(GUIDS[2].toString(),
+                new 
BackendIscsiBondNetworksResource(ISCSI_BOND_ID.toString())));
+    }
+
+    @Test
+    public void testGet() throws Exception {
+        setUriInfo(setUpBasicUriExpectations());
+        setUpEntityQueryExpectations(1, getIscsiBondContainingNetwork());
+        setUpEntityQueryExpectations(VdcQueryType.GetNetworkById,
+                IdQueryParameters.class,
+                new String[] { "Id" },
+                new Object[] { NETWORK_ID },
+                getEntityList());
+        control.replay();
+
+        verifyModel(resource.get(), 0);
+    }
+
+    @Test
+    public void testGetWithInvalidNetworkId() throws Exception {
+        setUriInfo(setUpBasicUriExpectations());
+        setUpEntityQueryExpectations(1, getIscsiBondWithNoMatchingNetworks());
+        control.replay();
+
+        try {
+            resource.get();
+            fail("expected WebApplicationException");
+        } catch (WebApplicationException wae) {
+            verifyNotFoundException(wae);
+        }
+    }
+
+    @Test
+    public void testGetNetworkNotFound() throws Exception {
+        setUriInfo(setUpBasicUriExpectations());
+        setUpEntityQueryExpectations(1, getIscsiBondContainingNetwork());
+
+        List<org.ovirt.engine.core.common.businessentities.network.Network> 
entities = new ArrayList<>();
+        setUpEntityQueryExpectations(VdcQueryType.GetNetworkById,
+                IdQueryParameters.class,
+                new String[] { "Id" },
+                new Object[] { NETWORK_ID },
+                entities);
+        control.replay();
+
+        try {
+            resource.get();
+            fail("expected WebApplicationException");
+        } catch (WebApplicationException wae) {
+            verifyNotFoundException(wae);
+        }
+    }
+
+    protected void setUpEntityQueryExpectations(int times, IscsiBond 
iscsiBond) throws Exception {
+        while (times-- > 0) {
+            setUpEntityQueryExpectations(VdcQueryType.GetIscsiBondById,
+                    IdQueryParameters.class,
+                    new String[]{"Id"},
+                    new Object[]{ISCSI_BOND_ID},
+                    iscsiBond);
+        }
+    }
+
+    private org.ovirt.engine.core.common.businessentities.IscsiBond 
getIscsiBondContainingNetwork() {
+        org.ovirt.engine.core.common.businessentities.IscsiBond iscsiBond = 
new org.ovirt.engine.core.common.businessentities.IscsiBond();
+        iscsiBond.setId(ISCSI_BOND_ID);
+        iscsiBond.getNetworkIds().add(NETWORK_ID);
+        return iscsiBond;
+    }
+
+    private org.ovirt.engine.core.common.businessentities.IscsiBond 
getIscsiBondWithNoMatchingNetworks() {
+        org.ovirt.engine.core.common.businessentities.IscsiBond iscsiBond = 
new org.ovirt.engine.core.common.businessentities.IscsiBond();
+        iscsiBond.setId(ISCSI_BOND_ID);
+        iscsiBond.getNetworkIds().add(GUIDS[0]);
+        return iscsiBond;
+    }
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworksResourceTest.java
 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworksResourceTest.java
new file mode 100644
index 0000000..c7c8812
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondNetworksResourceTest.java
@@ -0,0 +1,118 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.junit.Test;
+import org.ovirt.engine.api.model.Network;
+import org.ovirt.engine.core.common.action.EditIscsiBondParameters;
+import org.ovirt.engine.core.common.action.VdcActionParametersBase;
+import org.ovirt.engine.core.common.action.VdcActionType;
+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;
+
+public class BackendIscsiBondNetworksResourceTest extends 
AbstractBackendNetworksResourceTest<BackendNetworksResource> {
+    protected static final Guid ISCSI_BOND_ID = GUIDS[1];
+    protected static final Guid NETWORK_ID = GUIDS[2];
+
+    public BackendIscsiBondNetworksResourceTest() {
+        super(new BackendIscsiBondNetworksResource(ISCSI_BOND_ID.toString()), 
SearchType.IscsiBond, "IscsiBonds : ");
+    }
+
+    private org.ovirt.engine.core.common.businessentities.IscsiBond 
getIscsiBondContainingNetwork() {
+        org.ovirt.engine.core.common.businessentities.IscsiBond iscsiBond = 
getIscsiBondWithNoNetworks();
+        iscsiBond.getNetworkIds().add(NETWORK_ID);
+        return iscsiBond;
+    }
+
+    private org.ovirt.engine.core.common.businessentities.IscsiBond 
getIscsiBondWithNoNetworks() {
+        org.ovirt.engine.core.common.businessentities.IscsiBond iscsiBond =
+                new org.ovirt.engine.core.common.businessentities.IscsiBond();
+        iscsiBond.setId(ISCSI_BOND_ID);
+        return iscsiBond;
+    }
+
+    @Override
+    protected UriInfo setUpActionExpectations(VdcActionType task,
+            Class<? extends VdcActionParametersBase> clz,
+            String[] names,
+            Object[] values,
+            boolean canDo,
+            boolean success) {
+        return super.setUpActionExpectations(task, clz, names, values, canDo, 
success);
+    }
+
+    @Test
+    public void testAdd() throws Exception {
+        setUriInfo(setUpBasicUriExpectations());
+        Network network = getModel(0);
+        network.setId(NETWORK_ID.toString());
+
+        setUpGetEntityExpectations(VdcQueryType.GetIscsiBondById,
+                IdQueryParameters.class,
+                new String[] { "Id" },
+                new Object[] { ISCSI_BOND_ID },
+                getIscsiBondWithNoNetworks());
+
+        setUpActionExpectations(VdcActionType.EditIscsiBond,
+                EditIscsiBondParameters.class,
+                new String[] { "IscsiBond" },
+                new Object[] { getIscsiBondContainingNetwork() },
+                true,
+                true,
+                null);
+
+        Response response = collection.add(network);
+        assertEquals(200, response.getStatus());
+    }
+
+    @Test
+    public void testRemove() throws Exception {
+        setUriInfo(setUpBasicUriExpectations());
+        Network network = new Network();
+        network.setId(NETWORK_ID.toString());
+
+        setUpGetEntityExpectations(VdcQueryType.GetIscsiBondById,
+                IdQueryParameters.class,
+                new String[] { "Id" },
+                new Object[] { ISCSI_BOND_ID },
+                getIscsiBondContainingNetwork());
+
+        setUpActionExpectations(VdcActionType.EditIscsiBond,
+                EditIscsiBondParameters.class,
+                new String[] { "IscsiBond" },
+                new Object[] { getIscsiBondWithNoNetworks() },
+                true,
+                true,
+                null);
+
+        Response response = collection.performRemove(network.getId());
+        assertEquals(200, response.getStatus());
+    }
+
+    @Override
+    protected void setUpEntityQueryExpectations(int times, Object failure) 
throws Exception {
+        while (times-- > 0) {
+            setUpEntityQueryExpectations(VdcQueryType.GetNetworksByIscsiBondId,
+                    IdQueryParameters.class,
+                    new String[] { "Id" },
+                    new Object[] { ISCSI_BOND_ID },
+                    getEntityList(),
+                    failure);
+        }
+    }
+
+    @Override
+    protected void setUpQueryExpectations(String query, Object failure) throws 
Exception {
+        setUpEntityQueryExpectations(VdcQueryType.GetNetworksByIscsiBondId,
+                IdQueryParameters.class,
+                new String[] { "Id" },
+                new Object[] { ISCSI_BOND_ID },
+                getEntityList(),
+                failure);
+        control.replay();
+    }
+
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondsResourceTest.java
 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondsResourceTest.java
new file mode 100644
index 0000000..0c5145c
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendIscsiBondsResourceTest.java
@@ -0,0 +1,153 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+import org.junit.Test;
+import org.ovirt.engine.api.model.IscsiBond;
+import org.ovirt.engine.core.common.action.AddIscsiBondParameters;
+import org.ovirt.engine.core.common.action.RemoveIscsiBondParameters;
+import org.ovirt.engine.core.common.action.VdcActionType;
+import org.ovirt.engine.core.common.queries.IdQueryParameters;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
+import org.ovirt.engine.core.compat.Guid;
+
+public class BackendIscsiBondsResourceTest extends 
AbstractBackendCollectionResourceTest<IscsiBond, 
org.ovirt.engine.core.common.businessentities.IscsiBond, 
BackendIscsiBondsResource> {
+    protected static final Guid ISCSI_BOND_ID = GUIDS[1];
+    protected static final Guid DATA_CENTER_ID = GUIDS[2];
+    static Guid PARENT_GUID = GUIDS[2];
+
+    public BackendIscsiBondsResourceTest() {
+        super(new BackendIscsiBondsResource(DATA_CENTER_ID.toString()), null, 
"");
+    }
+
+    @Override
+    protected List<IscsiBond> getCollection() {
+        return collection.list().getIscsiBonds();
+    }
+
+    @Override
+    protected org.ovirt.engine.core.common.businessentities.IscsiBond 
getEntity(int index) {
+        org.ovirt.engine.core.common.businessentities.IscsiBond iscsiBond =
+                new org.ovirt.engine.core.common.businessentities.IscsiBond();
+        iscsiBond.setId(GUIDS[index]);
+        iscsiBond.setStoragePoolId(DATA_CENTER_ID);
+        iscsiBond.setName(NAMES[1]);
+        iscsiBond.setDescription(DESCRIPTIONS[1]);
+        return iscsiBond;
+    }
+
+    @Test
+    public void testAddIscsiBond() throws Exception {
+        setUriInfo(setUpBasicUriExpectations());
+        setUpCreationExpectations(VdcActionType.AddIscsiBond,
+                AddIscsiBondParameters.class,
+                new String[] { "IscsiBond" },
+                new Object[] { getIscsiBond() },
+                true,
+                true,
+                getIscsiBond().getId(),
+                VdcQueryType.GetIscsiBondById,
+                IdQueryParameters.class,
+                new String[] { "Id" },
+                new Object[] { ISCSI_BOND_ID },
+                getEntity(1));
+
+        Response response = collection.add(getIscsiBondApi());
+        assertEquals(201, response.getStatus());
+        assertTrue(response.getEntity() instanceof IscsiBond);
+        verifyModel((IscsiBond) response.getEntity(), 1);
+    }
+
+    private org.ovirt.engine.core.common.businessentities.IscsiBond 
getIscsiBond() {
+        org.ovirt.engine.core.common.businessentities.IscsiBond iscsiBond =
+                new org.ovirt.engine.core.common.businessentities.IscsiBond();
+        iscsiBond.setId(ISCSI_BOND_ID);
+        iscsiBond.setStoragePoolId(DATA_CENTER_ID);
+        iscsiBond.setName(NAMES[0]);
+        return iscsiBond;
+    }
+
+    private IscsiBond getIscsiBondApi() {
+        IscsiBond iscsiBond = new IscsiBond();
+        iscsiBond.setId(ISCSI_BOND_ID.toString());
+        iscsiBond.setName(NAMES[0]);
+        return iscsiBond;
+    }
+
+    protected void setUpEntityQueryExpectations(int times, Object failure) 
throws Exception {
+        while (times-- > 0) {
+            
setUpEntityQueryExpectations(VdcQueryType.GetIscsiBondsByStoragePoolId,
+                    IdQueryParameters.class,
+                    new String[] { "Id" },
+                    new Object[] { DATA_CENTER_ID },
+                    setUpIscsiBonds(),
+                    failure);
+        }
+    }
+
+    @Override
+    protected void setUpQueryExpectations(String query, Object failure) throws 
Exception {
+        setUpEntityQueryExpectations(VdcQueryType.GetIscsiBondsByStoragePoolId,
+                IdQueryParameters.class,
+                new String[] { "Id" },
+                new Object[] { DATA_CENTER_ID },
+                setUpIscsiBonds(),
+                failure);
+        control.replay();
+    }
+
+    static List<org.ovirt.engine.core.common.businessentities.IscsiBond> 
setUpIscsiBonds() {
+        List<org.ovirt.engine.core.common.businessentities.IscsiBond> 
iscsiBonds = new ArrayList<>();
+        for (int i = 0; i < NAMES.length; i++) {
+            org.ovirt.engine.core.common.businessentities.IscsiBond iscsiBond =
+                    new 
org.ovirt.engine.core.common.businessentities.IscsiBond();
+            iscsiBond.setDescription(DESCRIPTIONS[i]);
+            iscsiBond.setName(NAMES[i]);
+            iscsiBond.setId(GUIDS[i]);
+            iscsiBond.setStoragePoolId(DATA_CENTER_ID);
+            iscsiBonds.add(iscsiBond);
+        }
+        return iscsiBonds;
+    }
+
+    @Test
+    public void testRemove() throws Exception {
+        setUpGetEntityExcpectations();
+        setUriInfo(setUpActionExpectations(VdcActionType.RemoveIscsiBond,
+                RemoveIscsiBondParameters.class,
+                new String[] { "IscsiBondId" },
+                new Object[] { GUIDS[0] },
+                true,
+                true));
+        verifyRemove(collection.remove(GUIDS[0].toString()));
+    }
+
+    @Test
+    public void testRemoveNonExistant() throws Exception {
+        setUpGetEntityExpectations(VdcQueryType.GetIscsiBondById,
+                IdQueryParameters.class,
+                new String[] { "Id" },
+                new Object[] { NON_EXISTANT_GUID },
+                null);
+        control.replay();
+        try {
+            collection.remove(NON_EXISTANT_GUID.toString());
+            fail("expected WebApplicationException");
+        } catch (WebApplicationException wae) {
+            assertNotNull(wae.getResponse());
+            assertEquals(404, wae.getResponse().getStatus());
+        }
+    }
+
+    private void setUpGetEntityExcpectations() throws Exception {
+        setUpGetEntityExpectations(VdcQueryType.GetIscsiBondById,
+                IdQueryParameters.class,
+                new String[] { "Id" },
+                new Object[] { GUIDS[0] },
+                getEntity(0));
+    }
+}
diff --git 
a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/IscsiBondMapper.java
 
b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/IscsiBondMapper.java
new file mode 100644
index 0000000..2297b05
--- /dev/null
+++ 
b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/IscsiBondMapper.java
@@ -0,0 +1,84 @@
+package org.ovirt.engine.api.restapi.types;
+
+import org.ovirt.engine.api.model.DataCenter;
+import org.ovirt.engine.api.model.IscsiBond;
+import org.ovirt.engine.api.model.Network;
+import org.ovirt.engine.api.model.Networks;
+import org.ovirt.engine.api.model.StorageConnection;
+import org.ovirt.engine.api.model.StorageConnections;
+import org.ovirt.engine.core.compat.Guid;
+
+public class IscsiBondMapper {
+
+    @Mapping(from = IscsiBond.class, to = 
org.ovirt.engine.core.common.businessentities.IscsiBond.class)
+    public static org.ovirt.engine.core.common.businessentities.IscsiBond 
map(IscsiBond from,
+                                                                              
org.ovirt.engine.core.common.businessentities.IscsiBond to) {
+        org.ovirt.engine.core.common.businessentities.IscsiBond iscsiBond = 
(to != null) ?
+                to : new 
org.ovirt.engine.core.common.businessentities.IscsiBond();
+
+        if (from.isSetId()) {
+            iscsiBond.setId(Guid.createGuidFromString(from.getId()));
+        }
+
+        if (from.isSetDataCenter() && from.getDataCenter().isSetId()) {
+            
iscsiBond.setStoragePoolId(Guid.createGuidFromString(from.getDataCenter().getId()));
+        }
+
+        if (from.isSetName()) {
+            iscsiBond.setName(from.getName());
+        }
+
+        if (from.isSetDescription()) {
+            iscsiBond.setDescription(from.getDescription());
+        }
+
+        if (from.isSetStorageConnections()) {
+            for (StorageConnection conn : 
from.getStorageConnections().getStorageConnections()) {
+                iscsiBond.getStorageConnectionIds().add(conn.getId());
+            }
+        }
+
+        if (from.isSetNetworks()) {
+            for (Network network : from.getNetworks().getNetworks()) {
+                
iscsiBond.getNetworkIds().add(Guid.createGuidFromString(network.getId()));
+            }
+        }
+
+        return iscsiBond;
+    }
+
+    @Mapping(from = 
org.ovirt.engine.core.common.businessentities.IscsiBond.class, to = 
IscsiBond.class)
+    public static IscsiBond 
map(org.ovirt.engine.core.common.businessentities.IscsiBond from, IscsiBond to) 
{
+
+        IscsiBond iscsiBond = (to != null) ? to : new IscsiBond();
+
+        DataCenter dataCenter = new DataCenter();
+        dataCenter.setId(from.getStoragePoolId().toString());
+
+        iscsiBond.setDataCenter(dataCenter);
+        iscsiBond.setName(from.getName());
+        iscsiBond.setDescription(from.getDescription());
+
+        if (from.getId() != null) {
+            iscsiBond.setId(from.getId().toString());
+        }
+
+        Networks networks = new Networks();
+        for (Guid id : from.getNetworkIds()) {
+            Network network = new Network();
+            network.setId(id.toString());
+            networks.getNetworks().add(network);
+        }
+        iscsiBond.setNetworks(networks);
+
+        StorageConnections connections = new StorageConnections();
+        for (String id : from.getStorageConnectionIds()) {
+            StorageConnection conn = new StorageConnection();
+            conn.setId(id);
+            connections.getStorageConnections().add(conn);
+        }
+        iscsiBond.setStorageConnections(connections);
+
+        return iscsiBond;
+    }
+}
diff --git 
a/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/IscsiBondMapperTest.java
 
b/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/IscsiBondMapperTest.java
new file mode 100644
index 0000000..2f330fa
--- /dev/null
+++ 
b/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/IscsiBondMapperTest.java
@@ -0,0 +1,77 @@
+package org.ovirt.engine.api.restapi.types;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.ovirt.engine.api.model.IscsiBond;
+import org.ovirt.engine.api.model.Network;
+import org.ovirt.engine.api.model.Networks;
+import org.ovirt.engine.api.model.StorageConnection;
+import org.ovirt.engine.api.model.StorageConnections;
+
+public class IscsiBondMapperTest extends 
AbstractInvertibleMappingTest<IscsiBond,
+        org.ovirt.engine.core.common.businessentities.IscsiBond, 
org.ovirt.engine.core.common.businessentities.IscsiBond> {
+
+    public IscsiBondMapperTest() {
+        super(IscsiBond.class,
+                org.ovirt.engine.core.common.businessentities.IscsiBond.class,
+                org.ovirt.engine.core.common.businessentities.IscsiBond.class);
+    }
+
+    @Override
+    protected void verify(IscsiBond model, IscsiBond transform) {
+        assertNotNull(transform);
+        assertEquals(model.getName(), transform.getName());
+        assertEquals(model.getId(), transform.getId());
+        assertEquals(model.getDescription(), transform.getDescription());
+
+        if (model.isSetDataCenter()) {
+            assertEquals(model.getDataCenter().getId(), 
transform.getDataCenter().getId());
+        } else {
+            assertNull(transform.getDataCenter());
+        }
+
+        verifyNetworks(model.getNetworks(), transform.getNetworks());
+        verifyStorageConnections(model.getStorageConnections(), 
transform.getStorageConnections());
+    }
+
+    private static void verifyNetworks(Networks before, Networks after) {
+        if (before == null) {
+            assertNull(after);
+        } else {
+            assertEquals(before.getNetworks().size(), 
after.getNetworks().size());
+
+            Set<String> ids = new HashSet<>();
+
+            for (Network network : before.getNetworks()) {
+                ids.add(network.getId());
+            }
+
+            for (Network network : after.getNetworks()) {
+                ids.remove(network.getId());
+            }
+
+            assertEquals(0, ids.size());
+        }
+    }
+
+    private static void verifyStorageConnections(StorageConnections before, 
StorageConnections after) {
+        if (before == null) {
+            assertNull(after);
+        } else {
+            assertEquals(before.getStorageConnections().size(), 
after.getStorageConnections().size());
+
+            Set<String> ids = new HashSet<>();
+
+            for (StorageConnection conn : before.getStorageConnections()) {
+                ids.add(conn.getId());
+            }
+
+            for (StorageConnection conn : after.getStorageConnections()) {
+                ids.remove(conn.getId());
+            }
+
+            assertEquals(0, ids.size());
+        }
+    }
+}


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id8881110cbeb163e9fc09e98bf4497d894f40490
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: ovirt-engine-3.5
Gerrit-Owner: Maor Lipchuk <[email protected]>
Gerrit-Reviewer: Sergey Gotliv <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to