JAL-3066 Implement clustaloWS using slivka system.
authorMateusz Warowny <mmzwarowny@dundee.ac.uk>
Thu, 5 Sep 2019 16:00:38 +0000 (17:00 +0100)
committerMateusz Warowny <mmzwarowny@dundee.ac.uk>
Thu, 5 Sep 2019 16:00:38 +0000 (17:00 +0100)
j11lib/slivka-java-client.jar [new file with mode: 0644]
j8lib/slivka-java-client.jar [new file with mode: 0644]
src/jalview/gui/AlignFrame.java
src/jalview/ws/api/JalviewWebServiceI.java
src/jalview/ws/gui/MsaWSJob.java
src/jalview/ws/slivkaws/ClustaloWS.java [new file with mode: 0644]
src/jalview/ws/slivkaws/SlivkaWSDiscoverer.java [new file with mode: 0644]

diff --git a/j11lib/slivka-java-client.jar b/j11lib/slivka-java-client.jar
new file mode 100644 (file)
index 0000000..f622e77
Binary files /dev/null and b/j11lib/slivka-java-client.jar differ
diff --git a/j8lib/slivka-java-client.jar b/j8lib/slivka-java-client.jar
new file mode 100644 (file)
index 0000000..f622e77
Binary files /dev/null and b/j8lib/slivka-java-client.jar differ
index 67345cd..5a5df3b 100644 (file)
@@ -109,6 +109,7 @@ import jalview.ws.params.ArgumentI;
 import jalview.ws.params.ParamDatastoreI;
 import jalview.ws.params.WsParamSetI;
 import jalview.ws.seqfetcher.DbSourceProxy;
+import jalview.ws.slivkaws.SlivkaWSDiscoverer;
 
 import java.awt.BorderLayout;
 import java.awt.Component;
@@ -4444,9 +4445,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                 }
                 build_urlServiceMenu(me.webService);
 
+
                 // TODO Mateusz - follow pattern for adding web service
                 // JMenuItems for slivka-based services
 
+                SlivkaWSDiscoverer slivkaDiscoverer = SlivkaWSDiscoverer.getInstance();
+                slivkaDiscoverer.attachWSMenuEntry(webService, me);
+
+
                 build_fetchdbmenu(webService);
                 for (JMenu item : wsmenu)
                 {
index ecc8bab..6dda359 100644 (file)
@@ -8,6 +8,14 @@ public interface JalviewWebServiceI
 
   void updateStatus(WsJob job);
 
+  /**
+   * Retrieve any additional log information for the job and update WsJob's
+   * progress. Results won't be retrieved until progress updates have finished.
+   * 
+   * @param job
+   * @return true if Job's stdout/progress panel was added to
+   * @throws Exception
+   */
   boolean updateJobProgress(WsJob job) throws Exception;
 
   boolean handleSubmitError(Throwable _lex, WsJob j, WebserviceInfo wsInfo)
index 86d299a..b27222f 100644 (file)
@@ -55,6 +55,9 @@ class MsaWSJob extends WsJob
       submitted = true;
       subjobComplete = true;
       returnInput = true;
+    } else
+    {
+      validInput = true;
     }
 
   }
diff --git a/src/jalview/ws/slivkaws/ClustaloWS.java b/src/jalview/ws/slivkaws/ClustaloWS.java
new file mode 100644 (file)
index 0000000..645d6f2
--- /dev/null
@@ -0,0 +1,144 @@
+package jalview.ws.slivkaws;
+
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.gui.WebserviceInfo;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FormatAdapter;
+import jalview.ws.api.JalviewServiceEndpointProviderI;
+import jalview.ws.api.JobId;
+import jalview.ws.api.MultipleSequenceAlignmentI;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.gui.WsJob;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.ParamManager;
+import jalview.ws.params.WsParamSetI;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.EnumMap;
+import java.util.List;
+
+import org.apache.http.entity.ContentType;
+
+import uk.ac.dundee.compbio.slivkaclient.Form;
+import uk.ac.dundee.compbio.slivkaclient.FormValidationException;
+import uk.ac.dundee.compbio.slivkaclient.JobState;
+import uk.ac.dundee.compbio.slivkaclient.RemoteFile;
+import uk.ac.dundee.compbio.slivkaclient.Service;
+import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
+
+public class ClustaloWS extends ServiceWithParameters
+    implements MultipleSequenceAlignmentI, JalviewServiceEndpointProviderI
+{
+  private SlivkaClient client;
+  private Service service;
+
+  private EnumMap<JobState, WsJob.JobState> stateMap = new EnumMap<>(JobState.class);
+  {
+    stateMap.put(JobState.PENDING, WsJob.JobState.QUEUED);
+    stateMap.put(JobState.QUEUED, WsJob.JobState.QUEUED);
+    stateMap.put(JobState.RUNNING, WsJob.JobState.RUNNING);
+    stateMap.put(JobState.COMPLETED, WsJob.JobState.FINISHED);
+    stateMap.put(JobState.FAILED, WsJob.JobState.FAILED);
+    stateMap.put(JobState.ERROR, WsJob.JobState.SERVERERROR);
+    stateMap.put(JobState.UNKNOWN, WsJob.JobState.UNKNOWN);
+  }
+
+
+  ClustaloWS(SlivkaClient client)
+  {
+    super("ClustalO", "Alignment", "ClustalO", "foo", "http://foo.foo");
+
+    this.client = client;
+    try
+    {
+      service = client.getService("clustalo");
+    } catch (IOException e)
+    {
+      throw new RuntimeException(e);
+    }
+  }
+
+  @Override
+  public void updateStatus(WsJob job)
+  {
+    try
+    {
+      job.setState(stateMap.get(client.getJobState(job.getJobId())));
+    } catch (IOException e)
+    {
+      throw new RuntimeException(e);
+    }
+  }
+
+  @Override
+  public boolean updateJobProgress(WsJob job)
+  {
+    return false;
+  }
+
+  @Override
+  public boolean handleSubmitError(Throwable _lex, WsJob j, WebserviceInfo wsInfo)
+  {
+    return false;
+  }
+
+  @Override
+  public boolean handleCollectionException(Exception e, WsJob msjob, WebserviceInfo wsInfo)
+  {
+    return false;
+  }
+
+  @Override
+  public JobId align(List<SequenceI> toalign, WsParamSetI parameters, List<ArgumentI> list) throws FormValidationException, IOException
+  {
+    StringBuilder builder = new StringBuilder();
+    for (SequenceI seq : toalign)
+    {
+      builder.append(">").append(seq.getName()).append("\n");
+      builder.append(seq.getSequence()).append("\n\n");
+    }
+    InputStream stream = new ByteArrayInputStream(builder.toString().getBytes());
+    RemoteFile file = client.uploadFile(stream, "input.fasta", ContentType.create("application/fasta"));
+    Form form = service.getForm();
+    form.insert("input", file);
+    String jobUUID = form.submit();
+    return new JobId("clustalo", "clustalo", jobUUID);
+  }
+
+  @Override
+  public AlignmentI getAlignmentFor(JobId jobId)
+  {
+    List<RemoteFile> files;
+    try
+    {
+      files = client.getJobResults(jobId.getJobId());
+      for (RemoteFile f: files) {
+        if (f.getMimeType().equals("application/clustal"))
+        {
+          return new FormatAdapter().readFile(f.getURL().toString(), DataSourceType.URL, FileFormat.Clustal);
+        }
+      }
+    } catch (IOException e1)
+    {
+      // TODO Auto-generated catch block
+      e1.printStackTrace();
+    }
+    return null;
+  }
+
+  @Override
+  public void initParamStore(ParamManager userParameterStore)
+  {
+
+  }
+
+  @Override
+  public Object getEndpoint()
+  {
+    return this;
+  }
+}
diff --git a/src/jalview/ws/slivkaws/SlivkaWSDiscoverer.java b/src/jalview/ws/slivkaws/SlivkaWSDiscoverer.java
new file mode 100644 (file)
index 0000000..b799c5a
--- /dev/null
@@ -0,0 +1,77 @@
+package jalview.ws.slivkaws;
+
+import jalview.datamodel.AlignmentView;
+import jalview.gui.AlignFrame;
+import jalview.ws.WSMenuEntryProviderI;
+import jalview.ws.jws2.MsaWSClient;
+
+import java.awt.event.ActionEvent;
+import java.net.URISyntaxException;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+
+import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
+
+public class SlivkaWSDiscoverer
+  implements Runnable, WSMenuEntryProviderI
+{
+  private static SlivkaWSDiscoverer instance = null;
+  private SlivkaClient client;
+  private ClustaloWS clustalo;
+
+  private SlivkaWSDiscoverer() {
+    try
+    {
+      client = new SlivkaClient("gjb-www-1.cluster.lifesci.dundee.ac.uk", 3203);
+    } catch (URISyntaxException e)
+    {
+      throw new RuntimeException(e);
+    }
+    clustalo = new ClustaloWS(client);
+  }
+
+  public static SlivkaWSDiscoverer getInstance()
+  {
+    if (instance == null) {
+               instance = new SlivkaWSDiscoverer();
+       }
+    return instance;
+  }
+
+  @Override
+  public void attachWSMenuEntry(JMenu wsmenu, final AlignFrame alignFrame)
+  {
+    JMenu submenu = new JMenu("Slivka");
+    JMenuItem menuItem = new JMenuItem("ClustalO with defaults");
+    menuItem.addActionListener((ActionEvent e) -> {
+
+      AlignmentView msa = alignFrame.gatherSequencesForAlignment();
+
+      if (msa != null)
+      {
+        new MsaWSClient(clustalo, alignFrame.getTitle(), msa, false,
+            true,
+            alignFrame.getViewport().getAlignment().getDataset(),
+            alignFrame);
+      }
+//
+//      List<SequenceI> sequences = alignFrame.getViewport().getAlignment().getSequences();
+//      try
+//      {
+//        clustalo.align(sequences, null, null);
+//      } catch (FormValidationException | IOException exc)
+//      {
+//        throw new RuntimeException(exc);
+//      }
+    });
+    submenu.add(menuItem);
+    wsmenu.add(submenu);
+  }
+
+  @Override
+  public void run()
+  {
+
+  }
+}