@Override protected void handleStartedStagePatch(ContainerVolumeProvisionTaskState state) { switch (state.taskSubStage) { case CREATED: provisionVolumes(state); break; case PROVISIONING: break; case COMPLETED: complete(); break; case ERROR: completeWithError(); break; default: break; } }
private void provisionVolume(ContainerVolumeProvisionTaskState state, String volumeLink, ComputeState host, ServiceTaskCallback taskCallback) { updateContainerVolumeStateWithContainerHostLink(volumeLink, host, () -> createAndSendContainerVolumeRequest(state, taskCallback, volumeLink)); }
private void createTaskCallback(ContainerVolumeProvisionTaskState state, Consumer<ServiceTaskCallback> callbackFunction) { createCounterSubTaskCallback( state, state.resourceCount, false, SubStage.COMPLETED, (callback) -> { callbackFunction.accept(callback); }); }
private void selectHost(ContainerVolumeProvisionTaskState state, Consumer<ComputeState> callback) { getContextContainerStates(state, (states) -> { getContextContainerDescriptions(states, (descriptions) -> { List<ContainerState> containerStatesForVolume = getDependantContainerStates( descriptions, states, volumeDescription); if (containerStatesForVolume.isEmpty()) { String err = String.format( "No container states depending on volume description [%s] found.", volumeDescription.name); failTask(err, null); } else { String hostLink = containerStatesForVolume.get(0).parentLink; getHost(hostLink, (host) -> { callback.accept(host); }); } }); }); }
private void provisionVolumes(ContainerVolumeProvisionTaskState state) { logInfo("Provision request for %s volumes", state.resourceCount); getContainerVolumeDescription(state, (volumeDescription) -> { if (Boolean.TRUE.equals(volumeDescription.external)) { getVolumeByName(state, volumeDescription.name, (volumeState) -> { updateContainerVolumeState(state, volumeState, () -> { proceedTo(SubStage.COMPLETED, s -> { }); } else { createTaskCallback(state, (taskCallback) -> { state.instanceAdapterReference = volumeDescription.instanceAdapterReference; selectHosts(state, volumeDescription, (hosts) -> { ComputeState host = hostIt.next(); for (String volumeLink : state.resourceLinks) { provisionVolume(state, volumeLink, host, taskCallback); + " links! Actual resources - [%s], hosts - [%s]", state.resourceLinks.size(), hosts.size()); failTask(err, null); proceedTo(SubStage.PROVISIONING);
private void createAndSendContainerVolumeRequest(ContainerVolumeProvisionTaskState state, ServiceTaskCallback taskCallback, String volumeSelfLink) { AdapterRequest volumeRequest = new AdapterRequest(); volumeRequest.resourceReference = UriUtils.buildUri(getHost(), volumeSelfLink); volumeRequest.serviceTaskCallback = taskCallback; if (Boolean.TRUE.equals(volumeDescription.external)) { // The volume is defined as external, just validate that it exists actually. volumeRequest.operationTypeId = VolumeOperationType.INSPECT.id; } else { volumeRequest.operationTypeId = VolumeOperationType.CREATE.id; } volumeRequest.customProperties = state.customProperties; sendRequest(Operation.createPatch(getHost(), state.instanceAdapterReference.toString()) .setBody(volumeRequest) .setContextId(getSelfId()) .setCompletion((o, e) -> { if (e != null) { failTask("AdapterRequest failed for volume: " + volumeSelfLink, e); return; } logInfo("Volume provisioning started for: %s", volumeSelfLink); })); }
private void updateContainerVolumeStateWithContainerHostLink(String volumeSelfLink, ComputeState host, Runnable callbackFunction) { ContainerVolumeState patch = new ContainerVolumeState(); patch.originatingHostLink = host.documentSelfLink; patch.parentLinks = new ArrayList<>(Arrays.asList(host.documentSelfLink)); sendRequest(Operation .createPatch(this, volumeSelfLink) .setBody(patch) .setCompletion( (o, e) -> { if (e != null) { logWarning("Error while updating volume: %s", volumeSelfLink); failTask(String.format("Error while updating volume: %s", volumeSelfLink), e); } else { callbackFunction.run(); } })); }
private void selectHosts(ContainerVolumeProvisionTaskState state, ContainerVolumeDescription volumeDescription, Consumer<List<ComputeState>> callback) { // If hosts are provided use them directly to try to provision the volume // (e.g. when External volume CRUD operations) List<String> providedHostLinks = ContainerVolumeAllocationTaskService .getProvidedHostIdsAsSelfLinks(state); if (providedHostLinks != null) { retrieveContainerHostsByLinks(state, providedHostLinks, (hosts) -> { List<String> disabledHosts = hosts.stream().filter((host) -> { return host.powerState != PowerState.ON; }).map(host -> host.address).collect(Collectors.toList()); if (disabledHosts.isEmpty()) { callback.accept(hosts); } else { String err = String.format( "Requested volume provisioning for disabled hosts: [%s].", disabledHosts); failTask(err, null); } }); return; } selectHost(state, (host) -> { callback.accept(Collections.singletonList(host)); }); }
private void getContextContainerDescriptions( Map<String, List<ContainerState>> containersByDescriptionLink, Consumer<List<ContainerDescription>> callback) { if ((containersByDescriptionLink == null) || (containersByDescriptionLink.isEmpty())) { callback.accept(Collections.emptyList()); return; } QueryTask q = QueryUtil.buildQuery(ContainerDescription.class, true); QueryUtil.addExpandOption(q); QueryUtil.addListValueClause(q, ContainerDescription.FIELD_NAME_SELF_LINK, containersByDescriptionLink.keySet()); q.taskInfo.isDirect = false; List<ContainerDescription> result = new ArrayList<>(); new ServiceDocumentQuery<ContainerDescription>(getHost(), ContainerDescription.class) .query(q, (r) -> { if (r.hasException()) { failTask("Exception while selecting container descriptions", r.getException()); } else if (r.hasResult()) { result.add(r.getResult()); } else { callback.accept(result); } }); }
private void getVolumeByName(ContainerVolumeProvisionTaskState state, String volumeName, Consumer<ContainerVolumeState> callback) { selectHost(state, (host) -> { List<ContainerVolumeState> volumeStates = new ArrayList<ContainerVolumeState>(); QueryTask queryTask = VolumeUtil .getVolumeByHostAndNameQueryTask(host.documentSelfLink, volumeName); new ServiceDocumentQuery<ContainerVolumeState>(getHost(), ContainerVolumeState.class) .query(queryTask, (r) -> { if (r.hasException()) { failTask("Failed to query for active volume by name '" + volumeName + "' in host '" + host.documentSelfLink + "'!", r.getException()); } else if (r.hasResult()) { if (volumeName.equals(r.getResult().name)) { volumeStates.add(r.getResult()); } } else { if (volumeStates.size() == 1) { callback.accept(volumeStates.get(0)); return; } failTask(volumeStates.size() + " active volume(s) found by name '" + volumeName + "' in host '" + host.documentSelfLink + "'!", null); } }); }); }
private void getContainerVolumeDescription(ContainerVolumeProvisionTaskState state, Consumer<ContainerVolumeDescription> callbackFunction) { if (volumeDescription != null) { callbackFunction.accept(volumeDescription); return; } sendRequest(Operation.createGet(this, state.resourceDescriptionLink) .setCompletion( (o, e) -> { if (e != null) { failTask("Failure retrieving container volume description.", e); return; } ContainerVolumeDescription desc = o .getBody(ContainerVolumeDescription.class); this.volumeDescription = desc; callbackFunction.accept(desc); })); }
private void getHost(String hostLink, Consumer<ComputeState> callback) { Operation.createGet(this, hostLink).setCompletion((op, ex) -> { if (ex != null) { failTask("Failed retrieving host: " + Utils.toString(ex), null); return; } ComputeState host = op.getBody(ComputeState.class); callback.accept(host); }).sendWith(this); }
sendRequest(Operation .createPatch(this, currentVolumeState.documentSelfLink) .setBody(patch) (o, e) -> { if (e != null) { logWarning("Error while updating volume: %s", currentVolumeState.documentSelfLink); failTask(String.format("Error while updating volume: %s", currentVolumeState.documentSelfLink), e); } else {
QueryUtil.addExpandOption(queryTask); new ServiceDocumentQuery<ComputeState>(getHost(), ComputeState.class) .query(queryTask, (r) -> { if (r.hasException()) { failTask(String.format( "Exception during retrieving hosts with links [%s]. Error: [%s]", hostLinks, } else { if (!remainingHostLinks.isEmpty()) { failTask(String.format( "Not all hosts were found! Remaining hosts: [%s]!", remainingHostLinks),