1 package jalview.ws2.slivka;
3 import java.io.ByteArrayInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.util.ArrayList;
7 import java.util.Arrays;
8 import java.util.Collection;
9 import java.util.EnumMap;
10 import java.util.HashSet;
11 import java.util.List;
14 import jalview.bin.Cache;
15 import jalview.datamodel.AlignmentI;
16 import jalview.datamodel.SequenceI;
17 import jalview.io.DataSourceType;
18 import jalview.io.FileFormat;
19 import jalview.io.FileFormatI;
20 import jalview.io.FormatAdapter;
21 import jalview.ws.gui.WsJob;
22 import jalview.ws.params.ArgumentI;
23 import jalview.ws.params.ParamDatastoreI;
24 import jalview.ws.params.WsParamSetI;
25 import jalview.ws.slivkaws.SlivkaDatastore;
26 import jalview.ws2.WebServiceI;
27 import jalview.ws2.operations.Operation;
28 import jalview.ws2.ResultSupplier;
29 import jalview.ws2.WSJob;
30 import jalview.ws2.WSJobStatus;
31 import javajs.http.ClientProtocolException;
32 import uk.ac.dundee.compbio.slivkaclient.Job;
33 import uk.ac.dundee.compbio.slivkaclient.Parameter;
34 import uk.ac.dundee.compbio.slivkaclient.RemoteFile;
35 import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
36 import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
38 public class SlivkaWebService implements WebServiceI
40 protected final SlivkaClient client;
42 protected final SlivkaService service;
44 protected SlivkaDatastore store = null;
46 protected final ArrayList<Operation> operations = new ArrayList<>();
48 protected int typeFlags = 0;
50 protected static final EnumMap<Job.Status, WsJob.JobState> stateMap = new EnumMap<>(
53 stateMap.put(Job.Status.PENDING, WsJob.JobState.QUEUED);
54 stateMap.put(Job.Status.REJECTED, WsJob.JobState.INVALID);
55 stateMap.put(Job.Status.ACCEPTED, WsJob.JobState.QUEUED);
56 stateMap.put(Job.Status.QUEUED, WsJob.JobState.QUEUED);
57 stateMap.put(Job.Status.RUNNING, WsJob.JobState.RUNNING);
58 stateMap.put(Job.Status.COMPLETED, WsJob.JobState.FINISHED);
59 stateMap.put(Job.Status.INTERRUPTED, WsJob.JobState.CANCELLED);
60 stateMap.put(Job.Status.DELETED, WsJob.JobState.CANCELLED);
61 stateMap.put(Job.Status.FAILED, WsJob.JobState.FAILED);
62 stateMap.put(Job.Status.ERROR, WsJob.JobState.SERVERERROR);
63 stateMap.put(Job.Status.UNKNOWN, WsJob.JobState.UNKNOWN);
66 protected final Set<WsJob.JobState> failedStates = new HashSet<>(
67 Arrays.asList(WsJob.JobState.INVALID, WsJob.JobState.BROKEN,
68 WsJob.JobState.FAILED, WsJob.JobState.SERVERERROR,
69 WsJob.JobState.CANCELLED));
71 public SlivkaWebService(SlivkaClient client, SlivkaService service)
74 this.service = service;
78 public String getHostName()
80 return client.getUrl().toString();
84 public String getProviderName()
90 public String getName()
92 return service.getName();
96 public String getDescription()
98 return service.getDescription();
102 public List<Operation> getOperations()
107 void addOperation(Operation operation)
109 operations.add(operation);
112 void removeOperation(Operation operation)
114 operations.remove(operation);
118 public boolean hasParameters()
120 return getParamStore().getServiceParameters().size() > 0;
124 public ParamDatastoreI getParamStore()
128 store = new SlivkaDatastore(service);
134 public String submit(List<SequenceI> sequences, List<ArgumentI> args)
137 var request = new uk.ac.dundee.compbio.slivkaclient.JobRequest();
138 for (Parameter param : service.getParameters())
140 if (param instanceof Parameter.FileParameter)
142 // if finds a file input, gives it sequences stream
143 Parameter.FileParameter fileParam = (Parameter.FileParameter) param;
145 switch (fileParam.getMediaType())
147 case "application/pfam":
148 format = FileFormat.Pfam;
150 case "application/stockholm":
151 format = FileFormat.Stockholm;
153 case "application/clustal":
154 format = FileFormat.Clustal;
156 case "application/fasta":
158 format = FileFormat.Fasta;
161 InputStream stream = new ByteArrayInputStream(format.getWriter(null)
162 .print(sequences.toArray(new SequenceI[0]), false)
164 request.addFile(param.getId(), stream);
169 for (ArgumentI arg : args)
171 // multiple choice field names are name$number to avoid duplications
172 // the number is stripped here
173 String paramId = arg.getName().split("\\$", 2)[0];
174 Parameter param = service.getParameter(paramId);
175 if (param instanceof Parameter.FlagParameter)
177 if (arg.getValue() != null && !arg.getValue().isBlank())
178 request.addData(paramId, true);
180 request.addData(paramId, false);
184 request.addData(paramId, arg.getValue());
188 var job = service.submitJob(request);
193 public void updateProgress(WSJob job) throws IOException
195 // TODO Auto-generated method stub
200 public void cancel(WSJob job) throws IOException
202 Cache.log.warn("Slivka does not support job cancellation yet.");
206 public boolean handleSubmissionError(WSJob job, Exception ex)
208 if (ex instanceof ClientProtocolException)
210 Cache.log.error("Job submission failed due to exception.", ex);
217 public boolean handleCollectionError(WSJob job, Exception ex)
219 // TODO Auto-generated method stub
223 public AlignmentI getAlignment(WSJob job) throws IOException
225 Collection<RemoteFile> files;
226 var slivkaJob = client.getJob(job.getJobId());
227 files = slivkaJob.getResults();
228 for (RemoteFile f : files)
230 if (f.getMediaType().equals("application/clustal"))
232 return new FormatAdapter().readFile(f.getContentUrl().toString(),
233 DataSourceType.URL, FileFormat.Clustal);
235 else if (f.getMediaType().equals("application/fasta"))
237 return new FormatAdapter().readFile(f.getContentUrl().toString(),
238 DataSourceType.URL, FileFormat.Fasta);
245 public String toString()
247 return String.format("SlivkaWebService[%s]", getName());