Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the REST Endpoint to manage the job queue #29480

Closed
Tracked by #29474
fabrizzio-dotCMS opened this issue Aug 6, 2024 · 9 comments · Fixed by #30303 or #30386
Closed
Tracked by #29474

Implement the REST Endpoint to manage the job queue #29480

fabrizzio-dotCMS opened this issue Aug 6, 2024 · 9 comments · Fixed by #30303 or #30386

Comments

@fabrizzio-dotCMS
Copy link
Contributor

fabrizzio-dotCMS commented Aug 6, 2024

Parent Issue

#29474

Task

As a developer, I need to create a REST endpoint to manage the creation, execution, monitoring, and querying of system tasks. This endpoint will serve as the main interface for users to interact with the job system, allowing them to enqueue new jobs, check job status, cancel running jobs, retry failed jobs, and monitor job progress in real-time using Server-Sent Events (SSE).real time

Proposed Objective

Core Features

Proposed Priority

Priority 3 - Average

Acceptance Criteria

  1. Job Creation Endpoint: Implement a REST endpoint to create and enqueue new jobs.
    1.1. The endpoint should accept job parameters and optionally a queue name.
    1.2. The response should include a unique job identifier.
  2. Job Status Inquiry Endpoint: Implement a REST endpoint to query the status of a specific job.
    2.1. The status should include the job state, progress percentage, and the node executing the job.
  3. Job Cancellation Endpoint: Implement a REST endpoint to cancel a running job.
    3.1. The endpoint should update the job status to "canceled."
  4. Job Retry Endpoint: Implement a REST endpoint to retry a failed job.
    4.1. The endpoint should reset the job status to "pending" and re-enqueue it.
  5. List Jobs Endpoint: Implement a REST endpoint to list all enqueued jobs and their statuses.
  6. Real-Time Job Monitoring Endpoint: Implement a REST endpoint to monitor job status in real time using Server-Sent Events (SSE).
    6.1. The endpoint should stream updates on job status changes, progress, and completion to the client.
  7. Error Handling: Ensure all endpoints handle errors gracefully and return appropriate HTTP status codes and messages.
  8. Documentation: Document the REST API endpoints, including request and response formats and examples.
  9. Write the adequate postman test if applicable

Let the following code serve as a high-level example:

// JobResource.java (JAX-RS)
@Path("/jobs")
public class JobResource {
    @Inject
    private JobQueue jobQueue;

    @POST
    @Path("/{queueName}")
    public Response addJob(@PathParam("queueName") String queueName, Map<String, Object> parameters) {
        String jobId = jobQueue.addJob(queueName, parameters);
        return Response.ok(jobId).build();
    }

    @GET
    @Path("/{jobId}")
    public Response getJob(@PathParam("jobId") String jobId) {
        Job job = jobQueue.getJob(jobId);
        return Response.ok(job).build();
    }

    @GET
    @Path("/{queueName}/active")
    public Response getActiveJobs(@PathParam("queueName") String queueName,
                                  @QueryParam("page") @DefaultValue("1") int page,
                                  @QueryParam("pageSize") @DefaultValue("10") int pageSize) {
        List<Job> jobs = jobQueue.getActiveJobs(queueName, page, pageSize);
        return Response.ok(jobs).build();
    }

    @GET
    @Path("/{queueName}/completed")
    public Response getCompletedJobs(@PathParam("queueName") String queueName,
                                     @QueryParam("startDate") String startDate,
                                     @QueryParam("endDate") String endDate,
                                     @QueryParam("page") @DefaultValue("1") int page,
                                     @QueryParam("pageSize") @DefaultValue("10") int pageSize) {
        LocalDateTime start = LocalDateTime.parse(startDate);
        LocalDateTime end = LocalDateTime.parse(endDate);
        List<Job> jobs = jobQueue.getCompletedJobs(queueName, start, end, page, pageSize);
        return Response.ok(jobs).build();
    }

    @GET
    @Path("/{jobId}/watch")
    @Produces(MediaType.SERVER_SENT_EVENTS)
    public void watchJob(@PathParam("jobId") String jobId, @Context SseEventSink eventSink) {
        CompletableFuture<Job> future = jobQueue.watchJob(jobId);
        future.thenAccept(job -> {
            eventSink.send(sse.newEvent(Json.encode(job)));
            eventSink.close();
        });
    }
}

External Links... Slack Conversations, Support Tickets, Figma Designs, etc.

No response

Assumptions & Initiation Needs

No response

Quality Assurance Notes & Workarounds

No response

Sub-Tasks & Estimates

No response

@wezell
Copy link
Contributor

wezell commented Aug 8, 2024

Just a note, and I am sure you are on it, but we will need to be careful with the addJob and passing in clazz names to run/instantiate. We will probably need an allow list of job classes that can be called (and allow customers to add to it via osgi).

@fabrizzio-dotCMS
Copy link
Contributor Author

Just a note, and I am sure you are on it, but we will need to be careful with the addJob and passing in clazz names to run/instantiate. We will probably need an allow list of job classes that can be called (and allow customers to add to it via osgi).

#29544

@fabrizzio-dotCMS fabrizzio-dotCMS self-assigned this Sep 30, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 2, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 2, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 3, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 3, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 4, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 7, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 7, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 8, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 8, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 8, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 9, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 9, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 9, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 9, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 9, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 9, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 9, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 10, 2024
fabrizzio-dotCMS added a commit that referenced this issue Oct 10, 2024
@fabrizzio-dotCMS
Copy link
Contributor Author

None of this seems objective to me for the goal we're trying to accomplish here.

Tested every one of the endpoints and here some feedback

  • For the /status endpoint, we need to return more information because this is the only way to retrieve details about a specific job by ID. Therefore, we should return all the complete information about the job, just as we do for failed jobs. In the status response, all job-related information must be included.

We have purposely limited the info displayed here. to only what is necessary for knowing the status.

Job Status: Image

Failed job: Image

Failed Job gives away more info for debugging purposes.

  • Multipart is always required when creating a new job. If you only send an 'application/json' instead of "multipart/form-data" in the request without including the multipart, it will fail. We need to allow job creation without the need to send files—just by sending a regular JSON with the necessary information.

Okay, the endpoint is designed to take a multipart request. for a reason: It can take files and a set of parameters in json format.
To fulfill this request of yours I would need to write another endpoint that consumes JSON
and have it named differently to avoid a clash. That would be confusing.
Therefore one single endpoint thought to process a multipart request is the way here.

Image

  • We need to rename the following endpoint baseUrl}}/api/v1/jobs/queues. I think we should rename it to types or processors, as the term 'queue' is not descriptive enough to list all the available job types. It's unclear and can cause confusion

This is ambiguous. Would renaming it to type make it clearer? We have a concept and a design behind this.
The Processor is annotated with a Queue name. There's a link between the two concepts
The fact that we can name a queue for a given purpose is what makes this the JobQueue

  • Finally, creating a new endpoint to get jobs by status could be useful, as we currently don't have a way to filter all the jobs with a specific status.

True, but there is no need to reject a ticket for that. This work fulfills the requirements. file a ticket for an enhancement.

@bryanboza bryanboza added Next Release Bug Fixing and removed Release : 24.10.16 Upgrade Fixes labels Oct 16, 2024
@fabrizzio-dotCMS
Copy link
Contributor Author

fabrizzio-dotCMS commented Oct 17, 2024

After talking with @bryanboza, we agreed that we need an endpoint to retrieve a job in full detail using an identifier. This endpoint must include all the info already shown in other endpoints.
So the following endpodint will be updated to include the additional job details {{baseUrl}}/api/v1/jobs/{{jobId}}/status which only brought partial info about the issue.

@bryanboza
Copy link
Member

@fabrizzio-dotCMS Please make sure the postman test related to this endpoint use JWT instead basic auth.

fabrizzio-dotCMS added a commit that referenced this issue Oct 17, 2024
Copy link

@fabrizzio-dotCMS
Copy link
Contributor Author

@bryanboza, The following endpoint {{baseUrl}}/api/v1/jobs/{{jobId}}/status has been updated to include all additional details as shown on the job-list endpoints.
Postman was also updated to work with JWT

@bryanboza
Copy link
Member

bryanboza commented Oct 21, 2024

  • Status

Tested every one of the endpoints and here some feedback

  • For the /status endpoint, we need to return more information because this is the only way to retrieve details about a specific job by ID. Therefore, we should return all the complete information about the job, just as we do for failed jobs. In the status response, all job-related information must be included.

Job Status: Image

Failed job: Image

  • Multipart is always required when creating a new job. If you only send an 'application/json' instead of "multipart/form-data" in the request without including the multipart, it will fail. We need to allow job creation without the need to send files—just by sending a regular JSON with the necessary information.

Image

  • Finally, creating a new endpoint to get jobs by status could be useful, as we currently don't have a way to filter all the jobs with a specific status.

So to summarize this fix:

  • Point 1, was fixed and now the status endpoint is returning the complete information. ✅
    image

  • Point 2, according to @fabrizzio-dotCMS is a jersey limitation. We need to create a new endpoint to handle this case in the future.

  • Point 3, need to be reported as an enhancement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment