package org.ovirt.engine.core.bll.storage.dr; import java.util.Collections; import java.util.List; import java.util.Map; import javax.inject.Inject; import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.bll.CommandBase; import org.ovirt.engine.core.bll.LockMessage; import org.ovirt.engine.core.bll.LockMessagesMatchUtil; import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.bll.utils.PermissionSubject; import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.action.StorageSyncScheduleParameters; import org.ovirt.engine.core.common.businessentities.StorageDomainDR; import org.ovirt.engine.core.common.businessentities.gluster.GlusterGeoRepSession; import org.ovirt.engine.core.common.businessentities.gluster.StorageSyncSchedule; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.common.locks.LockingGroup; import org.ovirt.engine.core.common.utils.Pair; import org.ovirt.engine.core.dao.StorageDomainDRDao; import org.ovirt.engine.core.dao.gluster.GlusterGeoRepDao; import org.ovirt.engine.core.utils.timer.DBSchedulerUtilQuartzImpl; @NonTransactiveCommandAttribute public class ScheduleGlusterStorageSyncCommand<T extends StorageSyncScheduleParameters> extends CommandBase<T> { @Inject private DBSchedulerUtilQuartzImpl schedulerUtil; @Inject private StorageDomainDRDao storageDomainDRDao; @Inject private GlusterGeoRepDao geoRepDao; public ScheduleGlusterStorageSyncCommand(T parameters, CommandContext cmdContext) { super(parameters, cmdContext); setStorageDomainId(getParameters().getStorageDomainId()); } private GlusterGeoRepSession getGeoRepSession() { return geoRepDao.getById(getParameters().getGeoRepSessionId()); } @Override protected void setActionMessageParameters() { addValidationMessage(EngineMessage.VAR__ACTION__SCHEDULE); addValidationMessage(EngineMessage.VAR__TYPE__STORAGE_DOMAIN_DR); super.setActionMessageParameters(); } @Override protected Map<String, Pair<String, String>> getExclusiveLocks() { return Collections.singletonMap(getStorageDomainId().toString() + ";" +getGeoRepSession().toString(), LockMessagesMatchUtil.makeLockingPair(LockingGroup.GLUSTER_STORAGE_DOMAIN_SYNC, new LockMessage(EngineMessage.STORAGE_DOMAIN_SYNC_SCHEDULING_IN_PROGRESS))); } @Override protected boolean validate() { if (getParameters().getSchedule() == null || (getParameters().getSchedule().getFrequency() != StorageSyncSchedule.Frequency.NONE && StringUtils.isEmpty(getParameters().getSchedule().toCronExpression()))) { return failValidation(EngineMessage.VALIDATION_INVALID_SCHEDULE); } if (getStorageDomain() == null) { return failValidation(EngineMessage.STORAGE_DOMAIN_DOES_NOT_EXIST); } if (getGeoRepSession() == null) { return failValidation(EngineMessage.ACTION_TYPE_FAILED_GEOREP_SESSION_INVALID); } return super.validate(); } @Override protected void executeCommand() { StorageDomainDR storageDomainDR = storageDomainDRDao.get(getParameters().getStorageDomainId(), getParameters().getGeoRepSessionId()); if (storageDomainDR == null) { storageDomainDR = new StorageDomainDR(); storageDomainDR.setStorageDomainId(getParameters().getStorageDomainId()); storageDomainDR.setGeoRepSessionId(getParameters().getGeoRepSessionId()); } else if (storageDomainDR.getJobId() != null) { // delete existing job schedulerUtil.deleteJob(storageDomainDR.getJobId()); } if (getParameters().getSchedule().getFrequency() != StorageSyncSchedule.Frequency.NONE) { String jobId = schedulerUtil.scheduleACronJob(new GlusterStorageDomainDRSyncJob(), "syncData", new Class[] { String.class, String.class }, new Object[] { getParameters().getStorageDomainId().toString(), getParameters().getGeoRepSessionId().toString() }, getParameters().getSchedule().toCronExpression()); storageDomainDR.setScheduleCronExpression(getParameters().getSchedule().toCronExpression()); storageDomainDR.setJobId(jobId); storageDomainDRDao.saveOrUpdate(storageDomainDR); } else { // FREQUENCY = NONE - no sync scheduled, so delete this storageDomainDRDao.remove(storageDomainDR.getStorageDomainId(), storageDomainDR.getGeoRepSessionId()); } setSucceeded(true); } @Override public List getPermissionCheckSubjects() { return Collections.singletonList(new PermissionSubject(getParameters().getStorageDomainId(), VdcObjectType.Storage, getActionType().getActionGroup())); } }