code optimizations

This commit is contained in:
Harikrishna Patnala 2025-12-30 11:25:20 +05:30
parent a3d1c9464f
commit 4928d9bd15
5 changed files with 71 additions and 57 deletions

View File

@ -33,5 +33,5 @@ public interface StorageOrchestrationService {
Future<TemplateApiResult> orchestrateTemplateCopyToImageStore(TemplateInfo source, DataStore destStore);
Future<TemplateApiResult> orchestrateTemplateCopyAcrossZones(TemplateInfo source, DataStore sourceStore, DataStore destStore);
Future<TemplateApiResult> orchestrateTemplateCopyAcrossZones(TemplateInfo source, DataStore destStore);
}

View File

@ -38,6 +38,8 @@ import javax.naming.ConfigurationException;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.template.TemplateManager;
@ -322,11 +324,11 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
}
@Override
public Future<TemplateApiResult> orchestrateTemplateCopyAcrossZones(TemplateInfo templateInfo, DataStore sourceStore, DataStore destStore) {
public Future<TemplateApiResult> orchestrateTemplateCopyAcrossZones(TemplateInfo templateInfo, DataStore destStore) {
Long dstZoneId = destStore.getScope().getScopeId();
DataCenterVO dstZone = dcDao.findById(dstZoneId);
long userId = CallContext.current().getCallingUserId();
return submit(dstZoneId, new CrossZoneCopyTemplateTask(userId, templateInfo, sourceStore, dstZone));
return submit(dstZoneId, new CrossZoneCopyTemplateTask(userId, templateInfo, dstZone));
}
protected Pair<String, Boolean> migrateCompleted(Long destDatastoreId, DataStore srcDatastore, List<DataObject> files, MigrationPolicy migrationPolicy, int skipped) {
@ -678,17 +680,12 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
private class CrossZoneCopyTemplateTask implements Callable<TemplateApiResult> {
private final long userId;
private final TemplateInfo sourceTmpl;
private final DataStore sourceStore;
private final DataCenterVO dstZone;
private final String logid;
CrossZoneCopyTemplateTask(long userId,
TemplateInfo sourceTmpl,
DataStore sourceStore,
DataCenterVO dstZone) {
CrossZoneCopyTemplateTask(long userId, TemplateInfo sourceTmpl, DataCenterVO dstZone) {
this.userId = userId;
this.sourceTmpl = sourceTmpl;
this.sourceStore = sourceStore;
this.dstZone = dstZone;
this.logid = ThreadContext.get(LOGCONTEXTID);
}
@ -699,16 +696,17 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
TemplateApiResult result;
VMTemplateVO template = templateDao.findById(sourceTmpl.getId());
try {
DataStore sourceStore = sourceTmpl.getDataStore();
boolean success = templateManager.copy(userId, template, sourceStore, dstZone);
result = new TemplateApiResult(sourceTmpl);
if (!success) {
result.setResult("Cross-zone template copy failed");
}
} catch (Exception e) {
} catch (StorageUnavailableException | ResourceAllocationException e) {
logger.error("Exception while copying template [{}] from zone [{}] to zone [{}]",
template,
sourceStore.getScope().getScopeId(),
sourceTmpl.getDataStore().getScope().getScopeId(),
dstZone.getId(),
e);
result = new TemplateApiResult(sourceTmpl);

View File

@ -615,13 +615,11 @@ public class TemplateServiceImpl implements TemplateService {
}
protected boolean tryCopyingTemplateToImageStore(VMTemplateVO tmplt, DataStore destStore) {
Long destZoneId = destStore.getScope().getScopeId();
List<DataStore> storesInSameZone = _storeMgr.getImageStoresByZoneIds(destZoneId);
if (searchAndCopyWithinZone(tmplt, destStore, storesInSameZone)) {
if (searchAndCopyWithinZone(tmplt, destStore)) {
return true;
}
Long destZoneId = destStore.getScope().getScopeId();
logger.debug("Template [{}] not found in any image store of zone [{}]. Checking other zones.",
tmplt.getUniqueName(), destZoneId);
@ -643,45 +641,54 @@ public class TemplateServiceImpl implements TemplateService {
continue;
}
DataStore sourceStore = findImageStorageHavingTemplate(tmplt, storesInOtherZone);
if (sourceStore == null) {
logger.debug("Template [{}] not found in any image store of zone [{}].",
TemplateObject sourceTmpl = findUsableTemplate(tmplt, storesInOtherZone);
if (sourceTmpl == null) {
logger.debug("Template [{}] not found with a valid install path in any image store of zone [{}].",
tmplt.getUniqueName(), otherZoneId);
continue;
}
TemplateObject sourceTmpl = (TemplateObject) _templateFactory.getTemplate(tmplt.getId(), sourceStore);
if (sourceTmpl.getInstallPath() == null) {
logger.warn("Cannot copy template [{}] from image store [{}]; install path is null.",
tmplt.getUniqueName(), sourceStore.getName());
continue;
}
logger.info("Template [{}] found in zone [{}]. Initiating cross-zone copy to zone [{}].",
tmplt.getUniqueName(), otherZoneId, destZoneId);
return copyTemplateAcrossZones(sourceStore, destStore, tmplt);
return copyTemplateAcrossZones(destStore, sourceTmpl);
}
logger.debug("Template [{}] was not found in any zone. Cannot perform zone-to-zone copy.",
tmplt.getUniqueName());
logger.debug("Template [{}] was not found in any zone. Cannot perform zone-to-zone copy.", tmplt.getUniqueName());
return false;
}
private boolean searchAndCopyWithinZone(VMTemplateVO tmplt, DataStore destStore, List<DataStore> stores) {
for (DataStore sourceStore : stores) {
protected TemplateObject findUsableTemplate(VMTemplateVO tmplt, List<DataStore> imageStores) {
for (DataStore store : imageStores) {
TemplateObject tmpl = (TemplateObject) _templateFactory.getTemplate(tmplt.getId(), store);
if (tmpl == null) {
continue;
}
if (tmpl.getInstallPath() == null) {
logger.debug("Template [{}] found in image store [{}] but install path is null. Skipping.",
tmplt.getUniqueName(), store.getName());
continue;
}
return tmpl;
}
return null;
}
private boolean searchAndCopyWithinZone(VMTemplateVO tmplt, DataStore destStore) {
Long destZoneId = destStore.getScope().getScopeId();
List<DataStore> storesInSameZone = _storeMgr.getImageStoresByZoneIds(destZoneId);
for (DataStore sourceStore : storesInSameZone) {
Map<String, TemplateProp> existingTemplatesInSourceStore = listTemplate(sourceStore);
if (existingTemplatesInSourceStore == null ||
!existingTemplatesInSourceStore.containsKey(tmplt.getUniqueName())) {
logger.debug("Template [{}] does not exist on image store [{}]; searching another.",
tmplt.getUniqueName(), sourceStore.getName());
logger.debug("Template [{}] does not exist on image store [{}]; searching another.", tmplt.getUniqueName(), sourceStore.getName());
continue;
}
TemplateObject sourceTmpl = (TemplateObject) _templateFactory.getTemplate(tmplt.getId(), sourceStore);
if (sourceTmpl.getInstallPath() == null) {
logger.warn("Cannot copy template [{}] from image store [{}]; install path is null.",
tmplt.getUniqueName(), sourceStore.getName());
logger.warn("Cannot copy template [{}] from image store [{}]; install path is null.", tmplt.getUniqueName(), sourceStore.getName());
continue;
}
@ -691,36 +698,22 @@ public class TemplateServiceImpl implements TemplateService {
return false;
}
private DataStore findImageStorageHavingTemplate(VMTemplateVO tmplt, List<DataStore> stores) {
for (DataStore store : stores) {
Map<String, TemplateProp> templates = listTemplate(store);
if (templates != null && templates.containsKey(tmplt.getUniqueName())) {
return store;
}
}
return null;
}
private boolean copyTemplateAcrossZones(DataStore sourceStore,
DataStore destStore,
VMTemplateVO tmplt) {
private boolean copyTemplateAcrossZones(DataStore destStore, TemplateObject sourceTmpl) {
Long dstZoneId = destStore.getScope().getScopeId();
DataCenterVO dstZone = _dcDao.findById(dstZoneId);
if (dstZone == null) {
logger.warn("Destination zone [{}] not found for template [{}].",
dstZoneId, tmplt.getUniqueName());
logger.warn("Destination zone [{}] not found for template [{}].", dstZoneId, sourceTmpl.getUniqueName());
return false;
}
TemplateObject sourceTmpl = (TemplateObject) _templateFactory.getTemplate(tmplt.getId(), sourceStore);
try {
storageOrchestrator.orchestrateTemplateCopyAcrossZones(sourceTmpl, sourceStore, destStore);
storageOrchestrator.orchestrateTemplateCopyAcrossZones(sourceTmpl, destStore);
return true;
} catch (Exception e) {
logger.error("Failed to copy template [{}] from zone [{}] to zone [{}].",
tmplt.getUniqueName(),
sourceStore.getScope().getScopeId(),
sourceTmpl.getUniqueName(),
sourceTmpl.getDataStore().getScope().getScopeId(),
dstZoneId,
e);
return false;

View File

@ -213,7 +213,6 @@ public class TemplateServiceImplTest {
Map<String, TemplateProp> templatesInOtherZone = new HashMap<>();
templatesInOtherZone.put(tmpltMock.getUniqueName(), tmpltPropMock);
Mockito.doReturn(templatesInOtherZone).when(templateService).listTemplate(otherZoneStoreMock);
TemplateObject sourceTmplMock = Mockito.mock(TemplateObject.class);
Mockito.doReturn(sourceTmplMock).when(templateDataFactoryMock).getTemplate(100L, otherZoneStoreMock);
@ -241,7 +240,6 @@ public class TemplateServiceImplTest {
Map<String, TemplateProp> templates = new HashMap<>();
templates.put(tmpltMock.getUniqueName(), tmpltPropMock);
Mockito.doReturn(templates).when(templateService).listTemplate(otherZoneStoreMock);
TemplateObject sourceTmplMock = Mockito.mock(TemplateObject.class);
Mockito.doReturn(sourceTmplMock).when(templateDataFactoryMock).getTemplate(100L, otherZoneStoreMock);
@ -267,7 +265,6 @@ public class TemplateServiceImplTest {
Map<String, TemplateProp> templates = new HashMap<>();
templates.put(tmpltMock.getUniqueName(), tmpltPropMock);
Mockito.doReturn(templates).when(templateService).listTemplate(otherZoneStoreMock);
TemplateObject sourceTmplMock = Mockito.mock(TemplateObject.class);
Mockito.doReturn(sourceTmplMock).when(templateDataFactoryMock).getTemplate(100L, otherZoneStoreMock);
@ -294,4 +291,31 @@ public class TemplateServiceImplTest {
Assert.assertFalse(result);
}
@Test
public void testFindUsableTemplateReturnsTemplateWithNonNullInstallPath() {
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
Mockito.when(template.getId()).thenReturn(10L);
Mockito.when(template.getUniqueName()).thenReturn("test-template");
DataStore storeWithNullPath = Mockito.mock(DataStore.class);
Mockito.when(storeWithNullPath.getName()).thenReturn("store-null");
DataStore storeWithValidPath = Mockito.mock(DataStore.class);
TemplateObject tmplWithNullPath = Mockito.mock(TemplateObject.class);
Mockito.when(tmplWithNullPath.getInstallPath()).thenReturn(null);
TemplateObject tmplWithValidPath = Mockito.mock(TemplateObject.class);
Mockito.when(tmplWithValidPath.getInstallPath()).thenReturn("/mnt/secondary/template.qcow2");
Mockito.doReturn(tmplWithNullPath).when(templateDataFactoryMock).getTemplate(10L, storeWithNullPath);
Mockito.doReturn(tmplWithValidPath).when(templateDataFactoryMock).getTemplate(10L, storeWithValidPath);
List<DataStore> imageStores = List.of(storeWithNullPath, storeWithValidPath);
TemplateObject result = templateService.findUsableTemplate(template, imageStores);
Assert.assertNotNull(result);
Assert.assertEquals(tmplWithValidPath, result);
}
}

View File

@ -79,7 +79,6 @@ public class ImageStoreDetailsUtil {
}
public boolean isCopyTemplatesFromOtherStoragesEnabled(Long storeId, Long zoneId) {
final Map<String, String> storeDetails = imageStoreDetailsDao.getDetails(storeId);
final String keyWithoutDots = StorageManager.COPY_TEMPLATES_FROM_OTHER_SECONDARY_STORAGES.key()
.replace(".", "");