Alissa Bonas has uploaded a new change for review.

Change subject: restapi: add template versions support
......................................................................

restapi: add template versions support

Add to templates REST resource a new section that
describes template version details.
The user will be able to add this in POST (add template),
update version name in PUT (update) and see version details in
GET requests.

Feature page:
http://www.ovirt.org/Features/Template_Versions

Change-Id: Id8e4c498c4a1856ac341237837db40db8375c6da
Signed-off-by: Alissa Bonas <[email protected]>
---
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/BackendTemplatesResource.java
M 
backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendTemplatesResourceTest.java
M 
backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/TemplateMapper.java
M 
backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/TemplateMapperTest.java
6 files changed, 155 insertions(+), 13 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/19/25019/1

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 a849751..5e6d86f 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
@@ -479,6 +479,14 @@
     </xs:sequence>
   </xs:complexType>
 
+  <xs:complexType name="TemplateVersion">
+    <xs:sequence>
+       <xs:element name="base_template" type="Template"  minOccurs="0" 
maxOccurs="1"/>
+       <xs:element name="version_number" type="xs:int"  minOccurs="0" 
maxOccurs="1" />
+       <xs:element name="version_name" type="xs:string"  minOccurs="0" 
maxOccurs="1"/>
+    </xs:sequence>
+  </xs:complexType>
+
   <!-- Version numbers -->
 
   <xs:element name="system_version" type="Version"/>
@@ -2308,6 +2316,7 @@
           <xs:element ref="virtio_scsi" minOccurs="0" maxOccurs="1"/>
           <xs:element ref="permissions" minOccurs="0" maxOccurs="1"/>
           <!-- also rel="cdroms/disks/nics/watchdogs" links, see Devices below 
-->
+          <xs:element name="version" type="TemplateVersion" minOccurs="0" 
maxOccurs="1"/>
         </xs:sequence>
       </xs:extension>
     </xs:complexContent>
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 dd314bb..89d19a9 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
@@ -3365,6 +3365,7 @@
           template.tunnel_migration: xs:boolean
           template.migration_downtime: xs:int
           template.virtio_scsi.enabled: xs:boolean
+          template.version.version_name: xs:string
         description: update the specified template in the system
     urlparams: {}
     headers:
@@ -3415,6 +3416,8 @@
           template.virtio_scsi.enabled: xs:boolean
           template.vm.disks.disk--COLLECTION: {disk.id: 'xs:string', 
storage_domains.storage_domain--COLLECTION: {storage_domain.id: 'xs:string'}}
           template.permissions.clone: xs:boolean
+          template.version.version_name: xs:string
+          template.version.base_template.id: xs:string
           template.cpu.cpu_tune.vcpu_pin--COLLECTION: {vcpu_pin.vcpu: 
'xs:int', vcpu_pin.cpu_set: 'xs:string'}
         description: add a new template to the system
     urlparams: {}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendTemplatesResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendTemplatesResource.java
index 2dd9677..2010020 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendTemplatesResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendTemplatesResource.java
@@ -66,6 +66,9 @@
             clusterId = getClusterId(template);
             cluster = lookupCluster(clusterId);
         }
+        if (template.getVersion() != null) {
+            validateParameters(template.getVersion(), "baseTemplate");
+        }
         VmStatic staticVm = getMapper(Template.class, 
VmStatic.class).map(template, getVm(cluster, template));
         if (namedCluster(template)) {
             staticVm.setVdsGroupId(clusterId);
@@ -78,6 +81,10 @@
         AddVmTemplateParameters params = new AddVmTemplateParameters(staticVm,
                                        template.getName(),
                                        template.getDescription());
+        if (template.getVersion() != null) {
+            
params.setBaseTemplateId(Guid.createGuidFromString(template.getVersion().getBaseTemplate().getId()));
+            
params.setTemplateVersionName(template.getVersion().getVersionName());
+        }
         params.setConsoleEnabled(template.getConsole() != null && 
template.getConsole().isSetEnabled() ?
                         template.getConsole().isEnabled() :
                         
!getConsoleDevicesForEntity(staticVm.getId()).isEmpty());
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendTemplatesResourceTest.java
 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendTemplatesResourceTest.java
index d4e930b..3d1dac8 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendTemplatesResourceTest.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendTemplatesResourceTest.java
@@ -4,17 +4,17 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response;
-
 import javax.ws.rs.core.UriInfo;
+
 import org.easymock.EasyMock;
 import org.junit.Test;
 import org.ovirt.engine.api.model.Cluster;
 import org.ovirt.engine.api.model.CreationStatus;
 import org.ovirt.engine.api.model.Permissions;
 import org.ovirt.engine.api.model.Template;
+import org.ovirt.engine.api.model.TemplateVersion;
 import org.ovirt.engine.api.model.VM;
 import org.ovirt.engine.api.restapi.util.VmHelper;
 import org.ovirt.engine.core.common.action.AddVmTemplateParameters;
@@ -35,6 +35,7 @@
     extends AbstractBackendCollectionResourceTest<Template, VmTemplate, 
BackendTemplatesResource> {
 
     protected VmHelper vmHelper = VmHelper.getInstance();
+    private static final String VERSION_NAME = "my new version";
 
     public BackendTemplatesResourceTest() {
         super(new BackendTemplatesResource(), SearchType.VmTemplate, "Template 
: ");
@@ -69,7 +70,7 @@
                 new String[] { "Id" },
                 new Object[] { GUIDS[1] },
                 setUpVm(GUIDS[1]));
-        setUpGetEntityExpectations();
+        setUpGetEntityExpectations(0);
         setUpGetConsoleExpectations(new int[]{0, 0, 0});
         setUpGetVirtioScsiExpectations(new int[]{0, 0});
         setUpEntityQueryExpectations(VdcQueryType.GetVdsGroupByVdsGroupId,
@@ -102,7 +103,7 @@
 
     @Test
     public void testRemove() throws Exception {
-        setUpGetEntityExpectations();
+        setUpGetEntityExpectations(0);
         setUriInfo(setUpActionExpectations(VdcActionType.RemoveVmTemplate,
                                            VmTemplateParametersBase.class,
                                            new String[] { "VmTemplateId" },
@@ -129,12 +130,12 @@
         }
     }
 
-    private void setUpGetEntityExpectations() throws Exception {
+    private void setUpGetEntityExpectations(int index) throws Exception {
         setUpGetEntityExpectations(VdcQueryType.GetVmTemplate,
                 GetVmTemplateParameters.class,
                 new String[] { "Id" },
-                new Object[] { GUIDS[0] },
-                getEntity(0));
+                new Object[] { GUIDS[index] },
+                getEntity(index));
     }
 
     @Test
@@ -152,7 +153,7 @@
     }
 
     protected void doTestBadRemove(boolean canDo, boolean success, String 
detail) throws Exception {
-        setUpGetEntityExpectations();
+        setUpGetEntityExpectations(0);
         setUriInfo(setUpActionExpectations(VdcActionType.RemoveVmTemplate,
                                            VmTemplateParametersBase.class,
                                            new String[] { "VmTemplateId" },
@@ -235,7 +236,7 @@
                                    new String[] { "Id" },
                                    new Object[] { GUIDS[1] },
                                    setUpVm(GUIDS[1]));
-        setUpGetEntityExpectations();
+        setUpGetEntityExpectations(0);
         setUpEntityQueryExpectations(VdcQueryType.GetVdsGroupByVdsGroupId,
                 IdQueryParameters.class,
                 new String[] { "Id" },
@@ -265,6 +266,64 @@
     }
 
     @Test
+    public void testAddVersionNoBaseTemplateId() throws Exception {
+       setUriInfo(setUpBasicUriExpectations());
+       control.replay();
+       Template t = getModel(2);
+       t.getVersion().setBaseTemplate(null);
+       try {
+         collection.add(t);
+         fail("Should have failed with 400 error due to a missing base 
template");
+       }
+       catch (WebApplicationException e) {
+            assertNotNull(e.getResponse());
+            assertEquals(400, e.getResponse().getStatus());
+        }
+    }
+
+    @Test
+    public void testAddVersion() throws Exception {
+            setUriInfo(setUpBasicUriExpectations());
+            setUpHttpHeaderExpectations("Expect", "201-created");
+
+            setUpGetConsoleExpectations(new int[]{2, 0, 2});
+            setUpGetVirtioScsiExpectations(new int[]{2, 2});
+            setUpGetEntityExpectations(VdcQueryType.GetVmByVmId,
+                                       IdQueryParameters.class,
+                                       new String[] { "Id" },
+                                       new Object[] { GUIDS[1] },
+                                       setUpVm(GUIDS[1]));
+            setUpGetEntityExpectations(2);
+            setUpEntityQueryExpectations(VdcQueryType.GetVdsGroupByVdsGroupId,
+                    IdQueryParameters.class,
+                    new String[] { "Id" },
+                    new Object[] { GUIDS[2] },
+                    getVdsGroupEntity());
+
+            setUpCreationExpectations(VdcActionType.AddVmTemplate,
+                                      AddVmTemplateParameters.class,
+                                      new String[] { "Name", "Description" },
+                                      new Object[] { NAMES[2], DESCRIPTIONS[2] 
},
+                                      true,
+                                      true,
+                                      GUIDS[2],
+                                      asList(GUIDS[2]),
+                                      asList(new 
AsyncTaskStatus(AsyncTaskStatusEnum.finished)),
+                                      VdcQueryType.GetVmTemplate,
+                                      GetVmTemplateParameters.class,
+                                      new String[] { "Id" },
+                                      new Object[] { GUIDS[2] },
+                                      getEntity(2));
+
+            Response response = collection.add(getModel(2));
+            assertEquals(201, response.getStatus());
+            assertTrue(response.getEntity() instanceof Template);
+            assertEquals(((Template) 
response.getEntity()).getVersion().getVersionName(), VERSION_NAME);
+            assertEquals(((Template) 
response.getEntity()).getVersion().getBaseTemplate().getId(), 
GUIDS[1].toString());
+            verifyModel((Template)response.getEntity(), 2);
+    }
+
+    @Test
     public void testAddNamedVm() throws Exception {
         setUriInfo(setUpBasicUriExpectations());
         setUpEntityQueryExpectations(VdcQueryType.GetVdsGroupByVdsGroupId,
@@ -278,7 +337,7 @@
         setUpGetEntityExpectations("VM: name=" + NAMES[1],
                                    SearchType.VM,
                                    setUpVm(GUIDS[1]));
-        setUpGetEntityExpectations();
+        setUpGetEntityExpectations(0);
         setUpGetConsoleExpectations(new int[] {0, 0, 0});
         setUpGetVirtioScsiExpectations(new int[] {0, 0});
 
@@ -326,7 +385,7 @@
                                    new Object[] { NAMES[1] },
                                    setUpVm(GUIDS[1]));
 
-        setUpGetEntityExpectations();
+        setUpGetEntityExpectations(0);
         setUpGetConsoleExpectations(new int[] {0, 0, 0});
         setUpGetVirtioScsiExpectations(new int[] {0, 0});
 
@@ -372,7 +431,7 @@
                                    new String[] { "Id" },
                                    new Object[] { GUIDS[1] },
                                    setUpVm(GUIDS[1]));
-        setUpGetEntityExpectations();
+        setUpGetEntityExpectations(0);
 
         setUpGetConsoleExpectations(new int[] {0, 0, 0});
         setUpGetVirtioScsiExpectations(new int[] {0, 0});
@@ -418,7 +477,7 @@
                                    new String[] { "Id" },
                                    new Object[] { GUIDS[1] },
                                    setUpVm(GUIDS[1]));
-        setUpGetEntityExpectations();
+        setUpGetEntityExpectations(0);
 
         setUpGetConsoleExpectations(new int[] {0, 0, 0});
         setUpGetVirtioScsiExpectations(new int[] {0, 0});
@@ -532,6 +591,18 @@
         
expect(entity.getDescription()).andReturn(DESCRIPTIONS[index]).anyTimes();
         expect(entity.getNumOfCpus()).andReturn(8).anyTimes();
         expect(entity.getNumOfSockets()).andReturn(2).anyTimes();
+        if(index == 2) {
+           
expect(entity.getTemplateVersionName()).andReturn(VERSION_NAME).anyTimes();
+           expect(entity.getTemplateVersionNumber()).andReturn(2).anyTimes();
+           expect(entity.getBaseTemplateId()).andReturn(GUIDS[1]).anyTimes();
+           expect(entity.isBaseTemplate()).andReturn(false).anyTimes();
+        }
+        else {
+            expect(entity.getTemplateVersionNumber()).andReturn(1).anyTimes();
+            // same base template id as the template itself
+            
expect(entity.getBaseTemplateId()).andReturn(GUIDS[index]).anyTimes();
+            expect(entity.isBaseTemplate()).andReturn(true).anyTimes();
+        }
         return entity;
     }
 
@@ -543,7 +614,20 @@
         model.getVm().setId(GUIDS[1].toString());
         model.setCluster(new Cluster());
         model.getCluster().setId(GUIDS[2].toString());
+        if(index == 2) {
+            populateVersion(model);
+        }
         return model;
+    }
+
+    public static void populateVersion(Template t) {
+        TemplateVersion templateVersion = new TemplateVersion();
+        templateVersion.setVersionName(VERSION_NAME);
+        templateVersion.setVersionNumber(2);
+        Template base = new Template();
+        base.setId(GUIDS[1].toString());
+        templateVersion.setBaseTemplate(base);
+        t.setVersion(templateVersion);
     }
 
     @Override
@@ -586,6 +670,14 @@
 
         for (Template template : collection) {
             assertTrue(populated ? template.isSetConsole() : 
!template.isSetConsole());
+            if(template.getId().equals(GUIDS[2].toString())) {
+                 assertEquals(template.getVersion().getVersionName(), 
VERSION_NAME);
+                 assertEquals(template.getVersion().getVersionNumber(), new 
Integer(2));
+                 assertEquals(template.getVersion().getBaseTemplate().getId(), 
GUIDS[1].toString());
+            }
+            else {
+                assertNull(template.getVersion());
+            }
         }
     }
 
@@ -602,6 +694,10 @@
         assertNotNull(model.getCpu().getTopology());
         assertEquals(4, model.getCpu().getTopology().getCores().intValue());
         assertEquals(2, model.getCpu().getTopology().getSockets().intValue());
+        if(index == 2) {
+            assertNotNull(model.getVersion());
+            assertNotSame(model.getVersion().getBaseTemplate().getId(), 
model.getId());
+        }
     }
 
     private void setUpGetVirtioScsiExpectations(int ... idxs) throws Exception 
{
diff --git 
a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/TemplateMapper.java
 
b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/TemplateMapper.java
index 1626db0..10cea77 100644
--- 
a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/TemplateMapper.java
+++ 
b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/TemplateMapper.java
@@ -1,5 +1,6 @@
 package org.ovirt.engine.api.restapi.types;
 
+import org.apache.commons.lang.StringUtils;
 import org.ovirt.engine.api.common.util.StatusUtils;
 import org.ovirt.engine.api.model.Architecture;
 import org.ovirt.engine.api.model.Boot;
@@ -13,6 +14,7 @@
 import org.ovirt.engine.api.model.OperatingSystem;
 import org.ovirt.engine.api.model.Template;
 import org.ovirt.engine.api.model.TemplateStatus;
+import org.ovirt.engine.api.model.TemplateVersion;
 import org.ovirt.engine.api.model.Usb;
 import org.ovirt.engine.api.model.UsbType;
 import org.ovirt.engine.api.model.VmType;
@@ -26,6 +28,7 @@
 import org.ovirt.engine.core.common.businessentities.VmTemplateStatus;
 import org.ovirt.engine.core.common.osinfo.OsRepository;
 import org.ovirt.engine.core.common.utils.SimpleDependecyInjector;
+import org.ovirt.engine.core.compat.Guid;
 
 import static 
org.ovirt.engine.api.restapi.types.IntegerMapper.mapNullToMinusOne;
 import static 
org.ovirt.engine.api.restapi.types.IntegerMapper.mapMinusOneToNull;
@@ -162,6 +165,17 @@
         if (model.isSetMigrationDowntime()) {
             
entity.setMigrationDowntime(mapMinusOneToNull(model.getMigrationDowntime()));
         }
+        if (model.getVersion() != null) {
+            if (model.getVersion().getBaseTemplate() != null
+                    && 
StringUtils.isNotEmpty(model.getVersion().getBaseTemplate().getId())) {
+                
entity.setBaseTemplateId(Guid.createGuidFromString(model.getVersion().getBaseTemplate().getId()));
+            }
+            if (model.getVersion().isSetVersionName()) {
+                
entity.setTemplateVersionName(model.getVersion().getVersionName());
+            }
+            // numbering is generated in the backend, hence even if user 
specified version number, we ignore it.
+        }
+
         return entity;
     }
 
@@ -371,6 +385,17 @@
         model.setTimezone(entity.getTimeZone());
         model.setTunnelMigration(entity.getTunnelMigration());
         
model.setMigrationDowntime(mapNullToMinusOne(entity.getMigrationDowntime()));
+        // if this is not a base template, that means this is a template 
version
+        // so need to populate template version properties
+        if (!entity.isBaseTemplate()) {
+            TemplateVersion version = new TemplateVersion();
+            version.setVersionName(entity.getTemplateVersionName());
+            version.setVersionNumber(entity.getTemplateVersionNumber());
+            Template baseTemplate = new Template();
+            baseTemplate.setId(entity.getBaseTemplateId().toString());
+            version.setBaseTemplate(baseTemplate);
+            model.setVersion(version);
+        }
 
         return model;
     }
diff --git 
a/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/TemplateMapperTest.java
 
b/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/TemplateMapperTest.java
index 1c46fba..ad8b1eb 100644
--- 
a/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/TemplateMapperTest.java
+++ 
b/backend/manager/modules/restapi/types/src/test/java/org/ovirt/engine/api/restapi/types/TemplateMapperTest.java
@@ -79,5 +79,7 @@
         assertEquals(model.isDeleteProtected(), transform.isDeleteProtected());
         assertEquals(model.isTunnelMigration(), transform.isTunnelMigration());
         assertEquals(model.getMigrationDowntime(), 
transform.getMigrationDowntime());
+        assertEquals(model.getVersion().getVersionName(), 
transform.getVersion().getVersionName());
+        assertEquals(model.getVersion().getBaseTemplate().getId(), 
transform.getVersion().getBaseTemplate().getId());
     }
 }


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

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

Reply via email to