1 package jalview.ext.ensembl;
3 import jalview.io.FileParse;
5 import java.io.BufferedReader;
6 import java.io.DataOutputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.InputStreamReader;
10 import java.net.HttpURLConnection;
11 import java.net.MalformedURLException;
13 import java.util.List;
15 import javax.ws.rs.HttpMethod;
18 * Base class for Ensembl REST service clients
22 abstract class EnsemblRestClient extends EnsemblSequenceFetcher
24 protected final static String ENSEMBL_REST = "http://rest.ensembl.org";
26 protected static final String SEQUENCE_ID_URL = ENSEMBL_REST
29 // @see https://github.com/Ensembl/ensembl-rest/wiki/Output-formats
30 private static final String PING_URL = "http://rest.ensembl.org/info/ping.json";
32 private final static long RETEST_INTERVAL = 10000L; // 10 seconds
34 private static boolean ensemblRestAvailable = false;
36 private static long lastCheck = -1;
38 protected volatile boolean inProgress = false;
41 public boolean queryInProgress()
47 public StringBuffer getRawRecords()
53 * Returns the URL for the client http request
57 * @throws MalformedURLException
59 protected abstract URL getUrl(List<String> ids)
60 throws MalformedURLException;
63 * Returns true if client uses GET method, false if it uses POST
67 public abstract boolean useGetRequest();
70 * Return the desired value for the Content-Type request header
73 * @see https://github.com/Ensembl/ensembl-rest/wiki/HTTP-Headers
75 public abstract String getRequestMimeType();
78 * Return the desired value for the Accept request header
81 * @see https://github.com/Ensembl/ensembl-rest/wiki/HTTP-Headers
83 public abstract String getResponseMimeType();
86 * Tries to connect to Ensembl's REST 'ping' endpoint, and returns true if
87 * successful, else false
91 private boolean checkEnsembl()
95 URL ping = new URL(PING_URL);
96 HttpURLConnection conn = (HttpURLConnection) ping.openConnection();
97 int rc = conn.getResponseCode();
99 if (rc >= 200 && rc < 300)
103 } catch (Throwable t)
105 System.err.println("Error connecting to " + PING_URL + ": "
112 * returns a reader to a Fasta response from the Ensembl sequence endpoint
116 * @throws IOException
118 public FileParse getSequenceReader(List<String> ids)
121 URL url = getUrl(ids);
123 HttpURLConnection connection = (HttpURLConnection) url.openConnection();
126 * POST method allows multiple queries in one request; it is supported for
127 * sequence queries, but not for overlap
129 connection.setRequestMethod(useGetRequest() ? HttpMethod.GET
131 connection.setRequestProperty("Content-Type", getRequestMimeType());
132 connection.setRequestProperty("Accept", getResponseMimeType());
134 connection.setUseCaches(false);
135 connection.setDoInput(true);
136 connection.setDoOutput(true);
138 if (!useGetRequest())
140 writePostBody(connection, ids);
143 InputStream response = connection.getInputStream();
144 int responseCode = connection.getResponseCode();
146 if (responseCode != 200)
148 throw new RuntimeException(
149 "Response code was not 200. Detected response was "
153 BufferedReader reader = null;
154 reader = new BufferedReader(new InputStreamReader(response, "UTF-8"));
155 FileParse fp = new FileParse(reader, url.toString(), "HTTP_POST");
160 * Rechecks if Ensembl is responding, unless the last check was successful and
161 * the retest interval has not yet elapsed. Returns true if Ensembl is up,
166 public boolean isEnsemblAvailable()
168 long now = System.currentTimeMillis();
169 boolean retest = now - lastCheck > RETEST_INTERVAL;
170 if (ensemblRestAvailable && !retest)
174 ensemblRestAvailable = checkEnsembl();
176 return ensemblRestAvailable;
180 * Constructs, writes and flushes the POST body of the request, containing the
181 * query ids in JSON format
185 * @throws IOException
187 protected void writePostBody(HttpURLConnection connection,
188 List<String> ids) throws IOException
191 StringBuilder postBody = new StringBuilder(64);
192 postBody.append("{\"ids\":[");
194 for (String id : ids)
198 postBody.append(",");
201 postBody.append("\"");
202 postBody.append(id.trim());
203 postBody.append("\"");
205 postBody.append("]}");
206 byte[] thepostbody = postBody.toString().getBytes();
207 connection.setRequestProperty("Content-Length",
208 Integer.toString(thepostbody.length));
209 DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
210 wr.write(thepostbody);