Gilad Chaplik has uploaded a new change for review.

Change subject: restapi: adding support for affinity groups
......................................................................

restapi: adding support for affinity groups

* Adding a new affinity groups sub-collections for clusters:
GET /clusters/{cluster_id}/affinitygroups

* affinity groups action includes, add, update and remove affinity groups:
POST /clusters/{cluster_id}/affinitygroups/
<affinity_group>
  <name>
  <positive>
  <enforcing>
</..>
GET/DELETE/PUT /clusters/{cluster_id}/affinitygroups/{affinity_group_id}

* Adding VMs sub-collection for a single affinity group: allowing to add/remove
VMs from an affinity group using post/delete:
GET /clusters/{cluster_id}/affinitygroups/{affinity_group_id}/vms
POST /clusters/{cluster_id}/affinitygroups/{affinity_group_id}/vms
<vm id='{vm_id}'>
</vm>
DELETE /clusters/{cluster_id}/affinitygroups/{affinity_group_id}/vms/{vm_id}

* include tests for added resources

For more information please refer
    to: http://www.ovirt.org/Features/VM-Affinity

Change-Id: Ie2daa18742eca73517ef739e70e972d74aad4244
Bug-Url: https://bugzilla.redhat.com/??????
Signed-off-by: Gilad Chaplik <gchap...@redhat.com>
---
M 
backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/LinkHelper.java
A 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AffinityGroupResource.java
A 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AffinityGroupVmsResource.java
A 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AffinityGroupsResource.java
M 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/ClusterResource.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
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupResource.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupVmsResource.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupsResource.java
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendClusterResource.java
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendClustersResource.java
A 
backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupResourceTest.java
A 
backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupVmsResourceTest.java
A 
backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupsResourceTest.java
A 
backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/AffinityGroupMapper.java
A 
backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/AffinityGroupMapperTest.java
17 files changed, 867 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/52/23452/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 bca9d01..378a122 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
@@ -29,6 +29,7 @@
 
 import org.ovirt.engine.api.model.ActionableResource;
 import org.ovirt.engine.api.model.ActionsBuilder;
+import org.ovirt.engine.api.model.AffinityGroup;
 import org.ovirt.engine.api.model.Application;
 import org.ovirt.engine.api.model.BaseResource;
 import org.ovirt.engine.api.model.CdRom;
@@ -76,6 +77,8 @@
 import org.ovirt.engine.api.model.VmPool;
 import org.ovirt.engine.api.model.VnicProfile;
 import org.ovirt.engine.api.model.WatchDog;
+import org.ovirt.engine.api.resource.AffinityGroupResource;
+import org.ovirt.engine.api.resource.AffinityGroupsResource;
 import org.ovirt.engine.api.resource.AssignedNetworkResource;
 import org.ovirt.engine.api.resource.AssignedNetworksResource;
 import org.ovirt.engine.api.resource.AssignedPermissionsResource;
@@ -371,6 +374,9 @@
         map.add(LabelResource.class, LabelsResource.class, Network.class);
         map.add(LabelResource.class, LabelsResource.class, HostNIC.class);
         TYPES.put(Label.class, map);
+
+        map = new ParentToCollectionMap(AffinityGroupResource.class, 
AffinityGroupsResource.class, Cluster.class);
+        TYPES.put(AffinityGroup.class, map);
     }
 
     /**
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AffinityGroupResource.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AffinityGroupResource.java
new file mode 100644
index 0000000..5ac99b0
--- /dev/null
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AffinityGroupResource.java
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 2010 Red Hat, Inc.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*           http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package org.ovirt.engine.api.resource;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
+import org.ovirt.engine.api.model.AffinityGroup;
+
+@Produces({ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, 
ApiMediaType.APPLICATION_X_YAML})
+public interface AffinityGroupResource extends 
UpdatableResource<AffinityGroup> {
+
+    @Path("vms")
+    public AffinityGroupVmsResource getAffinityGroupVmsSubResource();
+
+}
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AffinityGroupVmsResource.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AffinityGroupVmsResource.java
new file mode 100644
index 0000000..1a81918
--- /dev/null
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AffinityGroupVmsResource.java
@@ -0,0 +1,32 @@
+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.jboss.resteasy.annotations.providers.jaxb.Formatted;
+import org.ovirt.engine.api.model.VM;
+import org.ovirt.engine.api.model.VMs;
+
+@Produces({ ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, 
ApiMediaType.APPLICATION_X_YAML })
+public interface AffinityGroupVmsResource {
+
+    @GET
+    @Formatted
+    public VMs list();
+
+    @POST
+    @Formatted
+    @Consumes({ ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, 
ApiMediaType.APPLICATION_X_YAML })
+    public Response add(VM vm);
+
+    @DELETE
+    @Path("{id}")
+    public Response remove(@PathParam("id") String id);
+
+}
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AffinityGroupsResource.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AffinityGroupsResource.java
new file mode 100644
index 0000000..8deb335
--- /dev/null
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/AffinityGroupsResource.java
@@ -0,0 +1,33 @@
+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.jboss.resteasy.annotations.providers.jaxb.Formatted;
+import org.ovirt.engine.api.model.AffinityGroup;
+import org.ovirt.engine.api.model.AffinityGroups;
+
+@Produces({ ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, 
ApiMediaType.APPLICATION_X_YAML })
+public interface AffinityGroupsResource {
+    @GET
+    @Formatted
+    public AffinityGroups list();
+
+    @POST
+    @Formatted
+    @Consumes({ ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, 
ApiMediaType.APPLICATION_X_YAML })
+    public Response add(AffinityGroup affinityGroup);
+
+    @DELETE
+    @Path("{id}")
+    public Response remove(@PathParam("id") String id);
+
+    @Path("{id}")
+    public AffinityGroupResource getAffinityGroupResource(@PathParam("id") 
String id);
+}
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/ClusterResource.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/ClusterResource.java
index 47d271d..66d47fe 100644
--- 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/ClusterResource.java
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/ClusterResource.java
@@ -38,4 +38,7 @@
 
     @Path("glusterhooks")
     public GlusterHooksResource getGlusterHooksResource();
+
+    @Path("affinitygroups")
+    public AffinityGroupsResource getAffinityGroupsResource();
 }
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 5cfdf2d..12ecd84 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
@@ -3848,4 +3848,35 @@
       </xs:extension>
     </xs:complexContent>
 </xs:complexType>
+
+  <xs:element name="affinity_group" type="AffinityGroup" />
+  <xs:complexType name="AffinityGroup">
+    <xs:complexContent>
+      <xs:extension base="BaseResource">
+        <xs:sequence>
+          <xs:element ref="cluster" minOccurs="1" maxOccurs="1" />
+          <xs:element name="positive" type="xs:boolean" minOccurs="1"
+            maxOccurs="1" />
+          <xs:element name="enforcing" type="xs:boolean"
+            minOccurs="1" maxOccurs="1" />
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:element name="affinity_groups" type="AffinityGroups" />
+  <xs:complexType name="AffinityGroups">
+    <xs:complexContent>
+      <xs:extension base="BaseResources">
+        <xs:sequence>
+          <xs:annotation>
+            <xs:appinfo>
+              <jaxb:property name="AffinityGroups" />
+            </xs:appinfo>
+          </xs:annotation>
+          <xs:element ref="affinity_group" minOccurs="0"
+            maxOccurs="unbounded" />
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
 </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 25ef2f3..1341335 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
@@ -4626,4 +4626,83 @@
       Content-Type: {value: application/xml|json, required: true}
       Expect: {value: 201-created, required: false}
       Correlation-Id: {value: 'any string', required: false}
+- name: /clusters/{cluster:id}/affinitygroups|rel=get
+  description: get the list of affinity groups in the cluster
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams:
+      max: {context: matrix, type: 'xs:int', value: 'max results', required: 
false}
+    headers: {}
+- name: /clusters/{cluster:id}/affinitygroups/{affinitygroup:id}|rel=get
+  description: get the details of the specified affinity group in the cluster
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: {}
+    headers: {}
+- name: /clusters/{cluster:id}/affinitygroups/{affinitygroup:id}|rel=delete
+  description: delete the specified affinity groups in the cluster
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: {}
+    headers: {}
+- name: /clusters/{cluster:id}/affinitygroups/{affinitygroup:id}|rel=update
+  description: update the specified affinity group in the cluster
+  request:
+    body:
+      parameterType: affinitygroup
+      signatures:
+      - mandatoryArguments: {}
+        optionalArguments: {affinitygroup.name: 'xs:string', 
affinitygroup.positive: 'xs:boolean', affinitygroup.enforcing: 'xs:boolean'}
+    urlparams: {}
+    headers:
+      Content-Type: {value: application/xml|json, required: true}
+- name: /clusters/{cluster:id}/affinitygroups|rel=add
+  description: add a new affinity group to the cluster
+  request:
+    body:
+      parameterType: affinitygroup
+      signatures:
+      - mandatoryArguments: {affinitygroup.name: 'xs:string', 
affinitygroup.positive: 'xs:boolean', affinitygroup.enforcing: 'xs:boolean'}
+        optionalArguments: {}
+        description: add a new affinity group to the cluster
+    urlparams: {}
+    headers:
+      Content-Type: {value: application/xml|json, required: true}
+      Expect: {value: 201-created, required: false}
+- name: /clusters/{cluster:id}/affinitygroups/{affinitygroup:id}/vms|rel=get
+  description: get the list of vms per affinity group
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams:
+      max: {context: matrix, type: 'xs:int', value: 'max results', required: 
false}
+    headers: {}
+- name: 
/clusters/{cluster:id}/affinitygroups/{affinitygroup:id}/vms/{vm:id}|rel=delete
+  description: remove the specified vm from the affinity groups
+  request:
+    body:
+      parameterType: null
+      signatures: []
+    urlparams: {}
+    headers: {}
+- name: /clusters/{cluster:id}/affinitygroups/{affinitygroup:id}/vms|rel=add
+  description: add a vm to the specified affinity group
+  request:
+    body:
+      parameterType: VM
+      signatures:
+      - mandatoryArguments: {vm.id|name: 'xs:string'}
+        optionalArguments: {}
+        description: add a vm to affinity group
+    urlparams: {}
+    headers:
+      Content-Type: {value: application/xml|json, required: true}
+      Expect: {value: 201-created, required: false}
 
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupResource.java
new file mode 100644
index 0000000..ce2a687
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupResource.java
@@ -0,0 +1,52 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import org.ovirt.engine.api.model.AffinityGroup;
+import org.ovirt.engine.api.resource.AffinityGroupResource;
+import org.ovirt.engine.api.resource.AffinityGroupVmsResource;
+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.common.scheduling.parameters.AffinityGroupCRUDParameters;
+import org.ovirt.engine.core.compat.Guid;
+
+public class BackendAffinityGroupResource
+        extends AbstractBackendSubResource<AffinityGroup, 
org.ovirt.engine.core.common.scheduling.AffinityGroup>
+        implements AffinityGroupResource {
+    static final String[] SUB_COLLECTIONS = { "vms" };
+
+    public BackendAffinityGroupResource(String id) {
+        super(id, AffinityGroup.class,
+                org.ovirt.engine.core.common.scheduling.AffinityGroup.class, 
SUB_COLLECTIONS);
+    }
+
+    @Override
+    public AffinityGroup get() {
+        return performGet(VdcQueryType.GetAffinityGroupById, new 
IdQueryParameters(guid));
+    }
+
+    @Override
+    public AffinityGroup update(final AffinityGroup incoming) {
+        return performUpdate(incoming,
+                new QueryIdResolver<Guid>(VdcQueryType.GetAffinityGroupById, 
IdQueryParameters.class),
+                VdcActionType.EditAffinityGroup,
+                new ParametersProvider<AffinityGroup, 
org.ovirt.engine.core.common.scheduling.AffinityGroup>() {
+                    @Override
+                    public VdcActionParametersBase getParameters(AffinityGroup 
model,
+                            
org.ovirt.engine.core.common.scheduling.AffinityGroup entity) {
+                        return new AffinityGroupCRUDParameters(guid, 
map(incoming, entity));
+                    }
+                });
+    }
+
+    @Override
+    protected AffinityGroup doPopulate(AffinityGroup model, 
org.ovirt.engine.core.common.scheduling.AffinityGroup entity) {
+        return model;
+    }
+
+    @Override
+    public AffinityGroupVmsResource getAffinityGroupVmsSubResource() {
+        return inject(new BackendAffinityGroupVmsResource(guid));
+    }
+
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupVmsResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupVmsResource.java
new file mode 100644
index 0000000..19cea5a
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupVmsResource.java
@@ -0,0 +1,80 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+import org.ovirt.engine.api.model.VM;
+import org.ovirt.engine.api.model.VMs;
+import org.ovirt.engine.api.resource.AffinityGroupVmsResource;
+import org.ovirt.engine.api.restapi.utils.GuidUtils;
+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.common.scheduling.AffinityGroup;
+import 
org.ovirt.engine.core.common.scheduling.parameters.AffinityGroupCRUDParameters;
+import org.ovirt.engine.core.compat.Guid;
+
+
+public class BackendAffinityGroupVmsResource extends 
AbstractBackendCollectionResource<VM, 
org.ovirt.engine.core.common.businessentities.VM>
+        implements AffinityGroupVmsResource {
+    private final Guid affinityGroupId;
+
+    public BackendAffinityGroupVmsResource(Guid affinityGroupId) {
+        super(VM.class, 
org.ovirt.engine.core.common.businessentities.VM.class);
+        this.affinityGroupId = affinityGroupId;
+    }
+
+    @Override
+    protected VM doPopulate(VM model, 
org.ovirt.engine.core.common.businessentities.VM entity) {
+        return model;
+    }
+
+    @Override
+    public VMs list() {
+        VMs vms = new VMs();
+        AffinityGroup affinityGroup = getEntity();
+
+        if (affinityGroup.getEntityIds() != null) {
+            for (int i = 0; i < affinityGroup.getEntityIds().size(); i++) {
+                VM vm = new VM();
+                vm.setId(affinityGroup.getEntityIds().get(i).toString());
+                vm.setName(affinityGroup.getEntityNames().get(i));
+                vm = addLinks(populate(vm, null));
+                // remove vm actions, not relevant to this context
+                vm.setActions(null);
+                vms.getVMs().add(vm);
+            }
+        }
+
+        return vms;
+    }
+
+    @Override
+    public Response add(VM vm) {
+        AffinityGroup affinityGroup = getEntity();
+
+        affinityGroup.getEntityIds().add(GuidUtils.asGuid(vm.getId()));
+        return performAction(VdcActionType.EditAffinityGroup, new 
AffinityGroupCRUDParameters(affinityGroup.getId(),
+                affinityGroup));
+    }
+
+    @Override
+    protected Response performRemove(String id) {
+        AffinityGroup affinityGroup = getEntity();
+
+        if (!affinityGroup.getEntityIds().remove(GuidUtils.asGuid(id))) {
+            throw new WebApplicationException(Response.Status.NOT_FOUND);
+        }
+        return performAction(VdcActionType.EditAffinityGroup, new 
AffinityGroupCRUDParameters(affinityGroup.getId(),
+                affinityGroup));
+    }
+
+    @Override
+    protected org.ovirt.engine.core.common.scheduling.AffinityGroup 
getEntity() {
+        return 
getEntity(org.ovirt.engine.core.common.scheduling.AffinityGroup.class,
+                VdcQueryType.GetAffinityGroupById,
+                new IdQueryParameters(affinityGroupId),
+                affinityGroupId.toString());
+    }
+
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupsResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupsResource.java
new file mode 100644
index 0000000..87f5bfd
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupsResource.java
@@ -0,0 +1,74 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import java.util.List;
+
+import javax.ws.rs.core.Response;
+
+import org.ovirt.engine.api.model.AffinityGroup;
+import org.ovirt.engine.api.model.AffinityGroups;
+import org.ovirt.engine.api.resource.AffinityGroupResource;
+import org.ovirt.engine.api.resource.AffinityGroupsResource;
+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.common.scheduling.parameters.AffinityGroupCRUDParameters;
+import org.ovirt.engine.core.compat.Guid;
+
+public class BackendAffinityGroupsResource
+        extends AbstractBackendCollectionResource<AffinityGroup, 
org.ovirt.engine.core.common.scheduling.AffinityGroup>
+        implements AffinityGroupsResource {
+
+    private String clusterId;
+
+    public BackendAffinityGroupsResource(String clusterId) {
+        super(AffinityGroup.class, 
org.ovirt.engine.core.common.scheduling.AffinityGroup.class);
+        this.clusterId = clusterId;
+    }
+
+    @Override
+    public AffinityGroups list() {
+        List<org.ovirt.engine.core.common.scheduling.AffinityGroup> entities =
+                getBackendCollection(VdcQueryType.GetAffinityGroupsByClusterId,
+                        new IdQueryParameters(asGuid(clusterId)));
+        return mapCollection(entities);
+    }
+
+    private AffinityGroups 
mapCollection(List<org.ovirt.engine.core.common.scheduling.AffinityGroup> 
entities) {
+        AffinityGroups collection = new AffinityGroups();
+        for (org.ovirt.engine.core.common.scheduling.AffinityGroup entity : 
entities) {
+            collection.getAffinityGroups().add(addLinks(populate(map(entity), 
entity)));
+        }
+        return collection;
+    }
+
+    @Override
+    public Response add(AffinityGroup affinityGroup) {
+        org.ovirt.engine.core.common.scheduling.AffinityGroup backendEntity =
+                getMapper(AffinityGroup.class, 
org.ovirt.engine.core.common.scheduling.AffinityGroup.class).map(affinityGroup,
+                        null);
+        backendEntity.setClusterId(asGuid(clusterId));
+
+        return performCreate(VdcActionType.AddAffinityGroup,
+                new AffinityGroupCRUDParameters(null, backendEntity),
+                new QueryIdResolver<Guid>(VdcQueryType.GetAffinityGroupById, 
IdQueryParameters.class),
+                true);
+    }
+
+    @Override
+    protected Response performRemove(String id) {
+        AffinityGroupCRUDParameters params = new AffinityGroupCRUDParameters();
+        params.setAffinityGroupId(asGuid(id));
+        return performAction(VdcActionType.RemoveAffinityGroup, params);
+    }
+
+    @Override
+    protected AffinityGroup doPopulate(AffinityGroup model, 
org.ovirt.engine.core.common.scheduling.AffinityGroup entity) {
+        return model;
+    }
+
+    @Override
+    @SingleEntityResource
+    public AffinityGroupResource getAffinityGroupResource(String id) {
+        return inject(new BackendAffinityGroupResource(id));
+    }
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendClusterResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendClusterResource.java
index 0614668..21d1122 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendClusterResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendClusterResource.java
@@ -4,6 +4,7 @@
 import static 
org.ovirt.engine.api.restapi.resource.BackendClustersResource.SUB_COLLECTIONS;
 
 import org.ovirt.engine.api.model.Cluster;
+import org.ovirt.engine.api.resource.AffinityGroupsResource;
 import org.ovirt.engine.api.resource.AssignedNetworksResource;
 import org.ovirt.engine.api.resource.AssignedPermissionsResource;
 import org.ovirt.engine.api.resource.ClusterResource;
@@ -78,4 +79,9 @@
         return inject(new BackendGlusterHooksResource(this));
     }
 
+    @Override
+    public AffinityGroupsResource getAffinityGroupsResource() {
+        return inject(new BackendAffinityGroupsResource(id));
+    }
+
 }
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendClustersResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendClustersResource.java
index 62e847b..fdbd402 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendClustersResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendClustersResource.java
@@ -25,7 +25,8 @@
 public class BackendClustersResource extends 
AbstractBackendCollectionResource<Cluster, VDSGroup>
         implements ClustersResource {
 
-    static final String[] SUB_COLLECTIONS = { "networks", "permissions", 
"glustervolumes", "glusterhooks" };
+    static final String[] SUB_COLLECTIONS = { "networks", "permissions", 
"glustervolumes", "glusterhooks",
+            "affinitygroups" };
     static final String[] VIRT_ONLY_MODE_COLLECTIONS_TO_HIDE = 
{"glustervolumes", "glusterhooks" };
     public BackendClustersResource() {
         super(Cluster.class, VDSGroup.class, SUB_COLLECTIONS);
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupResourceTest.java
 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupResourceTest.java
new file mode 100644
index 0000000..ec61ed2
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupResourceTest.java
@@ -0,0 +1,96 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import static org.easymock.EasyMock.expect;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.Test;
+import org.ovirt.engine.api.model.AffinityGroup;
+import org.ovirt.engine.api.model.Cluster;
+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.common.scheduling.parameters.AffinityGroupCRUDParameters;
+import org.ovirt.engine.core.compat.Guid;
+
+public class BackendAffinityGroupResourceTest extends 
AbstractBackendSubResourceTest<AffinityGroup, 
org.ovirt.engine.core.common.scheduling.AffinityGroup, 
BackendAffinityGroupResource> {
+
+    private static final Guid AFFINITY_GROUP_ID = GUIDS[0];
+    private static final Guid CLUSTER_ID = GUIDS[0];
+
+    public BackendAffinityGroupResourceTest() {
+        super(new BackendAffinityGroupResource(AFFINITY_GROUP_ID.toString()));
+    }
+
+    @Test
+    public void testGet() throws Exception {
+        setUriInfo(setUpBasicUriExpectations());
+        setUpGetEntityExpectations(1, true);
+        control.replay();
+
+        verifyModel(resource.get(), 0);
+    }
+
+    @Test
+    public void testGetNotFound() throws Exception {
+        setUriInfo(setUpBasicUriExpectations());
+        setUpGetEntityExpectations(1, false);
+        control.replay();
+        try {
+            resource.get();
+            fail("expected WebApplicationException");
+        } catch (WebApplicationException wae) {
+            verifyNotFoundException(wae);
+        }
+    }
+
+    @Test
+    public void testUpdate() throws Exception {
+        setUpGetEntityExpectations(2, true);
+
+        setUriInfo(setUpActionExpectations(VdcActionType.EditAffinityGroup,
+                AffinityGroupCRUDParameters.class,
+                new String[] {},
+                new Object[] {},
+                true,
+                true));
+
+        verifyModel(resource.update(getModel(0)), 0);
+    }
+
+    private void setUpGetEntityExpectations(int times, boolean found) throws 
Exception {
+        while (times-- > 0) {
+            setUpGetEntityExpectations(VdcQueryType.GetAffinityGroupById,
+                    IdQueryParameters.class,
+                    new String[] { "Id" },
+                    new Object[] { AFFINITY_GROUP_ID },
+                    found ? getEntity(0) : null);
+        }
+    }
+
+    @Override
+    protected org.ovirt.engine.core.common.scheduling.AffinityGroup 
getEntity(int index) {
+        org.ovirt.engine.core.common.scheduling.AffinityGroup entity =
+                
control.createMock(org.ovirt.engine.core.common.scheduling.AffinityGroup.class);
+        expect(entity.getId()).andReturn(GUIDS[index]).anyTimes();
+        expect(entity.getName()).andReturn(NAMES[index].toString()).anyTimes();
+        
expect(entity.getDescription()).andReturn(DESCRIPTIONS[index].toString()).anyTimes();
+        expect(entity.getClusterId()).andReturn(CLUSTER_ID).anyTimes();
+        expect(entity.isEnforcing()).andReturn(GUIDS[index].hashCode() % 2 == 
0).anyTimes();
+        expect(entity.isPositive()).andReturn(GUIDS[index].hashCode() % 2 == 
1).anyTimes();
+        return entity;
+    }
+
+    static AffinityGroup getModel(int index) {
+        AffinityGroup model = new AffinityGroup();
+        model.setId(GUIDS[0].toString());
+        model.setName(NAMES[index]);
+        model.setDescription(DESCRIPTIONS[index]);
+        model.setCluster(new Cluster());
+        model.getCluster().setId(CLUSTER_ID.toString());
+        model.setEnforcing(GUIDS[index].hashCode() % 2 == 0);
+        model.setPositive(GUIDS[index].hashCode() % 2 == 1);
+
+        return model;
+    }
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupVmsResourceTest.java
 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupVmsResourceTest.java
new file mode 100644
index 0000000..6d4a501
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupVmsResourceTest.java
@@ -0,0 +1,137 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.core.Response;
+
+import org.junit.Test;
+import org.ovirt.engine.api.model.VM;
+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.common.scheduling.parameters.AffinityGroupCRUDParameters;
+import org.ovirt.engine.core.compat.Guid;
+
+public class BackendAffinityGroupVmsResourceTest
+        extends AbstractBackendCollectionResourceTest<VM, 
org.ovirt.engine.core.common.businessentities.VM, 
BackendAffinityGroupVmsResource> {
+
+    private static final Guid AFFINITY_GROUP_ID = Guid.newGuid();
+
+    public BackendAffinityGroupVmsResourceTest() {
+        super(new BackendAffinityGroupVmsResource(AFFINITY_GROUP_ID), null, 
"");
+    }
+
+    @Override
+    protected void setUpQueryExpectations(String query) throws Exception {
+        assert (query.equals(""));
+
+        setUpGetEntityExpectations(true);
+        control.replay();
+    }
+
+    /**
+     * Overriding this as the affinity groups collection doesn't support 
search queries
+     */
+    @Override
+    @Test
+    public void testQuery() throws Exception {
+        testList();
+    }
+
+    @Test
+    public void testAddVMToAffinityGroup() throws Exception {
+        setUriInfo(setUpBasicUriExpectations());
+        setUpGetEntityExpectations(false);
+
+        setUriInfo(setUpActionExpectations(VdcActionType.EditAffinityGroup,
+                AffinityGroupCRUDParameters.class,
+                new String[] {},
+                new Object[] {},
+                true,
+                true));
+
+        VM vm = new VM();
+        vm.setId(GUIDS[0].toString());
+        Response response = collection.add(vm);
+        assertEquals(200, response.getStatus());
+    }
+
+    @Test
+    public void testRemoveVmFromAffinityGroup() throws Exception {
+        setUriInfo(setUpBasicUriExpectations());
+        setUpGetEntityExpectations(true);
+
+        setUriInfo(setUpActionExpectations(VdcActionType.EditAffinityGroup,
+                AffinityGroupCRUDParameters.class,
+                new String[] {},
+                new Object[] {},
+                true,
+                true));
+
+        VM vm = new VM();
+        vm.setId(GUIDS[0].toString());
+        Response response = collection.remove(GUIDS[0].toString());
+        assertEquals(200, response.getStatus());
+    }
+
+    private void setUpGetEntityExpectations(boolean withVms) throws Exception {
+        setUpGetEntityExpectations(VdcQueryType.GetAffinityGroupById,
+                IdQueryParameters.class,
+                new String[] { "Id" },
+                new Object[] { AFFINITY_GROUP_ID },
+                getAffinityGroup(withVms));
+    }
+
+    private org.ovirt.engine.core.common.scheduling.AffinityGroup 
getAffinityGroup(boolean withVms) {
+        org.ovirt.engine.core.common.scheduling.AffinityGroup affinityGroup = 
new org.ovirt.engine.core.common.scheduling.AffinityGroup();
+        affinityGroup.setEntityIds(new ArrayList<Guid>());
+        affinityGroup.setEntityNames(new ArrayList<String>());
+        if (withVms) {
+            for (int i = 0; i < NAMES.length; i++) {
+                org.ovirt.engine.core.common.businessentities.VM entity = 
getEntity(i);
+                affinityGroup.getEntityIds().add(entity.getId());
+                affinityGroup.getEntityNames().add(entity.getName());
+            }
+        }
+
+        return affinityGroup;
+    }
+
+    @Override
+    protected List<VM> getCollection() {
+        return collection.list().getVMs();
+    }
+
+    @Override
+    protected void setUpQueryExpectations(String query, Object failure) throws 
Exception {
+        setUpEntityQueryExpectations(VdcQueryType.GetAffinityGroupById,
+                IdQueryParameters.class,
+                new String[] {},
+                new Object[] {},
+                null,
+                failure);
+
+        control.replay();
+    }
+
+    @Override
+    protected void verifyModel(VM model, int index) {
+        assertEquals(GUIDS[index].toString(), model.getId());
+        assertEquals(NAMES[index], model.getName());
+        // overriding since vm doesn't has description
+        //assertEquals(DESCRIPTIONS[index], model.getDescription());
+        verifyLinks(model);
+    }
+
+    @Override
+    protected org.ovirt.engine.core.common.businessentities.VM getEntity(int 
index) {
+        org.ovirt.engine.core.common.businessentities.VM vm =
+                new org.ovirt.engine.core.common.businessentities.VM();
+        vm.setId(GUIDS[index]);
+        vm.setName(NAMES[index]);
+
+        return vm;
+    }
+
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupsResourceTest.java
 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupsResourceTest.java
new file mode 100644
index 0000000..d3687e8
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendAffinityGroupsResourceTest.java
@@ -0,0 +1,131 @@
+package org.ovirt.engine.api.restapi.resource;
+
+import static org.easymock.EasyMock.expect;
+
+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.AffinityGroup;
+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.common.scheduling.parameters.AffinityGroupCRUDParameters;
+import org.ovirt.engine.core.compat.Guid;
+
+public class BackendAffinityGroupsResourceTest extends 
AbstractBackendCollectionResourceTest<AffinityGroup, 
org.ovirt.engine.core.common.scheduling.AffinityGroup, 
BackendAffinityGroupsResource> {
+    private static final Guid CLUSTER_ID = GUIDS[0];
+
+    public BackendAffinityGroupsResourceTest() {
+        super(new BackendAffinityGroupsResource(CLUSTER_ID.toString()), null, 
"");
+    }
+
+    @Override
+    protected void setUpQueryExpectations(String query, Object failure) throws 
Exception {
+        assert (query.equals(""));
+
+        setUpEntityQueryExpectations(VdcQueryType.GetAffinityGroupsByClusterId,
+                IdQueryParameters.class,
+                new String[] {},
+                new Object[] {},
+                setUpAffinityGroups(),
+                failure);
+
+        control.replay();
+    }
+
+
+    @Override
+    protected List<AffinityGroup> getCollection() {
+        return collection.list().getAffinityGroups();
+    }
+
+    @Override
+    protected org.ovirt.engine.core.common.scheduling.AffinityGroup 
getEntity(int index) {
+        org.ovirt.engine.core.common.scheduling.AffinityGroup entity =
+                
control.createMock(org.ovirt.engine.core.common.scheduling.AffinityGroup.class);
+        expect(entity.getId()).andReturn(GUIDS[index]).anyTimes();
+        expect(entity.getName()).andReturn(NAMES[index].toString()).anyTimes();
+        
expect(entity.getDescription()).andReturn(DESCRIPTIONS[index].toString()).anyTimes();
+        expect(entity.getClusterId()).andReturn(CLUSTER_ID).anyTimes();
+        expect(entity.isEnforcing()).andReturn(GUIDS[index].hashCode() % 2 == 
0).anyTimes();
+        expect(entity.isPositive()).andReturn(GUIDS[index].hashCode() % 2 == 
1).anyTimes();
+        return entity;
+    }
+
+    /**
+     * Overriding this as the affinity groups collection doesn't support 
search queries
+     */
+    @Override
+    @Test
+    public void testQuery() throws Exception {
+        testList();
+    }
+
+    @Test
+    public void testAdd() {
+        setUriInfo(setUpBasicUriExpectations());
+        setUpCreationExpectations(VdcActionType.AddAffinityGroup,
+                AffinityGroupCRUDParameters.class,
+                new String[] {},
+                new Object[] {},
+                true,
+                true,
+                GUIDS[0],
+                VdcQueryType.GetAffinityGroupById,
+                IdQueryParameters.class,
+                new String[] { "Id" },
+                new Object[] { GUIDS[0] },
+                getEntity(0));
+        Response response = collection.add(new AffinityGroup());
+        assertEquals(201, response.getStatus());
+        assertTrue(response.getEntity() instanceof AffinityGroup);
+        verifyModel((AffinityGroup) response.getEntity(), 0);
+    }
+
+    @Test
+    public void testRemove() throws Exception {
+        setUriInfo(setUpBasicUriExpectations());
+        setUpGetEntityExpectations(GUIDS[0], false);
+        setUpActionExpectations(VdcActionType.RemoveAffinityGroup,
+                AffinityGroupCRUDParameters.class,
+                new String[] { "AffinityGroupId" },
+                new Object[] { GUIDS[0] },
+                true,
+                true);
+        verifyRemove(collection.remove(GUIDS[0].toString()));
+    }
+
+    @Test
+    public void testRemoveNonExistant() throws Exception {
+        setUpGetEntityExpectations(NON_EXISTANT_GUID, true);
+        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 setUpGetEntityExpectations(Guid entityId, Boolean returnNull) 
throws Exception {
+        setUpGetEntityExpectations(VdcQueryType.GetAffinityGroupById,
+                IdQueryParameters.class,
+                new String[] { "Id" },
+                new Object[] { entityId },
+                returnNull ? null : getEntity(0));
+    }
+
+    private List<org.ovirt.engine.core.common.scheduling.AffinityGroup> 
setUpAffinityGroups() {
+        List<org.ovirt.engine.core.common.scheduling.AffinityGroup> list = new 
ArrayList<>();
+        for (int i = 0; i < NAMES.length; i++) {
+            list.add(getEntity(i));
+        }
+
+        return list;
+    }
+}
diff --git 
a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/AffinityGroupMapper.java
 
b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/AffinityGroupMapper.java
new file mode 100644
index 0000000..008d97f
--- /dev/null
+++ 
b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/AffinityGroupMapper.java
@@ -0,0 +1,51 @@
+package org.ovirt.engine.api.restapi.types;
+
+import org.ovirt.engine.api.model.AffinityGroup;
+import org.ovirt.engine.api.model.Cluster;
+import org.ovirt.engine.api.restapi.utils.GuidUtils;
+
+public class AffinityGroupMapper {
+
+    @Mapping(from = 
org.ovirt.engine.core.common.scheduling.AffinityGroup.class, to = 
AffinityGroup.class)
+    public static AffinityGroup 
map(org.ovirt.engine.core.common.scheduling.AffinityGroup entity,
+            AffinityGroup template) {
+        AffinityGroup model = template != null ? template : new 
AffinityGroup();
+        model.setId(entity.getId().toString());
+        model.setName(entity.getName());
+        model.setDescription(entity.getDescription());
+        model.setPositive(entity.isPositive());
+        model.setEnforcing(entity.isEnforcing());
+        Cluster cluster = new Cluster();
+        cluster.setId(entity.getClusterId().toString());
+        model.setCluster(cluster);
+
+        return model;
+    }
+
+    @Mapping(from = AffinityGroup.class, to = 
org.ovirt.engine.core.common.scheduling.AffinityGroup.class)
+    public static org.ovirt.engine.core.common.scheduling.AffinityGroup 
map(AffinityGroup model,
+            org.ovirt.engine.core.common.scheduling.AffinityGroup template) {
+        org.ovirt.engine.core.common.scheduling.AffinityGroup entity =
+                template != null ? template : new 
org.ovirt.engine.core.common.scheduling.AffinityGroup();
+        if (model.isSetId()) {
+            entity.setId(GuidUtils.asGuid(model.getId()));
+        }
+        if (model.isSetName()) {
+            entity.setName(model.getName());
+        }
+        if (model.isSetDescription()) {
+            entity.setDescription(model.getDescription());
+        }
+        if (model.isSetCluster() && model.getCluster().isSetId()) {
+            entity.setClusterId(GuidUtils.asGuid(model.getCluster().getId()));
+        }
+        if (model.isSetPositive()) {
+            entity.setPositive(model.isPositive());
+        }
+        if (model.isSetEnforcing()) {
+            entity.setEnforcing(model.isEnforcing());
+        }
+
+        return entity;
+    }
+}
diff --git 
a/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/AffinityGroupMapperTest.java
 
b/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/AffinityGroupMapperTest.java
new file mode 100644
index 0000000..38921187
--- /dev/null
+++ 
b/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/AffinityGroupMapperTest.java
@@ -0,0 +1,24 @@
+package org.ovirt.engine.api.restapi.types;
+
+import org.ovirt.engine.api.model.AffinityGroup;
+
+public class AffinityGroupMapperTest extends 
AbstractInvertibleMappingTest<AffinityGroup, 
org.ovirt.engine.core.common.scheduling.AffinityGroup, 
org.ovirt.engine.core.common.scheduling.AffinityGroup> {
+
+    public AffinityGroupMapperTest() {
+        super(AffinityGroup.class,
+                org.ovirt.engine.core.common.scheduling.AffinityGroup.class,
+                org.ovirt.engine.core.common.scheduling.AffinityGroup.class);
+    }
+
+    @Override
+    protected void verify(AffinityGroup model, AffinityGroup transform) {
+        assertNotNull(transform);
+        assertEquals(model.getName(), transform.getName());
+        assertEquals(model.getId(), transform.getId());
+        assertEquals(model.getDescription(), transform.getDescription());
+        assertEquals(model.getCluster().getId(), 
transform.getCluster().getId());
+        assertEquals(model.isPositive(), transform.isPositive());
+        assertEquals(model.isEnforcing(), transform.isEnforcing());
+    }
+
+}


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie2daa18742eca73517ef739e70e972d74aad4244
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Gilad Chaplik <gchap...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to