-
Notifications
You must be signed in to change notification settings - Fork 7
/
JobsController.java
180 lines (167 loc) · 7.06 KB
/
JobsController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
* Made with all the love in the world
* by scireum in Remshalden, Germany
*
* Copyright by scireum GmbH
* http://www.scireum.de - [email protected]
*/
package sirius.biz.jobs;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import sirius.biz.jobs.params.Autocompleter;
import sirius.biz.web.Action;
import sirius.biz.web.BizController;
import sirius.kernel.commons.Strings;
import sirius.kernel.di.Injector;
import sirius.kernel.di.std.Part;
import sirius.kernel.di.std.Register;
import sirius.kernel.health.Exceptions;
import sirius.kernel.nls.NLS;
import sirius.web.controller.AutocompleteHelper;
import sirius.web.controller.Controller;
import sirius.web.controller.DefaultRoute;
import sirius.web.controller.Message;
import sirius.web.controller.Routed;
import sirius.web.http.WebContext;
import sirius.web.security.LoginRequired;
import sirius.web.security.UserContext;
import sirius.web.services.ApiResponsesFrom;
import sirius.web.services.DefaultErrorResponsesJson;
import sirius.web.services.InternalService;
import sirius.web.services.JSONStructuredOutput;
import sirius.web.services.PublicService;
import java.util.List;
/**
* Provides the UI for the jobs framework.
*/
@Register(framework = Jobs.FRAMEWORK_JOBS)
public class JobsController extends BizController {
@Part
private Jobs jobs;
/**
* Used to list all available jobs for the current user.
*
* @param webContext the current request
*/
@Routed("/jobs")
@DefaultRoute
@LoginRequired
public void jobs(WebContext webContext) {
List<Action> actions =
jobs.getAvailableJobs(null).filter(JobFactory::canStartInteractive).map(this::toAction).toList();
webContext.respondWith().template("/templates/biz/jobs/jobs.html.pasta", actions);
}
private Action toAction(JobFactory jobFactory) {
return new Action(jobFactory.getLabel(),
"/job/" + jobFactory.getName(),
NLS.smartGet(jobFactory.getCategory())).withDescription(jobFactory.getDescription())
.withIcon(jobFactory.getIcon());
}
/**
* Launches the job with the given name.
*
* @param webContext the current request
* @param jobType the name of the job to launch
*/
@Routed("/job/:1")
@LoginRequired
public void job(WebContext webContext, String jobType) {
try {
jobs.findFactory(jobType, JobFactory.class).startInteractively(webContext);
} catch (IllegalArgumentException exception) {
UserContext.get()
.addMessage(Message.error()
.withTextMessage(NLS.fmtr("JobsController.unknownJob")
.set("jobType", jobType)
.format()));
webContext.respondWith().redirectToGet("/jobs");
}
}
/**
* Checks the user input on the job parameters and returns a response that will be handled in the frontend
* accordingly.
*
* @param webContext the web context
* @param output the output to write the JSON response to
* @param jobType the type of the job, so we can find a suitable job factory
*/
@Routed("/job/params/:1")
@InternalService
@LoginRequired
public void params(WebContext webContext, JSONStructuredOutput output, String jobType) {
output.property("params",
jobs.findFactory(jobType, JobFactory.class).computeRequiredParameterUpdates(webContext));
}
/**
* Outputs the documentation for a job.
*
* @param webContext the current request
* @param jobType the name of the job to fetch the documentation for
*/
@Routed("/jobs/infos/:1")
@LoginRequired
public void infos(WebContext webContext, String jobType) {
webContext.respondWith()
.template("/templates/biz/jobs/infos.html.pasta", jobs.findFactory(jobType, JobFactory.class));
}
/**
* Uses a JSON call to invoke a job.
*
* @param webContext the current request
* @param output the output to write the JSON response to
* @param jobType the name of the job to launch
*/
@Routed("/jobs/api/:1")
@PublicService(apiName = "jobs-processes", path = "/jobs/api/{job}")
@Operation(summary = "Start Job", method = "POST", description = """
Starts the given job. Note that the expected job parameters have to be passed in as additional HTTP
parameters. Note that only POST requests are handled to prevent forged requests from being executed
too easily.
""")
@ApiResponse(responseCode = "200",
description = "Successfully started job containing the ID of the started process.",
content = @Content(mediaType = "application/json", examples = @ExampleObject(//language=JSON
"""
{
"success":true,
"error":false,
"process":"KR8E6I36AK7POAK0IP9L3KB0Q1"
}
""")))
@ApiResponsesFrom(DefaultErrorResponsesJson.class)
@Parameter(name = "process",
description = "The name of the job to start.",
required = true,
example = "jupiter-sync")
@LoginRequired
public void jsonApi(WebContext webContext, JSONStructuredOutput output, String jobType) {
enforceMethodPost(webContext);
try {
JobFactory factory = jobs.findFactory(jobType, JobFactory.class);
output.property("process", factory.startInBackground(webContext::get));
} catch (IllegalArgumentException exception) {
throw Exceptions.createHandled()
.withDirectMessage(Strings.apply("Unknown factory: %s", jobType))
.hint(Controller.HTTP_STATUS, HttpResponseStatus.NOT_FOUND.code())
.handle();
}
}
/**
* A route that can handle autocompletes of parameter input fields via the {@link Autocompleter}.
*
* @param webContext the web context
* @param output the output to write the JSON response to
* @param autocompleterName the name of the autocompleter
*/
@Routed("/jobs/parameter-autocomplete/:1")
@InternalService
@LoginRequired
public void autocomplete(WebContext webContext, JSONStructuredOutput output, String autocompleterName) {
Autocompleter<?> autocompleter = Injector.context().getPart(autocompleterName, Autocompleter.class);
AutocompleteHelper.handle(webContext, (query, result) -> autocompleter.suggest(query, webContext, result));
}
}