package org.ovirt.engine.core.bll;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.ovirt.engine.core.common.AuditLogType;
import org.ovirt.engine.core.common.businessentities.FileTypeExtension;
import org.ovirt.engine.core.common.businessentities.RepoFileMetaData;
import org.ovirt.engine.core.common.businessentities.StorageDomainStatus;
import org.ovirt.engine.core.common.businessentities.StorageDomainType;
import org.ovirt.engine.core.common.businessentities.StoragePoolStatus;
import org.ovirt.engine.core.common.businessentities.VDSStatus;
import org.ovirt.engine.core.common.businessentities.storage_domains;
import org.ovirt.engine.core.common.businessentities.storage_pool_iso_map;
import org.ovirt.engine.core.common.config.Config;
import org.ovirt.engine.core.common.config.ConfigValues;
import org.ovirt.engine.core.common.vdscommands.IrsBaseVDSCommandParameters;
import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
import org.ovirt.engine.core.common.vdscommands.VDSReturnValue;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.LogCompat;
import org.ovirt.engine.core.compat.LogFactoryCompat;
import org.ovirt.engine.core.compat.TransactionScopeOption;
import org.ovirt.engine.core.dal.dbbroker.DbFacade;
import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector;
import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableBase;
import org.ovirt.engine.core.dao.RepoFileMetaDataDAO;
import org.ovirt.engine.core.utils.Pair;
import org.ovirt.engine.core.utils.threadpool.ThreadPoolUtil;
import org.ovirt.engine.core.utils.timer.OnTimerMethodAnnotation;
import org.ovirt.engine.core.utils.timer.SchedulerUtilQuartzImpl;
import org.ovirt.engine.core.utils.transaction.TransactionMethod;
import org.ovirt.engine.core.utils.transaction.TransactionSupport;
/**
* The class manages the Iso domain cache mechanism, <BR/>
* which reflects upon support for Iso tool validation, activation of Iso domain, and fetching the Iso list by query.<BR/>
* The cache is being refreshed with quartz scheduler which run by configuration value AutoRepoDomainRefreshTime. The
* cache procedure using VDSM to fetch the Iso files from all the Data Centers and update the DB cache table with the
* appropriate file data.<BR/>
*/
public class IsoDomainListSyncronizer {
private List<RepoFileMetaData> problematicRepoFileList = new ArrayList<RepoFileMetaData>();
public static final String guestToolsSetupIsoPrefix = Config.<String> GetValue(ConfigValues.GuestToolsSetupIsoPrefix);
public static final String regexToolPattern = guestToolsSetupIsoPrefix + "([0-9]{1,}.[0-9])(_{1})([0-9]{1,}).[i|I][s|S][o|O]$";
private final int MIN_TO_MILLISECONDS = 60 * 1000;
private static final IsoDomainListSyncronizer isoDomainListSyncronizer = new IsoDomainListSyncronizer();;
private int isoDomainRefreshRate;
RepoFileMetaDataDAO repoStorageDom;
private static ConcurrentMap<Object,Lock> syncDomainForFileTypeMap = new ConcurrentHashMap<Object,Lock>();
/**
* private constructor to initialize the quartz scheduler
*/
private IsoDomainListSyncronizer() {
repoStorageDom = DbFacade.getInstance().getRepoFileMetaDataDao();
isoDomainRefreshRate = Config.<Integer> GetValue(ConfigValues.AutoRepoDomainRefreshTime) * MIN_TO_MILLISECONDS;
SchedulerUtilQuartzImpl.getInstance().scheduleAFixedDelayJob(this,
"fetchIsoDomains",
new Class[] {},
new Object[] {},
300000,
isoDomainRefreshRate,
TimeUnit.MILLISECONDS);
}
/**
* Returns the singleton instance.
* @return Singleton instance of IsoDomainManager
*/
public static IsoDomainListSyncronizer getInstance() {
return isoDomainListSyncronizer;
}
/**
* Check and update if needed each Iso domain in each Data Center in the system.
*/
@OnTimerMethodAnnotation("fetchIsoDomains")
public void fetchIsoDomains() {
// Gets all the active Iso storage domains.
List<RepoFileMetaData> repofileList = DbFacade.getInstance()
.getRepoFileMetaDataDao()
.getAllRepoFilesForAllStoragePools(StorageDomainType.ISO,
StoragePoolStatus.Up,
StorageDomainStatus.Active,
VDSStatus.Up);
// Set count down latch to size of map for multiple threaded.
final CountDownLatch latch = new CountDownLatch(repofileList.size());
resetProblematicList();
// Iterate for each storage domain.
for (final RepoFileMetaData repoFileMetaData : repofileList) {
// If the list should be refreshed and the refresh from the VDSM was succeeded, fetch the file list again
// from the DB.
if (shouldRefreshIsoDomain(repoFileMetaData.getLastRefreshed())) {
ThreadPoolUtil.execute(new Runnable() {
@Override
public void run() {
updateCachedIsoFileListFromVdsm(repoFileMetaData, latch);
}
});
} else {
latch.countDown();
log.debugFormat("Automatic refresh process for {0} file type in storage domain id {1} was not performed since refresh time out did not passed yet.",
repoFileMetaData.getFileType(),
repoFileMetaData.getRepoDomainId());
}
}
try {
latch.await();
} catch (InterruptedException e) {
log.error("Automatic refresh process encounter a problem.", e);
}
// After refresh for all Iso domains finished, handle the log.
handleErrorLog(problematicRepoFileList);
}
/**
* Returns a RepoFilesMetaData list with Iso file names for storage domain Id and with file type extension.<BR>
* If user choose to refresh the cache, and a problem occurs, then returns null.
*
* @param storageDomainId
* - The storage domain Id, which we fetch the Iso list from.
* @param fileTypeExtension
* - The fileTypeExtension we want to fetch the files from the cache.
* @param forceRefresh
* - Indicates if the domain should be refreshed from VDSM.
* @return List of RepoFilesMetaData files or null (If fetch from VDSM failed).
*/
public List<RepoFileMetaData> getUserRequestForStorageDomainRepoFileList(Guid storageDomainId,
FileTypeExtension fileTypeExtension,
boolean forceRefresh) {
// The result list we send back.
List<RepoFileMetaData> repoList = null;
// Check storage pool Id validity.
if (storageDomainId == null) {
log.error("Storage domain ID recieved from command query is null.");
return null;
}
List<RepoFileMetaData> tempProblematicRepoFileList = new ArrayList<RepoFileMetaData>();
// If user choose to force refresh.
if (forceRefresh) {
// Add an audit log if refresh succeeded.
if (refreshIsoDomain(storageDomainId, tempProblematicRepoFileList, fileTypeExtension)) {
// Print log Indicating the problematic pools (If was any).
handleErrorLog(tempProblematicRepoFileList);
// If refresh succeeded print an audit log Indicating that.
storage_domains storageDomain = DbFacade.getInstance().getStorageDomainDAO().get(storageDomainId);
addToAuditLogSuccessMessage(storageDomain.getstorage_name(), fileTypeExtension.name());
} else {
// Print log Indicating the problematic pools.
handleErrorLog(tempProblematicRepoFileList);
return null;
}
}
// At any case, if refreshed or not, get Iso list from the cache.
repoList = getCachedIsoListByDomainId(storageDomainId, fileTypeExtension);
// Return list of repository files.
return repoList;
}
/**
* The procedure Try to refresh the repository files of the storage domain id, with storage pool Id. If succeeded
* will return True, otherwise return false and update the list, of the problematic repository files with the
* storage pool and storage domain id, that could not complete the cache update transaction.
*
* @param storageDomainId
* - The Repository domain Id, we want to refresh.
* @param storagePoolId
* - The Storage pool Id, we use to fetch the Iso files from.
* @param ProblematicRepoFileList
* - List of business entities, each one indicating the problematic entity of storage pool id, storage
* domain id, and file type.
* @param fileTypeExtension
* - The fileTypeExtension we want to fetch the files from the cache.
* @return Boolean value indicating if the refresh succeeded or not.
*/
private boolean refreshIsoDomainFileForStoragePool(Guid storageDomainId,
Guid storagePoolId,
FileTypeExtension fileTypeExt) {
boolean refreshSucceeded = false;
// Check validation of storage pool and SPM.
Boolean isValid = (Boolean) (Backend
.getInstance()
.getResourceManager()
.RunVdsCommand(VDSCommandType.IsValid,
new IrsBaseVDSCommandParameters(storagePoolId)).getReturnValue());
log.debugFormat("Validation of Storage pool id {0} returned {1}.", storagePoolId, isValid ? "valid" : "not valid");
// Setting the indication to the indication whether the storage pool is valid.
boolean updateFromVDSMSucceeded = isValid;
// If the SPM and the storage pool are valid, try to refresh the Iso list by fetching it from the SPM.
if (isValid) {
if (fileTypeExt == FileTypeExtension.ISO) {
updateFromVDSMSucceeded = updateIsoListFromVDSM(storagePoolId, storageDomainId);
} else if (fileTypeExt == FileTypeExtension.Floppy) {
updateFromVDSMSucceeded =
updateFloppyListFromVDSM(storagePoolId, storageDomainId) && updateFromVDSMSucceeded;
}
}
// Log if the refresh succeeded or add the storage domain to the problematic list.
if (updateFromVDSMSucceeded) {
refreshSucceeded = true;
log.debugFormat("Refresh succeeded for file type {0} at storage domain id {1} in storage pool id {2}.",
fileTypeExt.name(),
storageDomainId,
storagePoolId);
}
return refreshSucceeded;
}
/**
* The procedure Try to refresh the repository files of the storage domain id, By iterate over the storage pools of
* this domain, and try to choose a valid storage pool, to fetch the repository files from the VDSM, and refresh the
* cached table. <BR/>
* If succeeded, will return True. Otherwise return false with updated list of problematic repository files with the
* storage pool, storage domain, and file type, that could not complete the cache update transaction.
*
* @param storageDomainId
* - The Repository domain Id, we want to refresh.
* @param ProblematicRepoFileList
* - List of business entities, each one indicating the problematic entity.
* @param fileTypeExtension
* - The fileTypeExtension we want to fetch the files from the cache.
* @return Boolean value indicating if the refresh succeeded or not.
*/
private boolean refreshIsoDomain(Guid storageDomainId,
List<RepoFileMetaData> problematicRepoFileList,
FileTypeExtension fileTypeExt) {
boolean refreshSucceeded = false;
List<RepoFileMetaData> tempProblematicRepoFileList = new ArrayList<RepoFileMetaData>();
// Fetch all the Storage pools for this Iso domain Id.
List<storage_pool_iso_map> isoMapList =
DbFacade.getInstance()
.getStoragePoolIsoMapDAO()
.getAllForStorage(storageDomainId);
log.debugFormat("Fetched {0} storage pools for {1} file type, in Iso domain {2}.",
isoMapList.size(),
fileTypeExt,
storageDomainId);
Iterator<storage_pool_iso_map> iter = isoMapList.iterator();
while (iter.hasNext() && !refreshSucceeded) {
storage_pool_iso_map storagePoolIsoMap = iter.next();
Guid storagePoolId = storagePoolIsoMap.getstorage_pool_id().getValue();
if ((storagePoolIsoMap.getstatus() != null)
&& (storagePoolIsoMap.getstatus() == StorageDomainStatus.Active)) {
// Try to refresh the domain of the storage pool id.
refreshSucceeded =
refreshIsoDomainFileForStoragePool(storageDomainId,
storagePoolId,
fileTypeExt);
} else {
log.debugFormat("Storage domain id {0}, is not active, and there for could not be refreshed for {1} file type (Iso domain status is {2}).",
storageDomainId,
fileTypeExt,
storagePoolIsoMap.getstatus());
}
if (!refreshSucceeded) {
log.debugFormat("Failed refreshing Storage domain id {0}, for {1} file type in storage pool id {2}.",
storageDomainId,
fileTypeExt,
storagePoolId);
// set a mock repository file meta data with storage domain id and storage pool id.
RepoFileMetaData repoFileMetaData = new RepoFileMetaData();
repoFileMetaData.setStoragePoolId(storagePoolId);
repoFileMetaData.setRepoDomainId(storageDomainId);
repoFileMetaData.setFileType(fileTypeExt);
// Add the repository file to the list of problematic Iso domains.
tempProblematicRepoFileList.add(repoFileMetaData);
}
}
// If refreshed was not succeeded add the problematic storage Iso domain to the list.
if (!refreshSucceeded) {
problematicRepoFileList.addAll(tempProblematicRepoFileList);
}
return refreshSucceeded;
}
/**
* Refresh the Iso domain when activating the domain,
* with executing a new Thread to prevent long lock status for the domain.
*
* @param IsoStorageDomainId
* - The storage domain Id we want to get the file list from.
* @param storagePoolId
* - The storage pool Id we get an Iso active domain, we want to get the file list from (used mainly for log issues).
*/
public void refresheIsoDomainWhenActivateDomain(final Guid isoStorageDomainId,
final Guid storagePoolId) {
if (storagePoolId != null && (isoStorageDomainId != null))
{
ThreadPoolUtil.execute(new Runnable() {
@Override
public void run() {
refreshActivatedStorageDomainFromVdsm(storagePoolId, isoStorageDomainId);
}
});
}
}
/**
* Returns the cached Iso file meta data list, of the storage pool Id with the storage domain id.
*
* @param IsoStorageDomainId
* - The storage domain Id we want to get the file list from.
* @param IsoStoragePoolId
* - The storage pool Id we want to get the file list from.
* @return List of Iso file fetched from DB, if parameter is invalid returns an empty list.
*/
public List<RepoFileMetaData> getCachedIsoListByPoolAndDomainId(Guid isoStoragePoolId, Guid isoStorageDomainId) {
List<RepoFileMetaData> fileListMD = new ArrayList<RepoFileMetaData>();
// Check validation of parameters.
if (isoStorageDomainId != null && isoStoragePoolId != null) {
// Get all the Iso files of storage and domain ID.
fileListMD = repoStorageDom.getRepoListForStorageDomainAndStoragePool(isoStoragePoolId, isoStorageDomainId,
FileTypeExtension.ISO);
}
return fileListMD;
}
/**
* Returns the cached Iso file meta data list, for storage domain.
*
* @param IsoStorageDomainId
* - The storage domain Id we want to get the file list from.
* @return List of Iso files fetched from DB, if parameter is invalid returns an empty list.
*/
public List<RepoFileMetaData> getCachedIsoListByDomainId(Guid isoStorageDomainId,FileTypeExtension fileTypeExtension) {
List<RepoFileMetaData> fileListMD = new ArrayList<RepoFileMetaData>();
if (isoStorageDomainId != null) {
fileListMD =
repoStorageDom.getRepoListForStorageDomain(isoStorageDomainId, fileTypeExtension);
}
return fileListMD;
}
/**
* Handling the list of problematic repository files, to maintain multi thread caching.
* @see #resetProblematicList()
*/
private synchronized void addRepoFileToProblematicList(List<RepoFileMetaData> repoFileMetaDataList) {
problematicRepoFileList.addAll(repoFileMetaDataList);
}
/**
* Reset the list of problematic repository files, before starting the refresh procedure.
* uses for multy thread caching.
* @see #addRepoFileToProblematicList()
*/
private synchronized void resetProblematicList() {
problematicRepoFileList.clear();
}
/**
* Print information on the problematic storage domain. Mainly transfer the business entity to list, for handling
* the error uniformly.
* Create a mock RepoFileMetaData object in a list, to use the functionality of the handleErrorLog with list.
*
* @param IsoStorageDomainId
* - The storage domain Id.
* @param storagePoolId
* - The storage pool Id.
* @param fileTypeExt
* - The file type extension (ISO or Floppy).
* @see #handleErrorLog(List)
*/
private void handleErrorLog(Guid storagePoolId, Guid storageDomainId, FileTypeExtension fileTypeExt) {
List<RepoFileMetaData> tempProblematicRepoFileList = new ArrayList<RepoFileMetaData>();
// set mock repo file meta data with storage domain id and storage pool id.
RepoFileMetaData repoFileMetaData = new RepoFileMetaData();
repoFileMetaData.setStoragePoolId(storagePoolId);
repoFileMetaData.setRepoDomainId(storageDomainId);
repoFileMetaData.setFileType(fileTypeExt);
// Add the repository file to the list, and use handleError.
tempProblematicRepoFileList.add(repoFileMetaData);
handleErrorLog(tempProblematicRepoFileList);
}
/**
* Print information on the problematic storage domains and print an audit log.<BR/>
* If the problematicFileListForHandleError list retrieved empty or null,<BR/>
* then don't do nothing and return false flag.
*
* @param problematicFileListForHandleError
* - List of repository file meta data, each one indicating a problematic repository domain.
* @return true, if has problematic storage domains, false otherwise (List is empty).
*/
private boolean handleErrorLog(List<RepoFileMetaData> problematicFileListForHandleError) {
boolean hasProblematic = false;
if (problematicFileListForHandleError != null && !problematicFileListForHandleError.isEmpty()) {
StringBuilder problematicStorages = new StringBuilder();
StringBuilder problematicIsoDomainsForAuditLog = new StringBuilder();
Set<String> storageDomainNames = new HashSet<String>();
for (RepoFileMetaData repoMap : problematicFileListForHandleError) {
problematicStorages.append(buildDetailedProblematicMapMsg(repoMap));
storageDomainNames.add(buildDetailedAuditLogMessage(repoMap));
}
// Build Audit log message with problematic domains.
for (String domainName : storageDomainNames) {
problematicIsoDomainsForAuditLog.append(" ").append(domainName);
}
hasProblematic = true;
log.errorFormat("The following storage domains had a problem retrieving data from VDSM {0}",
problematicStorages.toString());
addToAuditLogErrorMessage(problematicIsoDomainsForAuditLog.toString());
}
return hasProblematic;
}
/**
* Returns a string builder contains problematic repoFileMetaData details.
*
* @param repoFileMetaData
* - The problematic storage domain.
*/
private StringBuilder buildDetailedProblematicMapMsg(RepoFileMetaData repoFileMetaData) {
StringBuilder problematicStorageMsg = new StringBuilder();
if (repoFileMetaData != null) {
problematicStorageMsg.append(" (");
if (repoFileMetaData.getStoragePoolId() != null) {
problematicStorageMsg.append(" Storage Pool Id: ").append(repoFileMetaData.getStoragePoolId());
}
if (repoFileMetaData.getRepoDomainId() != null) {
problematicStorageMsg.append(" Storage domain Id: ").append(repoFileMetaData.getRepoDomainId());
}
problematicStorageMsg.append(" File type: ").append(repoFileMetaData.getFileType()).append(") ");
} else {
problematicStorageMsg.append("(A repository file meta data business entity, has null value) ");
}
return problematicStorageMsg;
}
/**
* Returns String contains problematic iso domain name for audit log message.
* @param repoFileMetaData
* - The problematic storage domain.
* @return
*/
private String buildDetailedAuditLogMessage(RepoFileMetaData repoFileMetaData) {
String storageDomainName = "Repository not found";
if (repoFileMetaData != null && repoFileMetaData.getRepoDomainId() != null) {
storage_domains storageDomain = DbFacade.getInstance().getStorageDomainDAO().get(repoFileMetaData.getRepoDomainId());
if (storageDomain != null) {
storageDomainName =
String.format("%s (%s file type)",
storageDomain.getstorage_name(),
repoFileMetaData.getFileType().name());
}
} else {
log.error("Repository file meta data not found for logging");
}
return storageDomainName;
}
/**
* Updates the DB cache table with files fetched from VDSM.
* The method is dedicated for multiple threads refresh.
* If refresh from VDSM has encounter problems, we update the problematic domain list.
* @param repoFileMetaData
*/
private void updateCachedIsoFileListFromVdsm(RepoFileMetaData repoFileMetaData, final CountDownLatch latch)
{
boolean isRefreshed = false;
try {
List<RepoFileMetaData> problematicRepoFileList = new ArrayList<RepoFileMetaData>();
isRefreshed = refreshIsoDomain(repoFileMetaData.getRepoDomainId(),problematicRepoFileList,repoFileMetaData.getFileType());
addRepoFileToProblematicList(problematicRepoFileList);
} finally {
// At any case count down the latch, and print log message.
latch.countDown();
log.infoFormat("Finished automatic refresh process for {0} file type with {1}, for storage domain id {2}.",
repoFileMetaData.getFileType(),
isRefreshed ? "success"
: "failure",
repoFileMetaData.getRepoDomainId());
}
}
/**
* Create a new transaction to refresh the Iso file list in to the DB.
*
* @param repoDomainId
* - The repository domain id we want to update.
* @param storageDomainDao
* - The Data Access Layer for storage domain.
* @param isoDomainList
* - The Iso files which refreshed in the cache.
*/
private static boolean refreshIsoFileListMetaData(final Guid repoStorageDomainId,
final RepoFileMetaDataDAO repoFileMetaDataDao,
final List<String> isoDomainList, final FileTypeExtension fileTypeExt) {
Lock syncObject = getSyncObject(repoStorageDomainId, fileTypeExt);
try {
syncObject.lock();
return (Boolean) TransactionSupport.executeInScope(TransactionScopeOption.RequiresNew,
new TransactionMethod<Object>() {
@Override
public Object runInTransaction() {
long currentTime = System.currentTimeMillis();
repoFileMetaDataDao.removeRepoDomainFileList(repoStorageDomainId, fileTypeExt);
RepoFileMetaData repo_md;
for (String isoFile : isoDomainList) {
repo_md = new RepoFileMetaData();
repo_md.setLastRefreshed(currentTime);
repo_md.setSize(0);
repo_md.setRepoDomainId(repoStorageDomainId);
repo_md.setDateCreated(null);
repo_md.setRepoFileName(isoFile);
repo_md.setFileType(fileTypeExt);
repoFileMetaDataDao.addRepoFileMap(repo_md);
}
return true;
}
});
} finally {
syncObject.unlock();
}
}
/**
* Try to update the cached table from the VDSM, if succeeded fetch the file list again from the DB. if not ,handle
* the log message.
*
* @param IsoStorageDomainId
* - The storage domain Id we want to get the file list from.
* @param fileListMD
* - File list of repository files.
* @param repoFileMetaData
* - repository file we fetch the domain counting on its domain id.
*/
private synchronized void refreshActivatedStorageDomainFromVdsm(Guid storagePoolId, Guid storageDomainId) {
if (!updateIsoListFromVDSM(storagePoolId, storageDomainId)) {
// Add an audit log that refresh was failed for Iso files.
handleErrorLog(storagePoolId, storageDomainId, FileTypeExtension.ISO);
}
if (!updateFloppyListFromVDSM(storagePoolId, storageDomainId)) {
// Add an audit log that refresh was failed for Floppy files.
handleErrorLog(storagePoolId, storageDomainId, FileTypeExtension.Floppy);
}
}
/**
* Check if last refreshed time has exceeded the time limit configured in isoDomainRefreshRate.
*
* @param lastRefreshed
* - Time when repository file was last refreshed.
* @return True if time exceeded, and should refresh the domain, false otherwise.
*/
private boolean shouldRefreshIsoDomain(long lastRefreshed) {
return ((System.currentTimeMillis() - lastRefreshed) > isoDomainRefreshRate);
}
/**
* Gets the Iso file list from VDSM, and if the fetch is valid refresh the Iso list in the DB.
*
* @param repoFileMetaData
* - The repository storage pool id, we want to update the file list.
* @param repoStorageDomainId
* - The repository storage domain id, for activate storage domain id.
* @return True, if the fetch from VDSM has succeeded. False otherwise.
*/
private boolean updateIsoListFromVDSM(Guid repoStoragePoolId, Guid repoStorageDomainId) {
boolean refreshIsoSucceeded = false;
if (repoStorageDomainId != null) {
try {
// Get Iso domain file list from storage pool.
VDSReturnValue returnValue = Backend
.getInstance()
.getResourceManager()
.RunVdsCommand(VDSCommandType.GetIsoList,
new IrsBaseVDSCommandParameters(repoStoragePoolId));
@SuppressWarnings("unchecked")
List<String> isoDomainList = (List<String>) returnValue.getReturnValue();
if (returnValue.getSucceeded() && isoDomainList != null) {
log.debugFormat("The refresh process from VDSM, for Iso files succeeded.");
// Set the Iso domain file list fetched from VDSM into the DB.
refreshIsoSucceeded =
refreshIsoFileListMetaData(repoStorageDomainId,
repoStorageDom,
isoDomainList, FileTypeExtension.ISO);
}
} catch (Exception e) {
refreshIsoSucceeded = false;
log.warnFormat("The refresh process from VDSM, for Iso files failed.");
log.error(e);
}
}
return refreshIsoSucceeded;
}
/**
* Gets the Iso floppy file list from VDSM, and if the fetch is valid refresh the Iso floppy list in the DB.
*
* @param repoFileMetaData
* - The repository storage pool id, we want to update the file list.
* @param repoStorageDomainId
* - The repository storage domain id, for activate storage domain id.
* @return True, if the fetch from VDSM has succeeded. False otherwise.
*/
private boolean updateFloppyListFromVDSM(Guid repoStoragePoolId, Guid repoStorageDomainId) {
boolean refreshFloppySucceeded = false;
if (repoStorageDomainId != null) {
try {
// Get Iso domain floppy file list from storage pool.
VDSReturnValue returnValue = Backend
.getInstance()
.getResourceManager()
.RunVdsCommand(VDSCommandType.GetFloppyList,
new IrsBaseVDSCommandParameters(repoStoragePoolId));
@SuppressWarnings("unchecked")
List<String> isoDomainFloppyList = (List<String>) returnValue.getReturnValue();
if (returnValue.getSucceeded() && isoDomainFloppyList != null) {
// Set the Iso domain floppy file list fetched from VDSM into the DB.
refreshFloppySucceeded =
refreshIsoFileListMetaData(repoStorageDomainId,
repoStorageDom,
isoDomainFloppyList, FileTypeExtension.Floppy);
}
log.debugFormat("The refresh process from VDSM, for Floppy files succeeded.");
} catch (Exception e) {
refreshFloppySucceeded = false;
log.warnFormat("The refresh process from VDSM, for Floppy files failed.");
log.error(e);
}
}
return refreshFloppySucceeded;
}
/**
* Maintain a <code>ConcurrentMap</code> which contains <code>Lock</code> object.<BR/>
* The key Object is a <code>Pair</code> object, which will represent the domain and the file type.<BR/>
* If no synchronized object found, the <code>Lock</code> will be add to the <code>ConcurrentMap</code>.
*
* @param domainId
* - The domain Id that supposed to be refreshed.
* @param fileTypeExt
* - The file type supposed to be refreshed.
* @return - The Lock object, which represent the domain and the file type, to lock.
*/
private static Lock getSyncObject(Guid domainId, FileTypeExtension fileTypeExt) {
Pair<Guid, FileTypeExtension> domainPerFileType = new Pair<Guid, FileTypeExtension>(domainId, fileTypeExt);
syncDomainForFileTypeMap.putIfAbsent(domainPerFileType,new ReentrantLock());
return syncDomainForFileTypeMap.get(domainPerFileType);
}
/**
* Add audit log message when fetch encounter problems.
*
* @param problematicRepoFilesList
* - List of Iso domain names, which encounter problem fetching from VDSM.
*/
private void addToAuditLogErrorMessage(String problematicRepoFilesList) {
AuditLogableBase logable = new AuditLogableBase();
// Get translated error by error code ,if no translation found (should not happened) ,
// will set the error code instead.
logable.AddCustomValue("isoDomains", problematicRepoFilesList);
AuditLogDirector.log(logable, AuditLogType.REFRESH_REPOSITORY_FILE_LIST_FAILED);
}
/**
* Add audit log message when fetch encounter problems.
*/
private void addToAuditLogSuccessMessage(String IsoDomain, String fileTypeExt) {
AuditLogableBase logable = new AuditLogableBase();
logable.AddCustomValue("isoDomains", String.format("%s (%s file type)", IsoDomain, fileTypeExt));
AuditLogDirector.log(logable, AuditLogType.REFRESH_REPOSITORY_FILE_LIST_SUCCEEDED);
}
private static LogCompat log = LogFactoryCompat.getLog(IsoDomainListSyncronizer.class);
}