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 String operation;
48 protected final ArrayList<Operation> operations = new ArrayList<>();
50 protected int typeFlags = 0;
52 protected static final EnumMap<Job.Status, WsJob.JobState> stateMap = new EnumMap<>(
55 stateMap.put(Job.Status.PENDING, WsJob.JobState.QUEUED);
56 stateMap.put(Job.Status.REJECTED, WsJob.JobState.INVALID);
57 stateMap.put(Job.Status.ACCEPTED, WsJob.JobState.QUEUED);
58 stateMap.put(Job.Status.QUEUED, WsJob.JobState.QUEUED);
59 stateMap.put(Job.Status.RUNNING, WsJob.JobState.RUNNING);
60 stateMap.put(Job.Status.COMPLETED, WsJob.JobState.FINISHED);
61 stateMap.put(Job.Status.INTERRUPTED, WsJob.JobState.CANCELLED);
62 stateMap.put(Job.Status.DELETED, WsJob.JobState.CANCELLED);
63 stateMap.put(Job.Status.FAILED, WsJob.JobState.FAILED);
64 stateMap.put(Job.Status.ERROR, WsJob.JobState.SERVERERROR);
65 stateMap.put(Job.Status.UNKNOWN, WsJob.JobState.UNKNOWN);
68 protected final Set<WsJob.JobState> failedStates = new HashSet<>(
69 Arrays.asList(WsJob.JobState.INVALID, WsJob.JobState.BROKEN,
70 WsJob.JobState.FAILED, WsJob.JobState.SERVERERROR,
71 WsJob.JobState.CANCELLED));
73 public SlivkaWebService(SlivkaClient client, SlivkaService service,
77 this.service = service;
78 this.operation = operation;
82 public String getHostName()
84 return client.getUrl().toString();
88 public String getProviderName()
94 public String getName()
96 return service.getName();
100 public String getDescription()
102 return service.getDescription();
106 public String getOperationType()
112 public List<Operation> getOperations()
117 void addOperation(Operation operation)
119 operations.add(operation);
122 void removeOperation(Operation operation)
124 operations.remove(operation);
128 public boolean hasParameters()
130 return getParamStore().getServiceParameters().size() > 0;
134 public ParamDatastoreI getParamStore()
138 store = new SlivkaDatastore(service);
144 public String submit(List<SequenceI> sequences, List<ArgumentI> args)
147 var request = new uk.ac.dundee.compbio.slivkaclient.JobRequest();
148 for (Parameter param : service.getParameters())
150 if (param instanceof Parameter.FileParameter)
152 // if finds a file input, gives it sequences stream
153 Parameter.FileParameter fileParam = (Parameter.FileParameter) param;
155 switch (fileParam.getMediaType())
157 case "application/pfam":
158 format = FileFormat.Pfam;
160 case "application/stockholm":
161 format = FileFormat.Stockholm;
163 case "application/clustal":
164 format = FileFormat.Clustal;
166 case "application/fasta":
168 format = FileFormat.Fasta;
171 InputStream stream = new ByteArrayInputStream(format.getWriter(null)
172 .print(sequences.toArray(new SequenceI[0]), false)
174 request.addFile(param.getId(), stream);
179 for (ArgumentI arg : args)
181 // multiple choice field names are name$number to avoid duplications
182 // the number is stripped here
183 String paramId = arg.getName().split("\\$", 2)[0];
184 Parameter param = service.getParameter(paramId);
185 if (param instanceof Parameter.FlagParameter)
187 if (arg.getValue() != null && !arg.getValue().isBlank())
188 request.addData(paramId, true);
190 request.addData(paramId, false);
194 request.addData(paramId, arg.getValue());
198 var job = service.submitJob(request);
203 public void updateProgress(WSJob job) throws IOException
205 // TODO Auto-generated method stub
210 public void cancel(WSJob job) throws IOException
212 Cache.log.warn("Slivka does not support job cancellation yet.");
216 public boolean handleSubmissionError(WSJob job, Exception ex)
218 if (ex instanceof ClientProtocolException)
220 Cache.log.error("Job submission failed due to exception.", ex);
227 public boolean handleCollectionError(WSJob job, Exception ex)
229 // TODO Auto-generated method stub
233 public AlignmentI getAlignment(WSJob job) throws IOException
235 Collection<RemoteFile> files;
236 var slivkaJob = client.getJob(job.getJobId());
237 files = slivkaJob.getResults();
238 for (RemoteFile f : files)
240 if (f.getMediaType().equals("application/clustal"))
242 return new FormatAdapter().readFile(f.getContentUrl().toString(),
243 DataSourceType.URL, FileFormat.Clustal);
245 else if (f.getMediaType().equals("application/fasta"))
247 return new FormatAdapter().readFile(f.getContentUrl().toString(),
248 DataSourceType.URL, FileFormat.Fasta);
255 public String toString()
257 return String.format("SlivkaWebService[%s]", getName());