I have this fragment of code that has to be executed repeatedly to validate deployment status
while (true) {
var logsFlags = devOpsClient.obtainInfoTaskFromRelease(personalToken, responseCreateRelease.getEnvironments().get(0).getReleaseId(), responseCreateRelease.getEnvironments().get(0).getId());
if ("inProgress".equalsIgnoreCase(logsFlags.getStatus()) || "queued".equalsIgnoreCase(logsFlags.getStatus())) {
Thread.sleep(3000);
Thread.currentThread().
log.info("Count {}", count++);
continue;
} else if ("succeeded".equalsIgnoreCase(logsFlags.getStatus())) {
break;
} else if ("rejected".equalsIgnoreCase(logsFlags.getStatus())) {
throw new Exception("The resource to be displayed failed, check de Logs");
}
break;
}
log.info("Status Finished - Resource {} deployed", data.getResource());
This makes use of the feign client
@FeignClient(
value = "devopsCell-svc",
url = "https://vsrm.dev.azure.com"
)
public interface DevOpsClient {
@PostMapping("/cell/Deployments-Terraform/_apis/release/releases?api-version=7.1-preview.8")
ResponseCreateRelease executeManualRelease(
@RequestHeader("Authorization") String authorizationHeader,
@RequestBody ReleaseDTO releaseDTO
);
@GetMapping("/cell/Deployments-Terraform/_apis/Release/releases/{releaseId}/environments/{environmentId}?api-version=7.1-preview.7")
DeploymentDTO obtainInfoTaskFromRelease(
@RequestHeader("Authorization") String authorizationHeader,
@PathVariable("releaseId") Integer releaseId,
@PathVariable("environmentId") Integer environmentId
);
The point is that it is blocking since as I repeatedly consult the status, obtainInfoTaskFromRelease becomes blocked so I would not know how to implement the asynchronous calls and at least that function is no longer blocking, since from the controller it has its own endpoint and is not can run by the above
@PostMapping("/data-deploy")
public ResponseEntity<String> dataIaCDevOpS(@RequestBody RequestIaCDTO requestList) throws Exception {
return databaseService.dataIaC(Shield.blindRequestIaCDTO(requestList));
}
@PostMapping("/obtain-tasks-release")
public SimplifiedDeploymentDTO responseTaskRelease(@RequestParam(name = "releaseId") Integer releaseId,
@RequestParam(name = "environmentId") Integer environmentId){
return databaseService.responseTaskRelease(Integer.valueOf(Shield.blindStr(String.valueOf(releaseId))), Integer.valueOf(Shield.blindStr(String.valueOf(environmentId))));
}
obtain-tasks-release is an endpoint that consumes obtainInfoTaskFromRelease to show the status, so the current problem is that if the while is repeatedly consulting obtainInfoTaskFromRelease, if I call obtain-tasks-release it will not respond to me until the while does so stop consulting
I appreciate if you can guide me to be able to carry out the process of including some asynchronous solution that does not block the obtainInfoTaskFromRelease function.
If you want know when is in progress, failed or complete you cannot make this in a single request.
Because the first call can be response with pending but if you want continuiosly the current state, you must call N time the endpoint obtain-tasks-release (polling https://en.wikipedia.org/wiki/Polling_(computer_science)). This method for a personal opinion i don't like.
Another way is make a streaming communication using for example https://www.baeldung.com/java-grpc-streaming
This example is to use the polling communication.
Your endpoint will return a CompletableFuture that will maintain the current state.