Shubhendu Tripathi has uploaded a new change for review.

Change subject: restapi: WIP: REST Migrate brick data and delete
......................................................................

restapi: WIP: REST Migrate brick data and delete

Migreates the brick data to other existing bricks and then deletes it
from the volumes.

Its different from the normal brick deletion in the sense that normal
delete works as force delete and removes the bricks from the volume
without any data migration. Whereas this option would migrate the data
first and then delete the brick from volume.

Usage:
    - api/clusters/<cluster-Id>/glustervolumes/<volume-id>/bricks/migrate

Input Parameters:
    <action>
        <bricks>
            <brick name="brick1-name" />
            <brick name="brick2-name" />
            .
            .
            .
        </bricks>
    </action>

Change-Id: Iaa88f3402a25316d1717ee914aa77856fbe802db
Signed-off-by: Shubhendu Tripathi <[email protected]>
---
M 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/gluster/GlusterBricksResource.java
M 
backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterBricksResource.java
M 
backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterBricksResourceTest.java
4 files changed, 119 insertions(+), 43 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/00/19400/1

diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/gluster/GlusterBricksResource.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/gluster/GlusterBricksResource.java
index 6ec9930..faf9a9d 100644
--- 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/gluster/GlusterBricksResource.java
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/gluster/GlusterBricksResource.java
@@ -13,7 +13,10 @@
 import javax.ws.rs.core.Response;
 
 import org.jboss.resteasy.annotations.providers.jaxb.Formatted;
+import org.ovirt.engine.api.model.Action;
+import org.ovirt.engine.api.model.Actionable;
 import org.ovirt.engine.api.model.GlusterBricks;
+import org.ovirt.engine.api.resource.ActionResource;
 import org.ovirt.engine.api.resource.ApiMediaType;
 import org.ovirt.engine.api.resource.RsdlIgnore;
 
@@ -22,6 +25,9 @@
  */
 @Produces({ ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, 
ApiMediaType.APPLICATION_X_YAML })
 public interface GlusterBricksResource {
+    @Path("{action: (migrate)}")
+    public ActionResource getActionSubresource(@PathParam("action") String 
action);
+
     @GET
     @Formatted
     public GlusterBricks list();
@@ -72,4 +78,12 @@
      */
     @Path("{brick_id}")
     public GlusterBrickResource 
getGlusterBrickSubResource(@PathParam("brick_id") String id);
+
+    @POST
+    @Formatted
+    @Consumes({ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, 
ApiMediaType.APPLICATION_X_YAML})
+    @Actionable
+    @Path("migrate")
+    public Response migrate(Action action);
+
 }
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 41df119..9b9402b 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
@@ -189,6 +189,8 @@
       <xs:element name="succeeded" type="xs:boolean" minOccurs="0"/>
       <!-- resolve GlusterHook using one of the resolution -->
       <xs:element name="resolution_type" type="xs:string" minOccurs="0" 
maxOccurs="1"/>
+      <!-- list of bricks to be migrated -->
+      <xs:element ref="bricks" minOccurs="0" />
       <!-- ... etc., explicitly enumerate all the parameter types -->
     </xs:sequence>
   </xs:group>
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterBricksResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterBricksResource.java
index 651dc3d..4cc8e10 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterBricksResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterBricksResource.java
@@ -6,13 +6,16 @@
 
 import javax.ws.rs.core.Response;
 
+import org.ovirt.engine.api.model.Action;
 import org.ovirt.engine.api.model.Cluster;
 import org.ovirt.engine.api.model.GlusterBrick;
 import org.ovirt.engine.api.model.GlusterBricks;
 import org.ovirt.engine.api.model.GlusterVolume;
+import org.ovirt.engine.api.resource.ActionResource;
 import org.ovirt.engine.api.resource.gluster.GlusterBrickResource;
 import org.ovirt.engine.api.resource.gluster.GlusterBricksResource;
 import org.ovirt.engine.api.restapi.resource.AbstractBackendCollectionResource;
+import org.ovirt.engine.api.restapi.resource.BackendActionResource;
 import org.ovirt.engine.core.common.action.VdcActionParametersBase;
 import org.ovirt.engine.core.common.action.VdcActionType;
 import org.ovirt.engine.core.common.action.VdcReturnValueBase;
@@ -29,7 +32,7 @@
 public class BackendGlusterBricksResource
         extends AbstractBackendCollectionResource<GlusterBrick, 
GlusterBrickEntity>
         implements GlusterBricksResource {
-    static final String[] SUB_COLLECTIONS = {"statistics"};
+    static final String[] SUB_COLLECTIONS = { "statistics" };
 
     private BackendGlusterVolumeResource parent;
 
@@ -38,7 +41,7 @@
     }
 
     public BackendGlusterBricksResource(BackendGlusterVolumeResource parent) {
-        super(GlusterBrick.class, GlusterBrickEntity.class,SUB_COLLECTIONS);
+        super(GlusterBrick.class, GlusterBrickEntity.class, SUB_COLLECTIONS);
         setParent(parent);
     }
 
@@ -53,7 +56,7 @@
     private GlusterBricks mapCollection(List<GlusterBrickEntity> entities) {
         GlusterBricks collection = new GlusterBricks();
         for (GlusterBrickEntity entity : entities) {
-            collection.getGlusterBricks().add(addLinks(populate(map(entity), 
entity),Cluster.class));
+            collection.getGlusterBricks().add(addLinks(populate(map(entity), 
entity), Cluster.class));
         }
         return collection;
     }
@@ -102,7 +105,7 @@
     protected GlusterBricks resolveCreatedList(VdcReturnValueBase result, 
EntityIdResolver<Guid> entityResolver) {
         try {
             GlusterBricks bricks = new GlusterBricks();
-            for(Guid id : (List<Guid>)result.getActionReturnValue()) {
+            for (Guid id : (List<Guid>) result.getActionReturnValue()) {
                 GlusterBrickEntity created = entityResolver.resolve(id);
                 
bricks.getGlusterBricks().add(addLinks(doPopulate(map(created), created)));
             }
@@ -146,7 +149,9 @@
         }
         int replicaCount = bricks.isSetReplicaCount() ? 
bricks.getReplicaCount() : 0;
         return performAction(VdcActionType.GlusterVolumeRemoveBricks,
-                new GlusterVolumeRemoveBricksParameters(asGuid(getVolumeId()), 
mapBricks(asGuid(getVolumeId()), bricks), replicaCount));
+                new GlusterVolumeRemoveBricksParameters(asGuid(getVolumeId()),
+                        mapBricks(asGuid(getVolumeId()), bricks),
+                        replicaCount));
     }
 
     @Override
@@ -179,24 +184,53 @@
     protected GlusterBrick populateAdvancedDetails(GlusterBrick model, 
GlusterBrickEntity entity) {
 
         GlusterVolumeEntity volumeEntity = getEntity(GlusterVolumeEntity.class,
-                                                     
VdcQueryType.GetGlusterVolumeById,
-                                                     new 
IdQueryParameters(entity.getVolumeId()),
-                                                     null,
-                                                     true);
+                VdcQueryType.GetGlusterVolumeById,
+                new IdQueryParameters(entity.getVolumeId()),
+                null,
+                true);
 
         GlusterVolumeAdvancedDetails detailsEntity = 
getEntity(GlusterVolumeAdvancedDetails.class,
-                                                
VdcQueryType.GetGlusterVolumeAdvancedDetails,
-                                                new 
GlusterVolumeAdvancedDetailsParameters(volumeEntity.getClusterId(),
-                                                                               
            volumeEntity.getId(),
-                                                                               
            entity.getId(),true),
-                                                null,
-                                                true);
+                VdcQueryType.GetGlusterVolumeAdvancedDetails,
+                new 
GlusterVolumeAdvancedDetailsParameters(volumeEntity.getClusterId(),
+                        volumeEntity.getId(),
+                        entity.getId(), true),
+                null,
+                true);
 
         model = getMapper(GlusterVolumeAdvancedDetails.class, 
GlusterBrick.class)
-                                                        .map(detailsEntity, 
model);
+                .map(detailsEntity, model);
 
         return model;
 
     }
 
+    private GlusterVolumeRemoveBricksParameters toParameters(Action action) {
+        GlusterVolumeRemoveBricksParameters params = new 
GlusterVolumeRemoveBricksParameters();
+
+        List<GlusterBrickEntity> entityBricks = new 
ArrayList<GlusterBrickEntity>();
+        for (GlusterBrick brick : action.getBricks().getGlusterBricks()) {
+            GlusterBrickEntity entity = new GlusterBrickEntity();
+            entity.setBrickDirectory(brick.getBrickDir());
+            entity.setVolumeId(new Guid(getVolumeId()));
+            entity.setId(new Guid(brick.getId()));
+            entityBricks.add(entity);
+        }
+        params.setVolumeId(new Guid(getVolumeId()));
+        params.setBricks(entityBricks);
+        params.setCommandType(VdcActionType.StartRemoveGlusterVolumeBricks);
+
+        return params;
+    }
+
+    @Override
+    public Response migrate(Action action) {
+        validateParameters(action, "bricks");
+        GlusterVolumeRemoveBricksParameters params = toParameters(action);
+        return performAction(VdcActionType.StartRemoveGlusterVolumeBricks, 
params);
+    }
+
+    @Override
+    public ActionResource getActionSubresource(String action) {
+        return inject(new BackendActionResource(action, ""));
+    }
 }
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterBricksResourceTest.java
 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterBricksResourceTest.java
index ef36816..7bf419e 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterBricksResourceTest.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterBricksResourceTest.java
@@ -1,6 +1,5 @@
 package org.ovirt.engine.api.restapi.resource.gluster;
 
-
 import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
@@ -11,6 +10,7 @@
 import static 
org.ovirt.engine.api.restapi.resource.gluster.GlusterTestHelper.volumeId;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import javax.ws.rs.WebApplicationException;
@@ -18,6 +18,7 @@
 import javax.ws.rs.core.UriInfo;
 
 import org.junit.Test;
+import org.ovirt.engine.api.model.Action;
 import org.ovirt.engine.api.model.Cluster;
 import org.ovirt.engine.api.model.Fault;
 import org.ovirt.engine.api.model.GlusterBrick;
@@ -49,8 +50,7 @@
     }
 
     /**
-     * Override init to perform additional mocking required
-     * for the "list" method of the collection resource.
+     * Override init to perform additional mocking required for the "list" 
method of the collection resource.
      */
     @Override
     protected void init() {
@@ -148,26 +148,25 @@
         }
     }
 
-
     @Test
     public void testAdd() throws Exception {
         UriInfo uriInfo = setUpBasicUriExpectations();
         expect(uriInfo.getPath()).andReturn("clusters/" + clusterId + 
"/glustervolumes/" + volumeId + "/bricks")
                 .anyTimes();
         setUriInfo(uriInfo);
-        setupEntityExpectationAdvancedDetails(1,false);
+        setupEntityExpectationAdvancedDetails(1, false);
         setUpCreationExpectations(VdcActionType.AddBricksToGlusterVolume,
-                                  GlusterVolumeBricksActionParameters.class,
-                                  new String[] { "VolumeId", "Bricks" },
-                                  new Object[] { volumeId, getBricks() },
-                                  true,
-                                  true,
-                                  getBrickIds(),
-                                  VdcQueryType.GetGlusterBrickById,
-                                  IdQueryParameters.class,
-                                  new String[] { "Id" },
-                                  new Object[] { GUIDS[0] },
-                                  getEntity(0));
+                GlusterVolumeBricksActionParameters.class,
+                new String[] { "VolumeId", "Bricks" },
+                new Object[] { volumeId, getBricks() },
+                true,
+                true,
+                getBrickIds(),
+                VdcQueryType.GetGlusterBrickById,
+                IdQueryParameters.class,
+                new String[] { "Id" },
+                new Object[] { GUIDS[0] },
+                getEntity(0));
         Response response = collection.add(createModel());
         assertEquals(201, response.getStatus());
         assertTrue(response.getEntity() instanceof GlusterBricks);
@@ -178,11 +177,39 @@
     public void testRemove() throws Exception {
         
setUriInfo(setUpActionExpectations(VdcActionType.GlusterVolumeRemoveBricks,
                 GlusterVolumeRemoveBricksParameters.class,
-                                           new String[] { "VolumeId", "Bricks" 
},
-                                           new Object[] { volumeId, 
getBricksToRemove() },
-                                           true,
-                                           true));
+                new String[] { "VolumeId", "Bricks" },
+                new Object[] { volumeId, getBricksToRemove() },
+                true,
+                true));
         verifyRemove(collection.remove(GUIDS[0].toString()));
+    }
+
+    @Test
+    public void testMigrate() throws Exception {
+        GlusterBrick brick = new GlusterBrick();
+        GlusterVolume volume = new GlusterVolume();
+        brick.setId(GUIDS[0].toString());
+        brick.setBrickDir(brickDir);
+        brick.setServerId(serverId.toString());
+        volume.setId(volumeId.toString());
+        brick.setGlusterVolume(volume);
+
+        GlusterBricks bricks = control.createMock(GlusterBricks.class);
+        
expect(bricks.getGlusterBricks()).andReturn(Collections.singletonList(brick)).anyTimes();
+
+        
setUriInfo(setUpActionExpectations(VdcActionType.StartRemoveGlusterVolumeBricks,
+                GlusterVolumeRemoveBricksParameters.class,
+//                new String [] {"VolumeId", "Bricks"},
+//                new Object[] {volumeId, getBricksToRemove()},
+              new String [] {},
+              new Object[] {},
+
+                true,
+                true));
+
+        Action action = new Action();
+        action.setBricks(bricks);
+        collection.migrate(action);
     }
 
     /**
@@ -248,10 +275,9 @@
     }
 
     /**
-     * The method {@link BackendGlusterBricksResource#list()} internally
-     * invokes {@link BackendGlusterVolumeResource#get()} to fetch the volume 
object,
-     * and then invokes the query to fetch the bricks of that volume.
-     * This method mocks the volume resource to return pre-defined volume id
+     * The method {@link BackendGlusterBricksResource#list()} internally 
invokes
+     * {@link BackendGlusterVolumeResource#get()} to fetch the volume object, 
and then invokes the query to fetch the
+     * bricks of that volume. This method mocks the volume resource to return 
pre-defined volume id
      */
     private void setUpParentMocks() {
         GlusterVolume volume = new GlusterVolume();
@@ -285,7 +311,6 @@
                         return model;
                     }
 
-
                 }).anyTimes();
 
     }
@@ -303,9 +328,10 @@
         } else {
             if (failure instanceof String) {
                 expect(queryResult.getExceptionString()).andReturn((String) 
failure).anyTimes();
-                setUpL10nExpectations((String)failure);
+                setUpL10nExpectations((String) failure);
             } else if (failure instanceof Exception) {
-                
expect(backend.RunQuery(eq(VdcQueryType.GetGlusterVolumeBricks), 
anyObject(IdQueryParameters.class))).andThrow((Exception) failure).anyTimes();
+                
expect(backend.RunQuery(eq(VdcQueryType.GetGlusterVolumeBricks), 
anyObject(IdQueryParameters.class))).andThrow((Exception) failure)
+                        .anyTimes();
                 return;
             }
         }


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

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

Reply via email to