1 package jalview.ws.slivkaws;
3 import jalview.bin.Cache;
4 import jalview.ws.ServiceChangeListener;
5 import jalview.ws.WSDiscovererI;
6 import jalview.ws.api.ServiceWithParameters;
7 import java.io.IOException;
8 import java.net.MalformedURLException;
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.List;
14 import java.util.Vector;
15 import java.util.concurrent.CompletableFuture;
16 import java.util.concurrent.CopyOnWriteArraySet;
17 import java.util.concurrent.ExecutorService;
18 import java.util.concurrent.Executors;
19 import java.util.concurrent.Future;
20 import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
21 import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
23 public class SlivkaWSDiscoverer implements WSDiscovererI
25 private static final String SLIVKA_HOST_URLS = "SLIVKAHOSTURLS";
27 private static final String COMPBIO_SLIVKA = "https://www.compbio.dundee.ac.uk/slivka/";
29 private static SlivkaWSDiscoverer instance = null;
31 private List<ServiceWithParameters> services = List.of();
33 private SlivkaWSDiscoverer()
37 public static SlivkaWSDiscoverer getInstance()
41 instance = new SlivkaWSDiscoverer();
46 private Set<ServiceChangeListener> serviceListeners = new CopyOnWriteArraySet<>();
49 public void addServiceChangeListener(ServiceChangeListener l)
51 serviceListeners.add(l);
55 public void removeServiceChangeListener(ServiceChangeListener l)
57 serviceListeners.remove(l);
60 public void notifyServiceListeners(List<ServiceWithParameters> services)
62 for (var listener : serviceListeners)
64 listener.servicesChanged(this, services);
68 private final ExecutorService executor = Executors.newSingleThreadExecutor();
69 private Vector<Future<?>> discoveryTasks = new Vector<>();
71 public CompletableFuture<WSDiscovererI> startDiscoverer()
73 CompletableFuture<WSDiscovererI> task = CompletableFuture
76 return SlivkaWSDiscoverer.this;
78 discoveryTasks.add(task);
82 private List<ServiceWithParameters> reloadServices()
84 Cache.log.info("Reloading Slivka services");
85 notifyServiceListeners(Collections.emptyList());
86 ArrayList<ServiceWithParameters> instances = new ArrayList<>();
88 for (String url : getServiceUrls())
92 client = new SlivkaClient(url);
95 for (SlivkaService service : client.getServices())
97 SlivkaWSInstance newinstance = null;
98 for (String classifier : service.classifiers)
100 if (classifier.contains("Multiple sequence alignment"))
102 newinstance = new SlivkaMsaServiceInstance(client, service);
104 if (classifier.contains("Protein sequence analysis")
105 && newinstance == null)
107 newinstance = new SlivkaAnnotationServiceInstance(client,
111 .contains("Sequence alignment analysis (conservation)"))
113 newinstance = new SlivkaAnnotationServiceInstance(client,
117 if (newinstance != null)
119 instances.add(newinstance);
122 } catch (IOException e)
129 services = instances;
130 notifyServiceListeners(instances);
131 Cache.log.info("Slivka services reloading finished");
136 public List<ServiceWithParameters> getServices()
142 public boolean hasServices()
144 return !isRunning() && services.size() > 0;
148 public boolean isRunning()
150 return !discoveryTasks.stream().allMatch(Future::isDone);
154 public void setServiceUrls(List<String> wsUrls)
156 if (wsUrls != null && !wsUrls.isEmpty())
158 Cache.setProperty(SLIVKA_HOST_URLS, String.join(",", wsUrls));
162 Cache.removeProperty(SLIVKA_HOST_URLS);
167 public List<String> getServiceUrls()
169 String surls = Cache.getDefault(SLIVKA_HOST_URLS, COMPBIO_SLIVKA);
170 String[] urls = surls.split(",");
171 ArrayList<String> valid = new ArrayList<>(urls.length);
172 for (String url : urls)
178 } catch (MalformedURLException e)
180 Cache.log.warn("Problem whilst trying to make a URL from '"
181 + ((url != null) ? url : "<null>") + "'");
183 "This was probably due to a malformed comma separated list"
184 + " in the " + SLIVKA_HOST_URLS
185 + " entry of $(HOME)/.jalview_properties)");
186 Cache.log.debug("Exception was ", e);
193 public boolean testServiceUrl(URL url)
195 return getServerStatusFor(url.toString()) == STATUS_OK;
199 public int getServerStatusFor(String url)
203 List<?> services = new SlivkaClient(url).getServices();
204 return services.isEmpty() ? STATUS_NO_SERVICES : STATUS_OK;
205 } catch (IOException e)
207 Cache.log.error("Slivka could not retrieve services list", e);
208 return STATUS_INVALID;
213 public String getErrorMessages()
215 // TODO Auto-generated method stub