3 import java.io.IOException;
4 import java.io.PrintWriter;
5 import java.util.concurrent.CompletableFuture;
7 import javax.servlet.http.HttpServletRequest;
8 import javax.servlet.http.HttpServletResponse;
10 import jalview.bin.Cache;
11 import jalview.rest.RestHandler.Status;
13 public abstract class EndpointAsync extends Endpoint
15 private String name = null;
17 private String idExtension = null;
19 private String id = null;
21 private CompletableFuture<Void> cf = null;
23 protected void setCompletableFuture(CompletableFuture<Void> cf)
28 protected CompletableFuture<Void> getCompletableFuture()
33 protected void setId(String idExtension)
35 this.id = getName() + "::" + idExtension;
38 protected String getId()
44 * Override the three methods
45 * initialise (get parameters, set id (extension), set cf if using an existing one)
46 * process (what to do in the cf if not using an existing one)
47 * finalise (extra stuff to do at the end of the first call to this)
49 protected void initialise(HttpServletRequest request,
50 HttpServletResponse response)
52 // should be overridden
53 // must setId(request, extension)
57 protected abstract void process(HttpServletRequest request,
58 HttpServletResponse response);
60 protected void finalise(HttpServletRequest request,
61 HttpServletResponse response)
66 protected void passCompletableFuture()
68 // Override this if you want to use an existing CompletableFuture
72 public void processEndpoint(HttpServletRequest request,
73 HttpServletResponse response)
75 initialise(request, response);
76 final String id = getId();
78 if (checkStatus(request, response))
81 passCompletableFuture();
82 if (getCompletableFuture() == null)
84 setCompletableFuture(CompletableFuture.runAsync(() -> {
85 this.process(request, response);
88 finaliseCompletableFuture();
90 finalise(request, response);
92 returnStatus(response);
93 changeStatus(Status.IN_PROGRESS);
97 * Shared methods below here
100 protected String setId(HttpServletRequest request, String extension)
102 String idString = request.getParameter("id");
103 if (idString == null)
111 protected void changeStatus(Status status)
114 // don't change a job's status if it has finished or died
115 if (API.getStatusMap().get(id) == Status.FINISHED
116 || API.getStatusMap().get(id) == Status.ERROR)
118 API.getStatusMap().put(id, status);
121 protected Status getStatus()
123 return API.getStatusMap().get(getId());
126 protected void returnStatus(HttpServletResponse response)
131 PrintWriter writer = response.getWriter();
133 writer.write("id=" + id + "\n");
134 if (API.getRequestMap().get(id) != null)
136 "request=" + API.getRequestMap().get(id).toString() + "\n");
137 if (API.getStatusMap().get(id) != null)
139 if (API.getStatusMap().get(id) == Status.ERROR)
140 response.setStatus(500);
142 "status=" + API.getStatusMap().get(id).toString() + "\n");
144 } catch (IOException e)
150 protected boolean checkStatus(HttpServletRequest request,
151 HttpServletResponse response)
154 Status status = API.getStatusMap().get(id);
157 API.getStatusMap().put(id, Status.STARTED);
158 API.getRequestMap().put(id, request.getRequestURI());
162 returnStatus(response);
168 protected void finaliseCompletableFuture()
171 cf.whenComplete((Void, e) -> {
174 Cache.error("Endpoint job " + id + " did not complete");
176 changeStatus(Status.ERROR);
180 Cache.info("Endpoint job " + id + " completed successfully");
181 changeStatus(Status.FINISHED);