Maor Lipchuk has uploaded a new change for review.

Change subject: core: Fetch unregisterd entity from all the Storage Domains.
......................................................................

core: Fetch unregisterd entity from all the Storage Domains.

Add the ability to fetch an entity from all the
Storage Domains with a stored procedure, by passing null as storage domain id.

This stored procedure should be used for fetching Tempalte with disk copied on 
several
Storage Domains.

Change-Id: Ia279818045ee3adfcda6383b010ac9f7e283886f
Bug-Url: https://bugzilla.redhat.com/1138136
Signed-off-by: Maor Lipchuk <mlipc...@redhat.com>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ImportVmFromConfigurationCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ImportVmTemplateFromConfigurationCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/StorageHandlingCommandBase.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetUnregisteredVmTemplatesQueryTest.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetUnregisteredVmsQueryTest.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/ImportVMFromConfigurationCommandTest.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAO.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAODbFacadeImpl.java
M 
backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAOTest.java
M backend/manager/modules/dal/src/test/resources/fixtures.xml
M packaging/dbscripts/unregistered_OVF_data_sp.sql
11 files changed, 75 insertions(+), 33 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/86/35886/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ImportVmFromConfigurationCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ImportVmFromConfigurationCommand.java
index 9c4bbd3..51f146d 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ImportVmFromConfigurationCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ImportVmFromConfigurationCommand.java
@@ -87,11 +87,13 @@
 
     private void initUnregisteredVM() {
         OvfHelper ovfHelper = new OvfHelper();
-        ovfEntityData =
+        List<OvfEntityData> ovfEntityDataList =
                 
getUnregisteredOVFDataDao().getByEntityIdAndStorageDomain(getParameters().getContainerId(),
                         getParameters().getStorageDomainId());
-        if (ovfEntityData != null) {
+        if (!ovfEntityDataList.isEmpty()) {
             try {
+                // We should get only one entity, since we fetched the entity 
with a specific Storage Domain
+                ovfEntityData = ovfEntityDataList.get(0);
                 vmFromConfiguration = 
ovfHelper.readVmFromOvf(ovfEntityData.getOvfData());
                 
vmFromConfiguration.setVdsGroupId(getParameters().getVdsGroupId());
                 getParameters().setVm(vmFromConfiguration);
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ImportVmTemplateFromConfigurationCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ImportVmTemplateFromConfigurationCommand.java
index f28cfe6..9c51a4a 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ImportVmTemplateFromConfigurationCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ImportVmTemplateFromConfigurationCommand.java
@@ -1,6 +1,7 @@
 package org.ovirt.engine.core.bll;
 
 import java.util.ArrayList;
+import java.util.List;
 
 import org.ovirt.engine.core.common.AuditLogType;
 import org.ovirt.engine.core.common.action.ImportVmTemplateParameters;
@@ -56,11 +57,13 @@
 
     private void initVmTemplate() {
         OvfHelper ovfHelper = new OvfHelper();
-        ovfEntityData =
+        List<OvfEntityData> ovfEntityList =
                 
getUnregisteredOVFDataDao().getByEntityIdAndStorageDomain(getParameters().getContainerId(),
                         getParameters().getStorageDomainId());
-        if (ovfEntityData != null) {
+        if (!ovfEntityList.isEmpty()) {
             try {
+                // We should get only one entity, since we fetched the entity 
with a specific Storage Domain
+                OvfEntityData ovfEntityData = ovfEntityList.get(0);
                 vmTemplateFromConfiguration = 
ovfHelper.readVmTemplateFromOvf(ovfEntityData.getOvfData());
                 
vmTemplateFromConfiguration.setVdsGroupId(getParameters().getVdsGroupId());
                 setVmTemplate(vmTemplateFromConfiguration);
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/StorageHandlingCommandBase.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/StorageHandlingCommandBase.java
index 2af373e..c2eaea5 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/StorageHandlingCommandBase.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/StorageHandlingCommandBase.java
@@ -226,8 +226,9 @@
     }
 
     private void removeEntityLeftOver(Guid entityId, String entityName, Guid 
storageDomainId) {
-        OvfEntityData ovfEntityData = 
getUnregisteredOVFDataDao().getByEntityIdAndStorageDomain(entityId, 
storageDomainId);
-        if (ovfEntityData != null) {
+        List<OvfEntityData> ovfEntityList =
+                
getUnregisteredOVFDataDao().getByEntityIdAndStorageDomain(entityId, 
storageDomainId);
+        if (!ovfEntityList.isEmpty()) {
             log.info("Entity '{}' with id '{}', already exists as unregistered 
entity. override it with the new entity from the engine",
                     entityName,
                     entityId);
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetUnregisteredVmTemplatesQueryTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetUnregisteredVmTemplatesQueryTest.java
index d0a15ae..f7c2dfa 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetUnregisteredVmTemplatesQueryTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetUnregisteredVmTemplatesQueryTest.java
@@ -63,6 +63,8 @@
                         ovfData,
                         null);
         List<OvfEntityData> expectedResult = new ArrayList<>();
+        List<OvfEntityData> expectedResultQuery1 = new ArrayList<>();
+        expectedResultQuery1.add(ovfEntityData);
         expectedResult.add(ovfEntityData);
         VmTemplate VmTemplateReturnForOvf2 = new VmTemplate();
         VmTemplateReturnForOvf2.setId(newVmTemplateGuid2);
@@ -78,13 +80,15 @@
                         ovfData2,
                         null);
         expectedResult.add(ovfEntityData2);
+        List<OvfEntityData> expectedResultQuery2 = new ArrayList<>();
+        expectedResultQuery2.add(ovfEntityData);
 
         // Mock the DAOs
         UnregisteredOVFDataDAO unregisteredOVFDataDAOMock = 
mock(UnregisteredOVFDataDAO.class);
         
when(getDbFacadeMockInstance().getUnregisteredOVFDataDao()).thenReturn(unregisteredOVFDataDAOMock);
         
when(unregisteredOVFDataDAOMock.getAllForStorageDomainByEntityType(storageDomainId,
 entityType)).thenReturn(expectedResult);
-        
when(unregisteredOVFDataDAOMock.getByEntityIdAndStorageDomain(newVmTemplateGuid,
 storageDomainId)).thenReturn(ovfEntityData);
-        
when(unregisteredOVFDataDAOMock.getByEntityIdAndStorageDomain(newVmTemplateGuid2,
 storageDomainId)).thenReturn(ovfEntityData2);
+        
when(unregisteredOVFDataDAOMock.getByEntityIdAndStorageDomain(newVmTemplateGuid,
 storageDomainId)).thenReturn(expectedResultQuery1);
+        
when(unregisteredOVFDataDAOMock.getByEntityIdAndStorageDomain(newVmTemplateGuid2,
 storageDomainId)).thenReturn(expectedResultQuery2);
 
         // Mock OVF
         OvfHelper ovfHelperMock = mock(OvfHelper.class);
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetUnregisteredVmsQueryTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetUnregisteredVmsQueryTest.java
index 789edf3..cb0548e 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetUnregisteredVmsQueryTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetUnregisteredVmsQueryTest.java
@@ -62,6 +62,8 @@
                         storageDomainId,
                         ovfData,
                         null);
+        List<OvfEntityData> expectedResultQuery1 = new ArrayList<>();
+        expectedResultQuery1.add(ovfEntityData);
         List<OvfEntityData> expectedResult = new ArrayList<>();
         expectedResult.add(ovfEntityData);
         VM vmReturnForOvf2 = new VM();
@@ -78,13 +80,15 @@
                         ovfData2,
                         null);
         expectedResult.add(ovfEntityData2);
+        List<OvfEntityData> expectedResultQuery2 = new ArrayList<>();
+        expectedResultQuery2.add(ovfEntityData);
 
         // Mock the DAOs
         UnregisteredOVFDataDAO unregisteredOVFDataDAOMock = 
mock(UnregisteredOVFDataDAO.class);
         
when(getDbFacadeMockInstance().getUnregisteredOVFDataDao()).thenReturn(unregisteredOVFDataDAOMock);
         
when(unregisteredOVFDataDAOMock.getAllForStorageDomainByEntityType(storageDomainId,
 entityType)).thenReturn(expectedResult);
-        
when(unregisteredOVFDataDAOMock.getByEntityIdAndStorageDomain(newVmGuid2, 
storageDomainId)).thenReturn(ovfEntityData2);
-        
when(unregisteredOVFDataDAOMock.getByEntityIdAndStorageDomain(newVmGuid, 
storageDomainId)).thenReturn(ovfEntityData);
+        
when(unregisteredOVFDataDAOMock.getByEntityIdAndStorageDomain(newVmGuid2, 
storageDomainId)).thenReturn(expectedResultQuery2);
+        
when(unregisteredOVFDataDAOMock.getByEntityIdAndStorageDomain(newVmGuid, 
storageDomainId)).thenReturn(expectedResultQuery1);
 
         // Mock OVF
         OvfHelper ovfHelperMock = mock(OvfHelper.class);
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/ImportVMFromConfigurationCommandTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/ImportVMFromConfigurationCommandTest.java
index 8d9cec2..00aa6b7 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/ImportVMFromConfigurationCommandTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/ImportVMFromConfigurationCommandTest.java
@@ -14,6 +14,7 @@
 import java.nio.charset.Charset;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
@@ -153,7 +154,9 @@
         OvfEntityData ovfEntity = getOvfEntityData();
         ovfEntity.setOvfData("This is not a valid XML");
         initCommand(ovfEntity);
-        when(unregisteredOVFDataDao.getByEntityIdAndStorageDomain(vmId, 
storageDomainId)).thenReturn(ovfEntity);
+        List<OvfEntityData> ovfEntityDataList = new ArrayList<>();
+        ovfEntityDataList.add(ovfEntity);
+        when(unregisteredOVFDataDao.getByEntityIdAndStorageDomain(vmId, 
storageDomainId)).thenReturn(ovfEntityDataList);
         when(validator.validateUnregisteredEntity(any(IVdcQueryable.class), 
any(OvfEntityData.class), anyList())).thenReturn(new 
ValidationResult(VdcBllMessages.ACTION_TYPE_FAILED_OVF_CONFIGURATION_NOT_SUPPORTED));
         CanDoActionTestUtils.runAndAssertCanDoActionFailure(cmd,
                 
VdcBllMessages.ACTION_TYPE_FAILED_OVF_CONFIGURATION_NOT_SUPPORTED);
@@ -195,7 +198,11 @@
     }
 
     private void initUnregisteredOVFData(OvfEntityData resultOvfEntityData) {
-        when(unregisteredOVFDataDao.getByEntityIdAndStorageDomain(vmId, 
storageDomainId)).thenReturn(resultOvfEntityData);
+        List<OvfEntityData> ovfEntityDataList = new ArrayList<>();
+        if (resultOvfEntityData != null) {
+            ovfEntityDataList.add(resultOvfEntityData);
+        }
+        when(unregisteredOVFDataDao.getByEntityIdAndStorageDomain(vmId, 
storageDomainId)).thenReturn(ovfEntityDataList);
     }
 
     private OvfEntityData getOvfEntityData() {
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAO.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAO.java
index e496c52..4d40be2 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAO.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAO.java
@@ -9,7 +9,8 @@
 public interface UnregisteredOVFDataDAO extends DAO {
 
     /**
-     * Retrieves the entity with the given Entity id.
+     * Retrieves the entity with the given entity id and storage domain 
id.<BR/>
+     * If the Storage Domain id is null, then return all the unregistered 
entities with the entity id.
      *
      * @param entityId
      *            The Entity Id.
@@ -17,7 +18,7 @@
      *            The Storage Domain Id.
      * @return The entity instance, or <code>null</code> if not found.
      */
-    public OvfEntityData getByEntityIdAndStorageDomain(Guid entityId, Guid 
storageDomainId);
+    public List<OvfEntityData> getByEntityIdAndStorageDomain(Guid entityId, 
Guid storageDomainId);
 
     /**
      * Retrieves all the entities of the given type related to the storage 
Domain Id.
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAODbFacadeImpl.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAODbFacadeImpl.java
index e1e6acd..b06a959 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAODbFacadeImpl.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAODbFacadeImpl.java
@@ -23,8 +23,8 @@
     }
 
     @Override
-    public OvfEntityData getByEntityIdAndStorageDomain(Guid entityId, Guid 
storageDomainId) {
-        return 
getCallsHandler().executeRead("GetOVFDataByEntityIdAndStorageDomain",
+    public List<OvfEntityData> getByEntityIdAndStorageDomain(Guid entityId, 
Guid storageDomainId) {
+        return 
getCallsHandler().executeReadList("GetOVFDataByEntityIdAndStorageDomain",
                 OvfEntityDataRowMapper.instance,
                 getCustomMapSqlParameterSource()
                         .addValue("entity_guid", entityId)
diff --git 
a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAOTest.java
 
b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAOTest.java
index 7c55930..ab8f47b 100644
--- 
a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAOTest.java
+++ 
b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/UnregisteredOVFDataDAOTest.java
@@ -1,8 +1,7 @@
 package org.ovirt.engine.core.dao;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import java.util.List;
@@ -24,23 +23,24 @@
 
     @Test
     public void testGetWithEntityId() {
-        OvfEntityData ovfEntityData =
+        List<OvfEntityData> ovfEntityDataList =
                 
dao.getByEntityIdAndStorageDomain(FixturesTool.UNREGISTERED_VM, 
FixturesTool.STORAGE_DOAMIN_NFS2_1);
-        assertNotNull("VM should exists in the UnregisteredOVFData", 
ovfEntityData);
+        assertFalse("VM should exists in the UnregisteredOVFData", 
ovfEntityDataList.isEmpty());
     }
 
     @Test
     public void testGetWithNotExistingEntityId() {
-        OvfEntityData ovfEntityData =
+        List<OvfEntityData> ovfEntityDataList =
                 
dao.getByEntityIdAndStorageDomain(FixturesTool.VM_RHEL5_POOL_51, 
FixturesTool.STORAGE_DOAMIN_NFS2_1);
-        assertNull("VM should not exists in the UnregisteredOVFData", 
ovfEntityData);
+        assertTrue("VM should not exists in the UnregisteredOVFData", 
ovfEntityDataList.isEmpty());
     }
 
     @Test
     public void testGetWithVMOnWrongStorageDomainId() {
-        OvfEntityData ovfEntityData =
+        List<OvfEntityData> ovfEntityDataList =
                 
dao.getByEntityIdAndStorageDomain(FixturesTool.UNREGISTERED_VM, 
FixturesTool.STORAGE_DOAMIN_NFS2_2);
-        assertNull("VM should not exists in the UnregisteredOVFData for the 
specific Storage Domain", ovfEntityData);
+        assertTrue("VM should not exists in the UnregisteredOVFData for the 
specific Storage Domain",
+                ovfEntityDataList.isEmpty());
     }
 
     @Test
@@ -101,22 +101,32 @@
 
         dao.saveOVFData(ovfEntityData);
 
-        OvfEntityData fetchedOvfEntityData =
+        List<OvfEntityData> fetchedOvfEntityData =
                 
dao.getByEntityIdAndStorageDomain(FixturesTool.VM_TEMPLATE_RHEL5, 
FixturesTool.STORAGE_DOAMIN_NFS2_1);
-        assertNotNull(fetchedOvfEntityData);
-        assertTrue("The entity type should be template", 
fetchedOvfEntityData.getEntityType().isTemplateType());
-        assertTrue("The entity OVF extra data should be updated", 
fetchedOvfEntityData.getOvfExtraData()
+        assertFalse(fetchedOvfEntityData.isEmpty());
+        assertTrue("The entity type should be template", 
fetchedOvfEntityData.get(0).getEntityType().isTemplateType());
+        assertTrue("The entity OVF extra data should be updated", 
fetchedOvfEntityData.get(0).getOvfExtraData()
                 .equals(ovfExtraData));
     }
 
     @Test
     public void testDeleteUnregisteredEntity() {
-        OvfEntityData ovfEntityData =
+        List<OvfEntityData> ovfEntityDataList =
                 
dao.getByEntityIdAndStorageDomain(FixturesTool.UNREGISTERED_VM, 
FixturesTool.STORAGE_DOAMIN_NFS2_1);
-        assertNotNull(ovfEntityData);
+        assertFalse(ovfEntityDataList.isEmpty());
         dao.removeEntity(FixturesTool.UNREGISTERED_VM, 
FixturesTool.STORAGE_DOAMIN_NFS2_1);
-        ovfEntityData =
+        List<OvfEntityData> ovfEntityDataList2 =
                 
dao.getByEntityIdAndStorageDomain(FixturesTool.UNREGISTERED_VM, 
FixturesTool.STORAGE_DOAMIN_NFS2_1);
-        assertNull(ovfEntityData);
+        assertTrue(ovfEntityDataList2.isEmpty());
+    }
+
+    @Test
+    public void testGetUnregisteredEntitiesWithStorageDomainNull() {
+        List<OvfEntityData> ovfEntityDataList =
+                
dao.getByEntityIdAndStorageDomain(FixturesTool.UNREGISTERED_TEMPLATE, null);
+        assertTrue(ovfEntityDataList.size() == 2);
+        assertEquals(ovfEntityDataList.get(0).getEntityId(), 
FixturesTool.UNREGISTERED_TEMPLATE);
+        assertEquals(ovfEntityDataList.get(1).getEntityId(), 
FixturesTool.UNREGISTERED_TEMPLATE);
+        
assertFalse(ovfEntityDataList.get(0).getStorageDomainId().equals(ovfEntityDataList.get(1).getStorageDomainId()));
     }
 }
diff --git a/backend/manager/modules/dal/src/test/resources/fixtures.xml 
b/backend/manager/modules/dal/src/test/resources/fixtures.xml
index 907666c..d708194 100644
--- a/backend/manager/modules/dal/src/test/resources/fixtures.xml
+++ b/backend/manager/modules/dal/src/test/resources/fixtures.xml
@@ -4430,6 +4430,16 @@
             <value>null</value>
             <value>null</value>
         </row>
+        <row>
+            <value>1b85420c-b84c-4f29-997e-0eb674b40b94</value>
+            <value>UnregisteredTemplate</value>
+            <value>TEMPLATE</value>
+            <value>1</value>
+            <value>3.4</value>
+            <value>d9ede37f-e6c3-4bf9-a984-19174070aa41</value>
+            <value>null</value>
+            <value>null</value>
+        </row>
     </table>
 
     <table name="storage_pool_iso_map">
diff --git a/packaging/dbscripts/unregistered_OVF_data_sp.sql 
b/packaging/dbscripts/unregistered_OVF_data_sp.sql
index c56afc0..78a31fa 100644
--- a/packaging/dbscripts/unregistered_OVF_data_sp.sql
+++ b/packaging/dbscripts/unregistered_OVF_data_sp.sql
@@ -53,6 +53,6 @@
         RETURN QUERY SELECT *
         FROM unregistered_ovf_of_entities
         WHERE entity_guid = v_entity_guid
-          AND storage_domain_id = v_storage_domain_id;
+          AND (storage_domain_id = v_storage_domain_id OR v_storage_domain_id 
IS NULL);
 END; $procedure$
 LANGUAGE plpgsql;


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

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

Reply via email to