package org.ovirt.engine.core.vdsbroker.vdsbroker;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.ovirt.engine.core.common.errors.EngineError;
import org.ovirt.engine.core.common.errors.VDSError;
import org.ovirt.engine.core.common.vdscommands.VDSParametersBase;
import org.ovirt.engine.core.vdsbroker.ObjectDescriptor;
import org.ovirt.engine.core.vdsbroker.VDSCommandBase;
import org.ovirt.engine.core.vdsbroker.irsbroker.IRSNoMasterDomainException;
import org.ovirt.engine.core.vdsbroker.irsbroker.IRSNonOperationalException;
import org.ovirt.engine.core.vdsbroker.irsbroker.IRSUnicodeArgumentException;
import org.ovirt.engine.core.vdsbroker.irsbroker.IrsBrokerCommand;
import org.ovirt.engine.core.vdsbroker.irsbroker.IrsOperationFailedNoFailoverException;
public abstract class BrokerCommandBase<P extends VDSParametersBase> extends VDSCommandBase<P> {
public BrokerCommandBase(P parameters) {
super(parameters);
}
protected StatusOnlyReturn status;
protected Status getReturnStatus() {
return status.status;
}
protected void initializeVdsError(EngineError returnStatus) {
VDSError tempVar = new VDSError();
tempVar.setCode(returnStatus);
tempVar.setMessage(getReturnStatus().message);
getVDSReturnValue().setVdsError(tempVar);
}
protected void proceedProxyReturnValue() {
EngineError returnStatus = getReturnValueFromStatus(getReturnStatus());
VDSExceptionBase outEx;
switch (returnStatus) {
case Done:
return;
case recovery:
outEx = new VDSRecoveringException(returnStatus, getReturnStatus().message);
break;
case SpmStatusError:
outEx = new IRSNonOperationalException(getReturnStatus().message);
break;
case StoragePoolMasterNotFound:
case StoragePoolTooManyMasters:
case StoragePoolWrongMaster:
case StoragePoolHasPotentialMaster:
case StorageDomainMasterError:
outEx = new IRSNoMasterDomainException(getReturnStatus().message);
break;
case UnicodeArgumentException:
outEx = new IRSUnicodeArgumentException(getReturnStatus().message);
break;
case TooManyDomainsInStoragePoolError:
case StorageDomainAlreadyAttached:
case StorageDomainDescriptionTooLongError:
case TooManyPVsInVG:
case createIllegalVolumeSnapshotError:
case prepareIllegalVolumeError:
case createVolumeRollbackError:
case InvalidParameterException:
case InvalidDefaultExceptionException:
case NotImplementedException:
case OperationInProgress:
case MiscDirCleanupFailure:
case createVolumeSizeError:
case IncorrectFormat:
case VolumeIsBusy:
case VolumeImageHasChildren:
case VolumeUnlinkError:
case OrphanVolumeError:
case VolumeAlreadyExists:
case VolumeNonWritable:
case VolumeNonShareable:
case VolumeCannotGetParent:
case SharedVolumeNonWritable:
case InternalVolumeNonWritable:
case CannotDeleteSharedVolume:
case NonLeafVolumeNotWritable:
case ImagesActionError:
case ImageValidationError:
case ImageDeleteError:
case ImageIsNotEmpty:
case ImageIsNotLegalChain:
case OverwriteImageError:
case MoveTemplateImageError:
case StoragePoolDisconnectionError:
case StoragePoolAlreadyExists:
case IsoCannotBeMasterDomain:
case CannotConnectMultiplePools:
case BackupCannotBeMasterDomain:
case StoragePoolConnected:
case StoragePoolDescriptionTooLongError:
case StorageDomainNotInPool:
case StorageDomainNotEmpty:
case StorageDomainMetadataCreationError:
case StorageDomainMetadataFileMissing:
case StorageDomainMetadataNotFound:
case StorageDomainAlreadyExists:
case StorageDomainMasterUnmountError:
case BlockStorageDomainMasterFSCKError:
case StorageDomainLayoutError:
case StorageDomainTypeError:
case StorageDomainNotMemberOfPool:
case StorageDomainStatusError:
case StorageDomainCheckError:
case StorageDomainTypeNotBackup:
case StorageDomainStateTransitionIllegal:
case StorageDomainActive:
case CannotDetachMasterStorageDomain:
case StorageDomainInsufficientPermissions:
case StorageDomainClassError:
case StorageDomainIsMadeFromTooManyPVs:
case InvalidTask:
case UnknownTask:
case TaskClearError:
case TaskNotFinished:
case InvalidTaskType:
case AddTaskError:
case TaskInProgress:
case TaskStateError:
case TaskAborted:
case TaskPersistError:
case InvalidJob:
case InvalidRecovery:
case InvalidTaskMng:
case TaskStateTransitionError:
case TaskHasRefs:
case VolumeGroupSizeError:
case VolumeGroupAlreadyExistsError:
case VolumeGroupUninitialized:
case VolumeGroupHasDomainTag:
case CannotRemoveLogicalVolume:
case CannotDeactivateLogicalVolume:
case CannotActivateLogicalVolume:
case LogicalVolumePermissionsError:
case LogicalVolumeAlreadyExists:
case PartitionedPhysDev:
case DomainAlreadyLocked:
case DomainLockDoesNotExist:
case MetaDataKeyError:
case MetaDataSealIsBroken:
case MetaDataValidationError:
case MetaDataMappingError:
case MetaDataParamError:
case MetadataOverflowError:
case ImportUnknownType:
case ExportError:
case MergeVolumeRollbackError:
case ActionStopped:
case FAILED_CHANGE_CD_IS_MOUNTED:
case UnsupportedDomainVersion:
case CurrentVersionTooAdvancedError:
case iSCSILogoutError:
case iSCSIDiscoveryError:
case ISCSI_LOGIN_AUTH_ERROR:
case PoolUpgradeInProgress:
case MixedSDVersionError:
case NoSpaceLeftOnDomain:
case ImageDoesNotExistInDomainError:
case NO_IMPLEMENTATION:
case VOLUME_WAS_NOT_PREPARED_BEFORE_TEARDOWN:
case IMAGES_NOT_SUPPORTED_ERROR:
case GET_FILE_LIST_ERROR:
case STORAGE_DOMAIN_REFRESH_ERROR:
case VOLUME_GROUP_BLOCK_SIZE_ERROR:
case MIGRATION_DEST_INVALID_HOSTNAME:
case ResourceTimeout:
case HOT_PLUG_UNPLUG_CPU_ERROR:
case DEVICE_BLOCK_SIZE_NOT_SUPPORTED:
case V2V_JOB_DOESNT_EXIST:
case V2V_NO_SUCH_OVF:
case V2V_JOB_NOT_DONE:
case V2V_JOB_ALREADY_EXIST:
case UnsupportedGlusterVolumeReplicaCountError:
if (this instanceof IrsBrokerCommand || this instanceof StorageJobVDSCommand) {
outEx = new IrsOperationFailedNoFailoverException(getReturnStatus().message);
} else {
outEx = new VDSErrorException(String.format("Failed in vdscommand to %1$s, error = %2$s",
getCommandName(), getReturnStatus().message));
}
break;
case VDS_NETWORK_ERROR:
case ERR_BAD_ADDR:
outEx = new VDSNetworkException(getReturnStatus().message);
break;
default:
log.error("Failed in '{}' method", getCommandName());
outEx = createException();
break;
}
VDSError tempVar = new VDSError();
tempVar.setCode(returnStatus);
tempVar.setMessage(getReturnStatus().message);
outEx.setVdsError(tempVar);
logToAuditIfNeeded();
throw outEx;
}
private void logToAuditIfNeeded(){
if (shouldLogToAudit()) {
logToAudit();
}
}
protected boolean shouldLogToAudit() {
// if error is in expected errors list, don't audit log it
return !getParameters().getExpectedEngineErrors().contains(getReturnValueFromStatus(getReturnStatus()));
}
protected void logToAudit(){
}
private VDSExceptionBase createException() {
final String errorMessage = String.format("Failed to %1$s, error = %2$s, code = %3$s", getCommandName(),
getReturnStatus().message, getReturnStatus().code);
return createDefaultConcreteException(errorMessage);
}
protected abstract VDSExceptionBase createDefaultConcreteException(String errorMessage);
protected EngineError getReturnValueFromStatus(Status status) {
try {
EngineError bllErrors = EngineError.forValue(status.code);
if (bllErrors == null) {
log.warn("Unexpected return value: {}", status);
bllErrors = EngineError.unexpected;
}
return bllErrors;
} catch (Exception e) {
return EngineError.unexpected;
}
}
protected Object getReturnValueFromBroker() {
return status;
}
protected boolean getIsPrintReturnValue() {
return true;
}
protected String getAdditionalInformation() {
return "";
}
@SuppressWarnings("unchecked")
protected void printReturnValue() {
if (getReturnValueFromBroker() != null && getIsPrintReturnValue()) {
String returnValue;
StringBuilder builder = new StringBuilder();
if (getReturnValueFromBroker() instanceof Map) {
ObjectDescriptor.toStringBuilder((Map<String, ?>) getReturnValueFromBroker(), builder);
returnValue = builder.toString();
} else {
returnValue = getReturnValueFromBroker().toString();
}
log.info("Command '{}' return value '{}'", getClass().getName(), returnValue);
if (!StringUtils.isEmpty(getAdditionalInformation())) {
log.info(getAdditionalInformation());
}
}
}
}