JAL-1270 move some Network tests to External (require third-party services)
[jalview.git] / test / jalview / fts / service / pdb / PDBFTSRestClientTest.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.fts.service.pdb;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertTrue;
25
26 import jalview.fts.api.FTSDataColumnI;
27 import jalview.fts.core.FTSRestRequest;
28 import jalview.fts.core.FTSRestResponse;
29
30 import java.io.BufferedReader;
31 import java.io.FileReader;
32 import java.io.IOException;
33 import java.util.ArrayList;
34 import java.util.Iterator;
35 import java.util.List;
36
37 import javax.ws.rs.core.MediaType;
38
39 import org.json.simple.JSONArray;
40 import org.json.simple.JSONObject;
41 import org.json.simple.parser.JSONParser;
42 import org.json.simple.parser.ParseException;
43 import org.testng.Assert;
44 import org.testng.annotations.AfterMethod;
45 import org.testng.annotations.BeforeMethod;
46 import org.testng.annotations.Test;
47
48 import com.sun.jersey.api.client.Client;
49 import com.sun.jersey.api.client.ClientResponse;
50 import com.sun.jersey.api.client.WebResource;
51 import com.sun.jersey.api.client.config.ClientConfig;
52 import com.sun.jersey.api.client.config.DefaultClientConfig;
53
54 public class PDBFTSRestClientTest
55 {
56
57   @BeforeMethod(alwaysRun = true)
58   public void setUp() throws Exception
59   {
60   }
61
62   @AfterMethod
63   public void tearDown() throws Exception
64   {
65   }
66
67   @Test(groups = { "External", "Network" })
68   public void executeRequestTest()
69   {
70     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
71     try
72     {
73       wantedFields.add(PDBFTSRestClient.getInstance()
74               .getDataColumnByNameOrCode("molecule_type"));
75       wantedFields
76 .add(PDBFTSRestClient.getInstance()
77               .getDataColumnByNameOrCode("pdb_id"));
78       wantedFields.add(PDBFTSRestClient.getInstance()
79               .getDataColumnByNameOrCode("genus"));
80       wantedFields
81 .add(PDBFTSRestClient.getInstance()
82               .getDataColumnByNameOrCode("gene_name"));
83       wantedFields.add(PDBFTSRestClient.getInstance()
84               .getDataColumnByNameOrCode("title"));
85     } catch (Exception e1)
86     {
87       e1.printStackTrace();
88     }
89
90     FTSRestRequest request = new FTSRestRequest();
91     request.setAllowEmptySeq(false);
92     request.setResponseSize(100);
93     request.setFieldToSearchBy("text:");
94     request.setSearchTerm("abc");
95     request.setWantedFields(wantedFields);
96
97     FTSRestResponse response;
98     try
99     {
100       response = PDBFTSRestClient.getInstance().executeRequest(request);
101     } catch (Exception e)
102     {
103       e.printStackTrace();
104       Assert.fail("Couldn't execute webservice call!");
105       return;
106     }
107     assertTrue(response.getNumberOfItemsFound() > 99);
108     assertTrue(response.getSearchSummary() != null);
109     assertTrue(response.getSearchSummary().size() > 99);
110   }
111
112   @Test(groups = { "Functional" })
113   public void getPDBDocFieldsAsCommaDelimitedStringTest()
114   {
115     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
116     try
117     {
118       wantedFields.add(PDBFTSRestClient.getInstance()
119               .getDataColumnByNameOrCode("molecule_type"));
120       wantedFields
121 .add(PDBFTSRestClient.getInstance()
122               .getDataColumnByNameOrCode("pdb_id"));
123       wantedFields.add(PDBFTSRestClient.getInstance()
124               .getDataColumnByNameOrCode("genus"));
125       wantedFields
126 .add(PDBFTSRestClient.getInstance()
127               .getDataColumnByNameOrCode("gene_name"));
128       wantedFields.add(PDBFTSRestClient.getInstance()
129               .getDataColumnByNameOrCode("title"));
130     } catch (Exception e)
131     {
132       e.printStackTrace();
133     }
134
135     String expectedResult = "molecule_type,pdb_id,genus,gene_name,title";
136     String actualResult = PDBFTSRestClient.getInstance()
137             .getDataColumnsFieldsAsCommaDelimitedString(wantedFields);
138
139     assertEquals("", expectedResult, actualResult);
140   }
141
142   @Test(groups = { "External, Network" })
143   public void parsePDBJsonExceptionStringTest()
144   {
145     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
146     try
147     {
148       wantedFields.add(PDBFTSRestClient.getInstance()
149               .getDataColumnByNameOrCode("molecule_type"));
150       wantedFields
151 .add(PDBFTSRestClient.getInstance()
152               .getDataColumnByNameOrCode("pdb_id"));
153       wantedFields.add(PDBFTSRestClient.getInstance()
154               .getDataColumnByNameOrCode("genus"));
155       wantedFields
156 .add(PDBFTSRestClient.getInstance()
157               .getDataColumnByNameOrCode("gene_name"));
158       wantedFields.add(PDBFTSRestClient.getInstance()
159               .getDataColumnByNameOrCode("title"));
160     } catch (Exception e1)
161     {
162       e1.printStackTrace();
163     }
164
165     FTSRestRequest request = new FTSRestRequest();
166     request.setAllowEmptySeq(false);
167     request.setResponseSize(100);
168     request.setFieldToSearchBy("text:");
169     request.setSearchTerm("abc");
170     request.setWantedFields(wantedFields);
171
172     String jsonErrorResponse = "";
173     try
174     {
175       jsonErrorResponse = readJsonStringFromFile("test/jalview/io/pdb_request_json_error.txt");
176     } catch (IOException e)
177     {
178       e.printStackTrace();
179     }
180
181     String parsedErrorResponse = PDBFTSRestClient
182             .parseJsonExceptionString(jsonErrorResponse);
183
184     String expectedErrorMsg = "\n============= PDB Rest Client RunTime error =============\n"
185             + "Status: 400\n"
186             + "Message: org.apache.solr.search.SyntaxError: Cannot parse 'text:abc OR text:go:abc AND molecule_sequence:['' TO *]': Encountered \" \":\" \": \"\" at line 1, column 19.\n"
187             + "query: text:abc OR text:go:abc AND molecule_sequence:['' TO *]\n"
188             + "fl: pdb_id\n";
189
190     assertEquals(expectedErrorMsg, parsedErrorResponse);
191   }
192
193   @Test(
194     groups = { "External" },
195     expectedExceptions = Exception.class)
196   public void testForExpectedRuntimeException() throws Exception
197   {
198     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
199     wantedFields.add(PDBFTSRestClient.getInstance()
200             .getDataColumnByNameOrCode("pdb_id"));
201
202     FTSRestRequest request = new FTSRestRequest();
203     request.setFieldToSearchBy("text:");
204     request.setSearchTerm("abc OR text:go:abc");
205     request.setWantedFields(wantedFields);
206     PDBFTSRestClient.getInstance().executeRequest(request);
207   }
208
209     // JBP: Is this actually external ?  Looks like it is mocked
210   @Test(groups = { "External" })
211   public void parsePDBJsonResponseTest()
212   {
213     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
214     try
215     {
216       wantedFields.add(PDBFTSRestClient.getInstance()
217               .getDataColumnByNameOrCode("molecule_type"));
218       wantedFields
219 .add(PDBFTSRestClient.getInstance()
220               .getDataColumnByNameOrCode("pdb_id"));
221       wantedFields.add(PDBFTSRestClient.getInstance()
222               .getDataColumnByNameOrCode("genus"));
223       wantedFields
224 .add(PDBFTSRestClient.getInstance()
225               .getDataColumnByNameOrCode("gene_name"));
226       wantedFields.add(PDBFTSRestClient.getInstance()
227               .getDataColumnByNameOrCode("title"));
228     } catch (Exception e1)
229     {
230       e1.printStackTrace();
231     }
232
233     FTSRestRequest request = new FTSRestRequest();
234     request.setAllowEmptySeq(false);
235     request.setWantedFields(wantedFields);
236
237     String jsonString = "";
238     try
239     {
240       jsonString = readJsonStringFromFile("test/jalview/io/pdb_response_json.txt");
241     } catch (IOException e)
242     {
243       e.printStackTrace();
244     }
245     FTSRestResponse response = PDBFTSRestClient.parsePDBJsonResponse(
246             jsonString, request);
247     assertTrue(response.getSearchSummary() != null);
248     assertTrue(response.getNumberOfItemsFound() == 931);
249     assertTrue(response.getSearchSummary().size() == 14);
250   }
251
252   @Test(groups = { "Functional" })
253   public void getPDBIdColumIndexTest()
254   {
255     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
256     try
257     {
258       wantedFields.add(PDBFTSRestClient.getInstance()
259               .getDataColumnByNameOrCode("molecule_type"));
260       wantedFields.add(PDBFTSRestClient.getInstance()
261               .getDataColumnByNameOrCode("genus"));
262       wantedFields
263 .add(PDBFTSRestClient.getInstance()
264               .getDataColumnByNameOrCode("gene_name"));
265       wantedFields.add(PDBFTSRestClient.getInstance()
266               .getDataColumnByNameOrCode("title"));
267       wantedFields
268 .add(PDBFTSRestClient.getInstance()
269               .getDataColumnByNameOrCode("pdb_id"));
270     } catch (Exception e)
271     {
272       e.printStackTrace();
273     }
274     try
275     {
276       assertEquals(5,
277  PDBFTSRestClient.getInstance()
278               .getPrimaryKeyColumIndex(wantedFields, true));
279       assertEquals(4,
280  PDBFTSRestClient.getInstance()
281               .getPrimaryKeyColumIndex(wantedFields, false));
282     } catch (Exception e)
283     {
284       // TODO Auto-generated catch block
285       e.printStackTrace();
286     }
287   }
288
289   @Test(groups = { "External" })
290   public void externalServiceIntegrationTest()
291   {
292     ClientConfig clientConfig = new DefaultClientConfig();
293     Client client = Client.create(clientConfig);
294
295     // Build request parameters for the REST Request
296     WebResource webResource = client
297             .resource(PDBFTSRestClient.PDB_SEARCH_ENDPOINT)
298             .queryParam("wt", "json").queryParam("rows", String.valueOf(1))
299             .queryParam("q", "text:abc AND molecule_sequence:['' TO *]");
300
301     // Execute the REST request
302     ClientResponse clientResponse = webResource.accept(
303             MediaType.APPLICATION_JSON).get(ClientResponse.class);
304
305     // Get the JSON string from the response object
306     String pdbJsonResponseString = clientResponse.getEntity(String.class);
307
308     // Check the response status and report exception if one occurs
309     if (clientResponse.getStatus() != 200)
310     {
311       Assert.fail("Webservice call failed!!!");
312     }
313     else
314     {
315       try
316       {
317         JSONParser jsonParser = new JSONParser();
318         JSONObject jsonObj = (JSONObject) jsonParser
319                 .parse(pdbJsonResponseString);
320         JSONObject pdbResponse = (JSONObject) jsonObj.get("response");
321         String queryTime = ((JSONObject) jsonObj.get("responseHeader"))
322                 .get("QTime").toString();
323         String numFound = pdbResponse.get("numFound").toString();
324         JSONArray docs = (JSONArray) pdbResponse.get("docs");
325         Iterator<JSONObject> docIter = docs.iterator();
326
327         assertTrue("Couldn't Retrieve 'response' object",
328                 pdbResponse != null);
329         assertTrue("Couldn't Retrieve 'QTime' value", queryTime != null);
330         assertTrue("Couldn't Retrieve 'numFound' value", numFound != null);
331         assertTrue("Couldn't Retrieve 'docs' object", docs != null
332                 || !docIter.hasNext());
333
334         JSONObject pdbJsonDoc = docIter.next();
335
336         for (FTSDataColumnI field : PDBFTSRestClient.getInstance()
337                 .getAllFTSDataColumns())
338         {
339           if (field.getName().equalsIgnoreCase("ALL"))
340           {
341             continue;
342           }
343           if (pdbJsonDoc.get(field.getCode()) == null)
344           {
345             // System.out.println(">>>\t" + field.getCode());
346             assertTrue(field.getCode()
347                     + " has been removed from PDB doc Entity",
348                     !pdbJsonResponseString.contains(field.getCode()));
349           }
350         }
351       } catch (ParseException e)
352       {
353         Assert.fail(">>>  Test failed due to exception while parsing pdb response json !!!");
354         e.printStackTrace();
355       }
356     }
357   }
358
359   public String readJsonStringFromFile(String filePath) throws IOException
360   {
361     String fileContent;
362     BufferedReader br = new BufferedReader(new FileReader(filePath));
363     try
364     {
365       StringBuilder sb = new StringBuilder();
366       String line = br.readLine();
367
368       while (line != null)
369       {
370         sb.append(line);
371         sb.append(System.lineSeparator());
372         line = br.readLine();
373       }
374       fileContent = sb.toString();
375     } finally
376     {
377       br.close();
378     }
379     return fileContent;
380   }
381
382 }