package jalview.ws2.slivka;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import jalview.api.AlignViewportI;
import jalview.bin.Cache;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
+import jalview.io.AnnotationFile;
import jalview.io.DataSourceType;
+import jalview.io.FeaturesFile;
import jalview.io.FileFormat;
import jalview.io.FileFormatI;
import jalview.io.FormatAdapter;
public class SlivkaWebService implements WebServiceI
{
protected final SlivkaClient client;
+
protected final SlivkaService service;
+
protected SlivkaDatastore store = null;
- protected final String operation;
+
protected final ArrayList<Operation> operations = new ArrayList<>();
+
protected int typeFlags = 0;
- protected static final EnumMap<Job.Status, WsJob.JobState> stateMap = new EnumMap<>(Job.Status.class);
- {
- stateMap.put(Job.Status.PENDING, WsJob.JobState.QUEUED);
- stateMap.put(Job.Status.REJECTED, WsJob.JobState.INVALID);
- stateMap.put(Job.Status.ACCEPTED, WsJob.JobState.QUEUED);
- stateMap.put(Job.Status.QUEUED, WsJob.JobState.QUEUED);
- stateMap.put(Job.Status.RUNNING, WsJob.JobState.RUNNING);
- stateMap.put(Job.Status.COMPLETED, WsJob.JobState.FINISHED);
- stateMap.put(Job.Status.INTERRUPTED, WsJob.JobState.CANCELLED);
- stateMap.put(Job.Status.DELETED, WsJob.JobState.CANCELLED);
- stateMap.put(Job.Status.FAILED, WsJob.JobState.FAILED);
- stateMap.put(Job.Status.ERROR, WsJob.JobState.SERVERERROR);
- stateMap.put(Job.Status.UNKNOWN, WsJob.JobState.UNKNOWN);
- }
- protected final Set<WsJob.JobState> failedStates = new HashSet<>(Arrays.asList(
- WsJob.JobState.INVALID, WsJob.JobState.BROKEN, WsJob.JobState.FAILED,
- WsJob.JobState.SERVERERROR, WsJob.JobState.CANCELLED
- ));
-
- public SlivkaWebService(SlivkaClient client, SlivkaService service, String operation) {
+ protected static final EnumMap<Job.Status, WSJobStatus> statusMap = new EnumMap<>(
+ Job.Status.class);
+ {
+ statusMap.put(Job.Status.PENDING, WSJobStatus.SUBMITTED);
+ statusMap.put(Job.Status.REJECTED, WSJobStatus.INVALID);
+ statusMap.put(Job.Status.ACCEPTED, WSJobStatus.QUEUED);
+ statusMap.put(Job.Status.QUEUED, WSJobStatus.QUEUED);
+ statusMap.put(Job.Status.RUNNING, WSJobStatus.RUNNING);
+ statusMap.put(Job.Status.COMPLETED, WSJobStatus.FINISHED);
+ statusMap.put(Job.Status.INTERRUPTED, WSJobStatus.CANCELLED);
+ statusMap.put(Job.Status.DELETED, WSJobStatus.CANCELLED);
+ statusMap.put(Job.Status.FAILED, WSJobStatus.FAILED);
+ statusMap.put(Job.Status.ERROR, WSJobStatus.SERVER_ERROR);
+ statusMap.put(Job.Status.UNKNOWN, WSJobStatus.UNKNOWN);
+ }
+
+ public SlivkaWebService(SlivkaClient client, SlivkaService service)
+ {
this.client = client;
this.service = service;
- this.operation = operation;
}
@Override
- public String getHostName() { return client.getUrl().toString(); }
+ public String getHostName()
+ {
+ return client.getUrl().toString();
+ }
@Override
- public String getName() { return service.getName(); }
+ public String getProviderName()
+ {
+ return "slivka";
+ }
@Override
- public String getDescription() { return service.getDescription(); }
+ public String getName()
+ {
+ return service.getName();
+ }
@Override
- public String getOperationType() { return operation; }
+ public String getDescription()
+ {
+ return service.getDescription();
+ }
@Override
- public List<Operation> getOperations() {
+ public List<Operation> getOperations()
+ {
return operations;
}
- void addOperation(Operation operation) {
+ void addOperation(Operation operation)
+ {
operations.add(operation);
}
- void removeOperation(Operation operation) {
+ void removeOperation(Operation operation)
+ {
operations.remove(operation);
}
@Override
- public boolean hasParameters() {
+ public boolean hasParameters()
+ {
return getParamStore().getServiceParameters().size() > 0;
}
@Override
- public ParamDatastoreI getParamStore() {
- if (store == null) {
+ public ParamDatastoreI getParamStore()
+ {
+ if (store == null)
+ {
store = new SlivkaDatastore(service);
}
return store;
}
@Override
- public WSJob submit(List<SequenceI> sequences, List<ArgumentI> args) throws IOException
+ public String submit(List<SequenceI> sequences, List<ArgumentI> args)
+ throws IOException
{
var request = new uk.ac.dundee.compbio.slivkaclient.JobRequest();
- for (Parameter param : service.getParameters()) {
- if (param instanceof Parameter.FileParameter) {
+ for (Parameter param : service.getParameters())
+ {
+ if (param instanceof Parameter.FileParameter)
+ {
// if finds a file input, gives it sequences stream
Parameter.FileParameter fileParam = (Parameter.FileParameter) param;
FileFormat format;
- switch (fileParam.getMediaType()) {
+ switch (fileParam.getMediaType())
+ {
case "application/pfam":
format = FileFormat.Pfam;
break;
format = FileFormat.Fasta;
break;
}
- InputStream stream = new ByteArrayInputStream(
- format.getWriter(null)
+ InputStream stream = new ByteArrayInputStream(format.getWriter(null)
.print(sequences.toArray(new SequenceI[0]), false)
.getBytes());
request.addFile(param.getId(), stream);
}
}
- if (args != null) {
- for (ArgumentI arg : args) {
+ if (args != null)
+ {
+ for (ArgumentI arg : args)
+ {
// multiple choice field names are name$number to avoid duplications
// the number is stripped here
String paramId = arg.getName().split("\\$", 2)[0];
Parameter param = service.getParameter(paramId);
- if (param instanceof Parameter.FlagParameter) {
+ if (param instanceof Parameter.FlagParameter)
+ {
if (arg.getValue() != null && !arg.getValue().isBlank())
request.addData(paramId, true);
else
}
}
var job = service.submitJob(request);
- return new WSJob("slivka", getName(), job.getId(), getHostName());
+ return job.getId();
}
@Override
- public void updateProgress(WSJob job)
- throws IOException
+ public void updateProgress(WSJob job) throws IOException
{
- // TODO Auto-generated method stub
-
+ var slivkaJob = client.getJob(job.getJobId());
+ job.setStatus(statusMap.get(slivkaJob.getStatus()));
+ Collection<RemoteFile> files = slivkaJob.getResults();
+ for (RemoteFile f : files)
+ {
+ if (f.getLabel().equals("log"))
+ {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ f.writeTo(stream);
+ job.setLog(stream.toString("UTF-8"));
+ }
+ else if (f.getLabel().equals("error-log"))
+ {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ f.writeTo(stream);
+ job.setErrorLog(stream.toString("UTF-8"));
+ }
+ }
}
@Override
@Override
public boolean handleSubmissionError(WSJob job, Exception ex)
{
- if (ex instanceof ClientProtocolException) {
+ if (ex instanceof ClientProtocolException)
+ {
Cache.log.error("Job submission failed due to exception.", ex);
return true;
}
return false;
}
- public AlignmentI getAlignment(WSJob job) throws IOException {
+ public AlignmentI getAlignment(WSJob job, List<SequenceI> dataset,
+ AlignViewportI viewport) throws IOException
+ {
Collection<RemoteFile> files;
- var slivkaJob = client.getJob(job.getJobID());
+ var slivkaJob = client.getJob(job.getJobId());
files = slivkaJob.getResults();
- for (RemoteFile f : files) {
- if (f.getMediaType().equals("application/clustal")) {
- return new FormatAdapter().readFile(
- f.getContentUrl().toString(), DataSourceType.URL, FileFormat.Clustal);
+ for (RemoteFile f : files)
+ {
+ if (f.getMediaType().equals("application/clustal"))
+ {
+ return new FormatAdapter().readFile(f.getContentUrl().toString(),
+ DataSourceType.URL, FileFormat.Clustal);
+ }
+ else if (f.getMediaType().equals("application/fasta"))
+ {
+ return new FormatAdapter().readFile(f.getContentUrl().toString(),
+ DataSourceType.URL, FileFormat.Fasta);
+ }
+ }
+ return null;
+ }
+
+ public FeaturesFile getFeaturesFile(WSJob job,
+ List<SequenceI> dataset, AlignViewportI viewport) throws IOException
+ {
+ var slivkaJob = client.getJob(job.getJobId());
+ Collection<RemoteFile> files = slivkaJob.getResults();
+ for (RemoteFile f : files)
+ {
+ if (f.getMediaType().equals("application/jalview-features"))
+ {
+ return new FeaturesFile(f.getContentUrl().toString(), DataSourceType.URL);
}
- else if (f.getMediaType().equals("application/fasta")) {
- return new FormatAdapter().readFile(
- f.getContentUrl().toString(), DataSourceType.URL, FileFormat.Fasta);
+ }
+ return null;
+ }
+
+ public List<AlignmentAnnotation> getAnnotationFile(WSJob job,
+ List<SequenceI> dataset, AlignViewportI viewport) throws IOException
+ {
+ var slivkaJob = client.getJob(job.getJobId());
+ Collection<RemoteFile> files = slivkaJob.getResults();
+ for (RemoteFile f : files)
+ {
+ if (f.getMediaType().equals("application/jalview-annotations"))
+ {
+ Alignment aln = new Alignment(dataset.toArray(new SequenceI[0]));
+ AnnotationFile af = new AnnotationFile();
+ boolean valid = af.readAnnotationFileWithCalcId(aln, service.getId(),
+ f.getContentUrl().toString(), DataSourceType.URL);
+ if (valid)
+ {
+ return Arrays.asList(aln.getAlignmentAnnotation());
+ }
+ else
+ {
+ throw new IOException("Unable to read annotations from file " +
+ f.getContentUrl().toString());
+ }
}
}
return null;
}
@Override
- public String toString() {
+ public String toString()
+ {
return String.format("SlivkaWebService[%s]", getName());
}
}