@Override public StorageOperationResponse<DeleteSnapshotsResponse> deleteSnapshots( DeleteSnapshotsRequest request) { logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "deleteSnapshots: snapshots:" + request.snapshotsToBeDeleted, null); List<StorageLogMessage> logMessages = new ArrayList<StorageLogMessage>(); List<StorageSnapshotVolume> storageSnapshots = request.snapshotsToBeDeleted; for (StorageSnapshotVolume snapshotVolume : storageSnapshots) { try { this.openstackClient.deleteSnapshot(snapshotVolume.storageVolumeId); } catch (CloudClientException e) { logger.traceThrowable( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "deleteSnapshots: " + e.getMessage(), null, e); logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSBlock", System.currentTimeMillis(), e.getMessage())); } } if (logMessages.size() > 0) { return StorageAdapterImplHelper.createFailedResponse( logMessages, DeleteSnapshotsResponse.class); } else { DeleteSnapshotsResponse payload = new DeleteSnapshotsResponse(); StorageOperationResponse<DeleteSnapshotsResponse> response = new StorageOperationResponse<DeleteSnapshotsResponse>(payload); response.setPercentCompleted(100); response.setStatus(StorageOperationStatus.COMPLETED); return response; } }
/** * @param operationId * @param context * @return * @throws InfrastructAdapterException */ public StorageOperationResponse<PostProcessCloneVolumesResponse> getOperationStatus( StorageOperationId operationId, OpenstackFileCloneVolumesContext context) throws InfrastructAdapterException { logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus: operationId: " + operationId + " context: " + context, null); List<StorageLogMessage> logMessages = new ArrayList<StorageLogMessage>(); Status snapshotState = null; Share share = null; Status shareState = null; String snapshotId = null; String sourceVolumeId = null; String targetVolumeId = null; int progress = 0; int operationProgress = 0; boolean pending = false; boolean failed = false; boolean snapshotsReady = true; List<OpenstackFileCloneVolumeStatus> volumeStatus = context.volumeStatus; // STEP 1 : Check sourceSnapshot State for (OpenstackFileCloneVolumeStatus status : volumeStatus) { try { sourceVolumeId = status.volumeToBeCloned.sourceVolumeId; snapshotId = status.sourceSnapshotId; // String sourceSnapshotId = status.sourceSnapshotId; logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), " //STEP 1 : Check sourceSnapshot State " + snapshotId, null); if (status.sourceSnapshotComplete) continue; // snapshot already completed // snapshot = openstackClient.getSnapshot(snapshotId); snapshotState = openstackClient.getSnapshotStatus(snapshotId); logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus: operationId: " + operationId + " checking snapshot: " + snapshotId + " state: " + snapshotState, null); if (snapshotState.equals(Status.CREATING)) { // logger.log(IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus: // operationId: " + operationId + "checking snapshot:" + snapshotId + " progress:" + // snapshot.getProgress(), null); String percent = "0"; // snapshot.getProgress(); //progress not tracked in Openstack // if (percent.isEmpty()) { // percent = "0"; // } else { // percent = percent.substring(0,percent.length() -2); // } progress = Integer.parseInt(percent); if (progress < operationProgress) operationProgress = progress; pending = true; snapshotsReady = false; continue; } else if (snapshotState.equals(Status.AVAILABLE)) { status.sourceSnapshotComplete = true; logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus: operationId: " + operationId + " completed source snapshot: " + snapshotId, null); // if (isRemoteClone(status.volumeToBeCloned)) { // createTargetSnapshot(snapshotId, status, operationId.toString()); // } else { createTargetShare(context, status, true); // } } else if (snapshotState.equals(Status.ERROR)) { logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus: operationId: " + operationId + " failed: " + snapshotId, null); logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSFile", System.currentTimeMillis(), "Failed to Clone volume " + status.volumeToBeCloned.sourceVolumeId + ". Snapshot process terminated with ERROR")); failed = true; break; } else { throw new IllegalStateException( "Failed to Clone volume " + status.volumeToBeCloned.sourceVolumeId + ". Snapshot process returned unexpected status: " + snapshotState); } } catch (Exception e) { failed = true; logger.traceThrowable( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus:" + e.getMessage(), null, e); logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSFile", System.currentTimeMillis(), "getOperationStatus:" + e.getMessage())); } } // STEP 2: Check Target Snapshot state (for cross-region only) //TODO for (OpenstackFileCloneVolumeStatus status : context.volumeStatus) { if (isRemoteClone(status.volumeToBeCloned)) { if (status.targetSnapshotId != null && !status.targetSnapshotComplete) { try { snapshotId = status.targetSnapshotId; // snapshot = openstackClient.getSnapshot(snapshotId); snapshotState = openstackClient.getSnapshotStatus(snapshotId); logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus: operationId: " + operationId + " checking snapshot: " + snapshotId + " state: " + snapshotState, null); if (snapshotState.equals(Status.CREATING)) { // logger.log(IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), // "getOperationStatus: operationId: " + operationId + "checking snapshot:" + // snapshotId + " progress:" + snapshot.getProgress(), null); // TODO: openstack doesnt have percent complete I think so map percentages based on // state 0, 50,100 String percent = "0"; // snapshot.getStatus() if (percent.isEmpty()) { percent = "0"; } else { percent = percent.substring(0, percent.length() - 2); } progress = Integer.parseInt(percent); if (progress < operationProgress) operationProgress = progress; pending = true; snapshotsReady = false; continue; } else if (snapshotState.equals(Status.AVAILABLE)) { status.targetSnapshotComplete = true; logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus: operationId: " + operationId + " completed target snapshot: " + snapshotId, null); createTargetShare(context, status, true); } else if (snapshotState.equals(Status.ERROR)) { logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus: operationId: " + operationId + " failed: " + snapshotId, null); logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSFile", System.currentTimeMillis(), "Failed to Clone volume " + status.volumeToBeCloned.sourceVolumeId + ". Snapshot process terminated with ERROR")); failed = true; break; } else { throw new IllegalStateException( "Failed to Clone volume " + status.volumeToBeCloned.sourceVolumeId + ". Snapshot process returned unexpected status: " + snapshotState); } } catch (CloudClientException e) { failed = true; logger.traceThrowable( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus:" + e.getMessage(), null, e); logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSFile", System.currentTimeMillis(), e.getMessage())); break; } } } } // STEP 3: Check Target Volume state for (OpenstackFileCloneVolumeStatus status : context.volumeStatus) { if (status.targetVolumeId == null) continue; try { share = openstackClient.getShare(status.targetVolumeId); if (share == null) { failed = true; logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSFile", System.currentTimeMillis(), "Volume " + status.targetVolumeId + " not found")); break; } // } catch (CloudClientException e) { } catch (Exception e) { failed = true; logger.traceThrowable( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus:" + e.getMessage(), null, e); logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSFile", System.currentTimeMillis(), e.getMessage())); break; } shareState = share.getStatus(); logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus: operationId: " + operationId + " checking volume: " + share.getId() + " state: " + shareState, null); if ((shareState.equals(Status.CREATING))) { pending = true; logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus: operationId: " + operationId + " in progress: " + share.getId(), null); } else if (shareState.equals(Status.ERROR)) { logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus: operationId: " + operationId + " create volume failed: " + share.getId(), null); logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSFile", System.currentTimeMillis(), "Failed to Clone volume " + share.getId() + ". Process terminated with ERROR")); failed = true; break; } else if (shareState.equals(Status.AVAILABLE)) { logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus: operationId: " + operationId + " completed volume: " + share.getId(), null); status.targetVolumeComplete = true; // once volume is ready we can delete the temporary snapshot as it is no longer needed. if (status.targetSnapshotComplete) { snapshotId = status.targetSnapshotId; } else { snapshotId = status.sourceSnapshotId; } try { boolean forDelete = false; if (forDelete) { openstackClient.deleteSnapshot(snapshotId); } } catch (Exception e) { logger.traceThrowable( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "getOperationStatus:" + e.getMessage(), null, e); // here we just log warning as failing to delete the temporary snapshot does not fail the // clone operation logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_WARNING, "OSFile", System.currentTimeMillis(), "Failed delete temorary snapshot " + share.getSnapshotId() + ". " + e.getMessage())); } } else { logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSFile", System.currentTimeMillis(), "Unexpected volume state: " + shareState.name())); failed = true; break; } } if (failed) { // cleanup cancelVolumes(operationId, context); return StorageAdapterImplHelper.createFailedResponse( logMessages, PostProcessCloneVolumesResponse.class); } else if (pending) { PostProcessCloneVolumesResponse payload = new PostProcessCloneVolumesResponse(); StorageOperationResponse<PostProcessCloneVolumesResponse> response = new StorageOperationResponse<PostProcessCloneVolumesResponse>(payload); response.setPercentCompleted(progress); response.setId(operationId); response.setContext(context); response.setStatus(StorageOperationStatus.EXECUTING); response.setLogMessages(logMessages); return response; } else { // operation completed successfully PostProcessCloneVolumesResponse payload = new PostProcessCloneVolumesResponse(); payload.mountConfiguration = new ArrayList<MountData>(); for (OpenstackFileCloneVolumeStatus state : context.volumeStatus) { state.volumeToBeCloned.targetVolumeId = state.targetVolumeId; sourceVolumeId = state.volumeToBeCloned.sourceVolumeId; targetVolumeId = state.volumeToBeCloned.targetVolumeId; Share sourceShare = openstackClient.getShare(sourceVolumeId); String sourceExport = sourceShare.getExport(); Share targetShare = openstackClient.getShare(targetVolumeId); String targetExport = targetShare.getExport(); List<MountData> sourceMnts = state.volumeToBeCloned.sourceMountConfiguration; if (sourceMnts != null && !sourceMnts.isEmpty()) { for (int i = 0; i < sourceMnts.size(); i++) { MountData srcMD = sourceMnts.get(i); String sourceExportPath = srcMD.exportPath; if (!sourceExportPath.contains(sourceExport)) continue; MountData targetMD = state.volumeToBeCloned.targetMountConfiguration.get(i); String targetExportPath = sourceExportPath.replace(sourceExport, targetExport); targetMD.exportPath = targetExportPath; payload.mountConfiguration.add(targetMD); } } try { List<? extends ShareAccessMapping> listAccess = openstackClient.listAccess(sourceVolumeId); for (ShareAccessMapping shareAccessMapping : listAccess) { String accessTo = shareAccessMapping.getAccessTo(); Boolean active = openstackClient.allowAccess(targetVolumeId, accessTo); } } catch (Exception e) { logger.traceThrowable( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "cloneVolumes:" + e.getMessage(), null, e); // ArrayList<StorageLogMessage> logMessages = cancel(snapshots); // logMessages.add(0, new StorageLogMessage(IJavaEeLog.SEVERITY_ERROR, // "OSFile", System.currentTimeMillis(), e.getMessage())); return StorageAdapterImplHelper.createFailedResponse( logMessages, PostProcessCloneVolumesResponse.class); } } StorageOperationResponse<PostProcessCloneVolumesResponse> response = new StorageOperationResponse<PostProcessCloneVolumesResponse>(payload); response.setId(operationId); response.setPercentCompleted(100); response.setLogMessages(logMessages); response.setStatus(StorageOperationStatus.COMPLETED); return response; } }
@Override public StorageOperationResponse<CloneVolumesResponse> cloneVolumes(CloneVolumesRequest request) { String msg = ""; PrepareCloneVolumesRequest prepareRequest = (PrepareCloneVolumesRequest) request.prepareCloneVolumesResult; List<VolumeToBeCloned> volumesToBeCloned = prepareRequest.volumesToBeCloned; ArrayList<StorageLogMessage> logMessages = new ArrayList<StorageLogMessage>(); logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "cloneVolumes: request:" + prepareRequest, null); msg = "CloneVolumes operation started"; logMessages.add( new StorageLogMessage(IJavaEeLog.SEVERITY_INFO, "OSFile", System.currentTimeMillis(), msg)); String operationId = OpenstackAdapterUtil.generateOperationId(); ArrayList<String> snapshots = new ArrayList<String>(); OpenstackFileCloneVolumesContext context = new OpenstackFileCloneVolumesContext(); context.volumeStatus = new ArrayList<OpenstackFileCloneVolumeStatus>(); OpenstackFileCloneVolumeStatus status; for (VolumeToBeCloned inputVolume : volumesToBeCloned) { status = new OpenstackFileCloneVolumeStatus(); status.volumeToBeCloned = inputVolume; status.customCloningProperties = prepareRequest.customCloningProperties; context.volumeStatus.add(status); try { if (inputVolume.isSourceVolumeSnapshot) { if (openstackClient.getSnapshot(inputVolume.sourceVolumeId) != null) { status.sourceSnapshotComplete = true; status.sourceSnapshotId = inputVolume.sourceVolumeId; if (isRemoteClone(status.volumeToBeCloned)) { createTargetSnapshot(status.sourceSnapshotId, status, operationId); snapshots.add(status.targetSnapshotId); msg = "Target snapshot" + status.targetSnapshotId + " created"; logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_INFO, "LVM", System.currentTimeMillis(), msg)); } } else { msg = "Snapshot not found: " + inputVolume.sourceVolumeId; logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSFile", System.currentTimeMillis(), msg)); return StorageAdapterImplHelper.createFailedResponse( logMessages, CloneVolumesResponse.class); } } else { ShareSnapshot snapshot = null; try { String snapshotName = "Snapshot of share " + inputVolume.sourceVolumeId; String snapshotDescription = "LVM Snapshot to clone share " + inputVolume.sourceVolumeId; snapshot = openstackClient.createShareSnapshot( inputVolume.sourceVolumeId, snapshotName, snapshotDescription); } catch (CloudClientException e) { throw e; } snapshots.add(snapshot.getId()); status.sourceSnapshotId = snapshot.getId(); } } catch (CloudClientException e) { logger.traceThrowable( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "cloneVolumes:" + e.getMessage(), null, e); logMessages.add( 0, new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSFile", System.currentTimeMillis(), e.getMessage())); return StorageAdapterImplHelper.createFailedResponse( logMessages, CloneVolumesResponse.class); } } msg = "CloneVolumes operation ended"; logMessages.add( new StorageLogMessage(IJavaEeLog.SEVERITY_INFO, "OSFile", System.currentTimeMillis(), msg)); CloneVolumesResponse payload = new CloneVolumesResponse(); context.operationId = operationId; context.customCloningProperties = prepareRequest.customCloningProperties; payload.cloneVolumeResult = context; StorageOperationResponse<CloneVolumesResponse> response = new StorageOperationResponse<CloneVolumesResponse>(payload); response.setLogMessages(logMessages); response.setPercentCompleted(100); response.setStatus(StorageOperationStatus.COMPLETED); response.setContext(context); return response; }
/** * @param operationId * @param context * @return * @throws InfrastructAdapterException */ public StorageOperationResponse<PostProcessCloneVolumesResponse> cancelVolumes( StorageOperationId operationId, OpenstackFileCloneVolumesContext context) throws InfrastructAdapterException { logger.log( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "cancelVolumes: operationId: " + operationId + " volumeStauts: " + context.volumeStatus, null); List<StorageLogMessage> logMessages = new ArrayList<StorageLogMessage>(); for (OpenstackFileCloneVolumeStatus status : context.volumeStatus) { if (status.sourceSnapshotId != null) { try { openstackClient.deleteSnapshot(status.sourceSnapshotId); } catch (CloudClientException e) { logger.traceThrowable( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "cancelVolumes:" + e.getMessage(), null, e); logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSFile", System.currentTimeMillis(), e.getMessage())); } } if (status.targetSnapshotId != null) { try { openstackClient.deleteSnapshot(status.targetSnapshotId); } catch (CloudClientException e) { logger.traceThrowable( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "cancelVolumes:" + e.getMessage(), null, e); logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSFile", System.currentTimeMillis(), e.getMessage())); } } if (status.targetVolumeId != null) { try { openstackClient.deleteShare(status.targetVolumeId); // } catch (CloudClientException e) { } catch (Exception e) { logger.traceThrowable( IJavaEeLog.SEVERITY_DEBUG, this.getClass().getName(), "cancelVolumes:" + e.getMessage(), null, e); logMessages.add( new StorageLogMessage( IJavaEeLog.SEVERITY_ERROR, "OSFile", System.currentTimeMillis(), e.getMessage())); } } } if (logMessages.isEmpty()) { PostProcessCloneVolumesResponse payload = new PostProcessCloneVolumesResponse(); payload.mountConfiguration = new ArrayList<MountData>(); StorageOperationResponse<PostProcessCloneVolumesResponse> response = new StorageOperationResponse<PostProcessCloneVolumesResponse>(payload); response.setPercentCompleted(100); response.setStatus(StorageOperationStatus.CANCELLED); return response; } else { return StorageAdapterImplHelper.createFailedResponse( logMessages, PostProcessCloneVolumesResponse.class); } }