1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.mycore.services.queuedjob;
19
20 import java.io.OutputStream;
21 import java.io.PrintStream;
22 import java.nio.charset.StandardCharsets;
23 import java.util.ArrayList;
24 import java.util.Date;
25 import java.util.List;
26 import java.util.Locale;
27 import java.util.stream.Collectors;
28 import java.util.stream.StreamSupport;
29
30 import org.mycore.frontend.jersey.filter.access.MCRRestrictedAccess;
31
32 import jakarta.inject.Singleton;
33 import jakarta.ws.rs.GET;
34 import jakarta.ws.rs.Path;
35 import jakarta.ws.rs.PathParam;
36 import jakarta.ws.rs.Produces;
37 import jakarta.ws.rs.core.MediaType;
38 import jakarta.ws.rs.core.Response;
39 import jakarta.ws.rs.core.StreamingOutput;
40 import jakarta.xml.bind.annotation.XmlAttribute;
41 import jakarta.xml.bind.annotation.XmlElement;
42 import jakarta.xml.bind.annotation.XmlRootElement;
43 import jakarta.xml.bind.annotation.XmlValue;
44
45
46
47
48
49 @Path("jobqueue")
50 @Singleton
51 public class MCRJobQueueResource {
52
53 @GET()
54 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
55 @MCRRestrictedAccess(MCRJobQueuePermission.class)
56 public Response listJSON() {
57 try {
58 Queues queuesEntity = new Queues();
59 queuesEntity.addAll(
60 MCRJobQueue.INSTANCES.keySet().stream().map(Queue::new).collect(Collectors.toList()));
61
62 return Response
63 .ok()
64 .status(Response.Status.OK)
65 .entity(queuesEntity)
66 .build();
67 } catch (Exception e) {
68 final StreamingOutput so = (OutputStream os) -> e
69 .printStackTrace(new PrintStream(os, false, StandardCharsets.UTF_8.name()));
70 return Response
71 .status(Response.Status.INTERNAL_SERVER_ERROR)
72 .type(MediaType.TEXT_PLAIN_TYPE)
73 .entity(so)
74 .build();
75 }
76 }
77
78 @GET()
79 @Path("{name:.+}")
80 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
81 @MCRRestrictedAccess(MCRJobQueuePermission.class)
82 public Response queueJSON(@PathParam("name") String name) {
83 try {
84 Queue queue = MCRJobQueue.INSTANCES.entrySet().stream().filter(e -> e.getKey().equals(name)).findFirst()
85 .map(e -> {
86 Queue q = new Queue(e.getKey());
87
88 MCRJobQueue jq = e.getValue();
89 Iterable<MCRJob> iterable = () -> jq.iterator(null);
90 q.jobs = StreamSupport.stream(iterable.spliterator(), false).map(Job::new)
91 .collect(Collectors.toList());
92
93 return q;
94 }).orElse(null);
95
96 return Response
97 .ok()
98 .status(Response.Status.OK)
99 .entity(queue)
100 .build();
101 } catch (Exception e) {
102 final StreamingOutput so = (OutputStream os) -> e
103 .printStackTrace(new PrintStream(os, false, StandardCharsets.UTF_8.name()));
104 return Response
105 .status(Response.Status.INTERNAL_SERVER_ERROR)
106 .type(MediaType.TEXT_PLAIN_TYPE)
107 .entity(so)
108 .build();
109 }
110 }
111
112 @XmlRootElement(name = "queues")
113 static class Queues {
114 @XmlElement(name = "queue")
115 List<Queue> queues;
116
117 void add(Queue queue) {
118 if (queues == null) {
119 queues = new ArrayList<>();
120 }
121
122 queues.add(queue);
123 }
124
125 void addAll(List<Queue> queues) {
126 if (this.queues == null) {
127 this.queues = new ArrayList<>();
128 }
129
130 this.queues.addAll(queues);
131 }
132 }
133
134 @XmlRootElement(name = "queue")
135 static class Queue {
136 @XmlAttribute
137 String name;
138
139 @XmlElement(name = "job")
140 List<Job> jobs;
141
142 Queue() {
143 }
144
145 Queue(String name) {
146 this.name = name;
147 }
148 }
149
150 @XmlRootElement(name = "job")
151 static class Job {
152 @XmlAttribute
153 long id;
154
155 @XmlAttribute
156 String status;
157
158 @XmlElement(name = "date")
159 List<TypedDate> dates;
160
161 @XmlElement(name = "parameter")
162 List<Parameter> parameters;
163
164 Job() {
165 }
166
167 Job(MCRJob job) {
168 this.id = job.getId();
169 this.status = job.getStatus().toString().toLowerCase(Locale.ROOT);
170
171 List<TypedDate> dates = new ArrayList<>();
172 if (job.getAdded() != null) {
173 dates.add(new TypedDate("added", job.getAdded()));
174 }
175 if (job.getStart() != null) {
176 dates.add(new TypedDate("start", job.getStart()));
177 }
178 if (job.getFinished() != null) {
179 dates.add(new TypedDate("finished", job.getFinished()));
180 }
181
182 this.parameters = job.getParameters().entrySet().stream().map(e -> new Parameter(e.getKey(), e.getValue()))
183 .collect(Collectors.toList());
184
185 if (!dates.isEmpty()) {
186 this.dates = dates;
187 }
188 }
189 }
190
191 @XmlRootElement(name = "date")
192 static class TypedDate {
193 @XmlAttribute
194 String type;
195
196 @XmlValue
197 Date date;
198
199 TypedDate() {
200 }
201
202 TypedDate(String type, Date date) {
203 this.type = type;
204 this.date = date;
205 }
206 }
207
208 @XmlRootElement(name = "parameter")
209 static class Parameter {
210 @XmlAttribute
211 String name;
212
213 @XmlValue
214 String value;
215
216 Parameter() {
217 }
218
219 Parameter(String name, String value) {
220 this.name = name;
221 this.value = value;
222 }
223 }
224
225 }