--- /dev/null
+package jalview.ws2.api;
+
+import java.util.Objects;
+
+public final class Credentials
+{
+ String username = null;
+ String email = null;
+ String password = null;
+
+ private Credentials() {
+ }
+
+ public static final Credentials usingEmail(String email) {
+ Objects.requireNonNull(email);
+ if (email.isEmpty())
+ throw new IllegalArgumentException("empty email");
+ Credentials credentials = new Credentials();
+ credentials.email = email;
+ return credentials;
+ }
+
+ public static final Credentials usingEmail(String email, String password) {
+ Objects.requireNonNull(email);
+ Objects.requireNonNull(password);
+ if (email.isEmpty())
+ throw new IllegalArgumentException("empty email");
+ Credentials credentials = new Credentials();
+ credentials.email = email;
+ credentials.password = password;
+ return credentials;
+ }
+
+ public static final Credentials usingUsername(String username, String password) {
+ Objects.requireNonNull(username);
+ Objects.requireNonNull(password);
+ if (username.isEmpty())
+ throw new IllegalArgumentException("empty username");
+ Credentials credentials = new Credentials();
+ credentials.username = username;
+ credentials.password = password;
+ return credentials;
+ }
+}
--- /dev/null
+package jalview.ws2.client.api;
+
+import java.io.IOException;
+import java.util.List;
+
+import jalview.datamodel.SequenceI;
+import jalview.ws.params.ArgumentI;
+import jalview.ws2.api.Credentials;
+
+public interface WebServiceClientI
+{
+ /**
+ * Get the hostname/url of the remote server which is supplying the service.
+ *
+ * @return host name
+ */
+ String getUrl();
+
+ /**
+ * Get the name of the web service client.
+ *
+ * @return client name
+ */
+ String getClientName();
+
+ /**
+ * Submit new job to the service with the supplied input sequences and
+ * arguments. Optionally, some services may require additional credentials to
+ * run. Implementations should perform all data serialization necessary for
+ * the job submission, start a new job on the remote server and return a
+ * handler for that job.
+ *
+ * @param sequences
+ * input sequences
+ * @param args
+ * user provided arguments
+ * @param credentials
+ * optional user credentials needed to run the job
+ * @return job handler
+ * @throws IOException
+ * submission failed due to a connection error
+ */
+ WebServiceJob submit(List<SequenceI> sequences, List<ArgumentI> args,
+ Credentials credentials) throws IOException;
+
+ /**
+ * Poll the server and update the progress of the running job accordingly.
+ * Implementations should fetch the current job status from the server and
+ * update the status and log strings on the provided job object.
+ *
+ * @param job
+ * job to update
+ * @throws IOException
+ * server error occurred
+ */
+ void updateProgress(WebServiceJob job) throws IOException;
+
+ /**
+ * Send the cancellation request to the server for the specified job.
+ *
+ * @param job
+ * job to cancel
+ * @throws IOException
+ * server error occurred
+ * @throws UnsupportedOperationException
+ * server does not support job cancellation
+ */
+ void cancel(WebServiceJob job) throws IOException, UnsupportedOperationException;
+}
--- /dev/null
+package jalview.ws2.client.api;
+
+import java.net.URL;
+import java.util.EventListener;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import jalview.ws2.api.WebService;
+
+/**
+ * The discoverer and supplier of web services. The discoverer is responsible
+ * for building and storing {@link jalview.ws2.api.WebService} objects
+ * according to the data retrieved from the servers avaiable at specified urls.
+ * @author mmwarowny
+ *
+ */
+public interface WebServiceDiscovererI
+{
+ public static final int STATUS_OK = 1;
+
+ public static final int STATUS_NO_SERVICES = 0;
+
+ public static final int STATUS_INVALID = -1;
+
+ public static final int STATUS_UNKNOWN = -2;
+
+ /**
+ * List the urls used by this discoverer.
+ */
+ List<URL> getUrls();
+
+ /**
+ * Set the list of urls where the discoverer will search for services.
+ */
+ void setUrls(List<URL> wsUrls);
+
+ /**
+ * Test if the url is a valid url for that discoverer.
+ */
+ default boolean testUrl(URL url)
+ {
+ return getStatusForUrl(url) == STATUS_OK;
+ }
+
+ /**
+ * Get the availability status of the services at the url. Return one of the
+ * status codes {@code STATUS_OK}, {@code STATUS_NO_SERVICES},
+ * {@code STATUS_INVALID} or {@code STATUS_UNKNOWN}.
+ *
+ * @return services availability status
+ */
+ int getStatusForUrl(URL url);
+
+ /**
+ * Get the list of services found on the servers.
+ *
+ * @return services
+ */
+ List<WebService> getServices();
+
+ /**
+ * @return {@value true} if there are services available
+ */
+ boolean hasServices();
+
+ /**
+ * Check if service discovery is still in progress. List of services may be
+ * incomplete when the discoverer is running.
+ *
+ * @return whether the discoverer is running
+ */
+ boolean isRunning();
+
+ /**
+ * Check if the discoverer is done searching for services. List of services
+ * should be complete if this methods returns true.
+ *
+ * @return whether the discoverer finished
+ */
+ boolean isDone();
+
+ /**
+ * Start the service discovery and return a future which will be set to the
+ * discovery result when the process is completed. This method should be
+ * called once on startup and then every time the urls list is updated.
+ *
+ * @return services list future result
+ */
+ CompletableFuture<List<WebService>> startDiscoverer();
+
+ /**
+ * An interface for the services list observers.
+ *
+ * @author mmwarowny
+ */
+ @FunctionalInterface
+ interface ServicesChangeListener extends EventListener
+ {
+ /**
+ * Called whenever the services list of the observed discoverer changes with
+ * that discoverer as the first argument and current services list as the
+ * second. The list can be empty if there are no services or the list was
+ * cleared at the beginning of the discovery.
+ *
+ * @param discoverer
+ * @param list
+ */
+ public void servicesChanged(WebServiceDiscovererI discoverer,
+ List<WebService> services);
+ }
+
+ /**
+ * Add a services list observer that will be notified of any changes to the
+ * services list.
+ *
+ * @param listener
+ * services list change listener
+ */
+ public void addServicesChangeListener(ServicesChangeListener listener);
+
+ /**
+ * Remove a listener from the listeners list.
+ *
+ * @param listener
+ * listener to be removed
+ */
+ public void removeServicesChangeListener(ServicesChangeListener listener);
+}