JAL-2071 architectural improvement for Plugable Free Text Search 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 import jalview.fts.service.pdb.PDBFTSRestClient;
30
31 import java.io.BufferedReader;
32 import java.io.FileReader;
33 import java.io.IOException;
34 import java.util.ArrayList;
35 import java.util.Iterator;
36 import java.util.List;
37
38 import javax.ws.rs.core.MediaType;
39
40 import org.json.simple.JSONArray;
41 import org.json.simple.JSONObject;
42 import org.json.simple.parser.JSONParser;
43 import org.json.simple.parser.ParseException;
44 import org.testng.Assert;
45 import org.testng.annotations.AfterMethod;
46 import org.testng.annotations.BeforeMethod;
47 import org.testng.annotations.Test;
48
49 import com.sun.jersey.api.client.Client;
50 import com.sun.jersey.api.client.ClientResponse;
51 import com.sun.jersey.api.client.WebResource;
52 import com.sun.jersey.api.client.config.ClientConfig;
53 import com.sun.jersey.api.client.config.DefaultClientConfig;
54
55 public class PDBFTSRestClientTest
56 {
57
58   @BeforeMethod(alwaysRun = true)
59   public void setUp() throws Exception
60   {
61   }
62
63   @AfterMethod
64   public void tearDown() throws Exception
65   {
66   }
67
68   @Test(groups = { "External", "Network" })
69   public void executeRequestTest()
70   {
71     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
72     try
73     {
74       wantedFields.add(PDBFTSRestClient.getInstance()
75               .getDataColumnByNameOrCode("molecule_type"));
76       wantedFields
77 .add(PDBFTSRestClient.getInstance()
78               .getDataColumnByNameOrCode("pdb_id"));
79       wantedFields.add(PDBFTSRestClient.getInstance()
80               .getDataColumnByNameOrCode("genus"));
81       wantedFields
82 .add(PDBFTSRestClient.getInstance()
83               .getDataColumnByNameOrCode("gene_name"));
84       wantedFields.add(PDBFTSRestClient.getInstance()
85               .getDataColumnByNameOrCode("title"));
86     } catch (Exception e1)
87     {
88       e1.printStackTrace();
89     }
90
91     FTSRestRequest request = new FTSRestRequest();
92     request.setAllowEmptySeq(false);
93     request.setResponseSize(100);
94     request.setFieldToSearchBy("text:");
95     request.setSearchTerm("abc");
96     request.setWantedFields(wantedFields);
97
98     FTSRestResponse response;
99     try
100     {
101       response = PDBFTSRestClient.getInstance().executeRequest(request);
102     } catch (Exception e)
103     {
104       e.printStackTrace();
105       Assert.fail("Couldn't execute webservice call!");
106       return;
107     }
108     assertTrue(response.getNumberOfItemsFound() > 99);
109     assertTrue(response.getSearchSummary() != null);
110     assertTrue(response.getSearchSummary().size() > 99);
111   }
112
113   @Test(groups = { "Functional" })
114   public void getPDBDocFieldsAsCommaDelimitedStringTest()
115   {
116     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
117     try
118     {
119       wantedFields.add(PDBFTSRestClient.getInstance()
120               .getDataColumnByNameOrCode("molecule_type"));
121       wantedFields
122 .add(PDBFTSRestClient.getInstance()
123               .getDataColumnByNameOrCode("pdb_id"));
124       wantedFields.add(PDBFTSRestClient.getInstance()
125               .getDataColumnByNameOrCode("genus"));
126       wantedFields
127 .add(PDBFTSRestClient.getInstance()
128               .getDataColumnByNameOrCode("gene_name"));
129       wantedFields.add(PDBFTSRestClient.getInstance()
130               .getDataColumnByNameOrCode("title"));
131     } catch (Exception e)
132     {
133       e.printStackTrace();
134     }
135
136     String expectedResult = "molecule_type,pdb_id,genus,gene_name,title";
137     String actualResult = PDBFTSRestClient
138             .getDataColumnsFieldsAsCommaDelimitedString(wantedFields);
139
140     assertEquals("", expectedResult, actualResult);
141   }
142
143   @Test(groups = { "External, Network" })
144   public void parsePDBJsonExceptionStringTest()
145   {
146     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
147     try
148     {
149       wantedFields.add(PDBFTSRestClient.getInstance()
150               .getDataColumnByNameOrCode("molecule_type"));
151       wantedFields
152 .add(PDBFTSRestClient.getInstance()
153               .getDataColumnByNameOrCode("pdb_id"));
154       wantedFields.add(PDBFTSRestClient.getInstance()
155               .getDataColumnByNameOrCode("genus"));
156       wantedFields
157 .add(PDBFTSRestClient.getInstance()
158               .getDataColumnByNameOrCode("gene_name"));
159       wantedFields.add(PDBFTSRestClient.getInstance()
160               .getDataColumnByNameOrCode("title"));
161     } catch (Exception e1)
162     {
163       e1.printStackTrace();
164     }
165
166     FTSRestRequest request = new FTSRestRequest();
167     request.setAllowEmptySeq(false);
168     request.setResponseSize(100);
169     request.setFieldToSearchBy("text:");
170     request.setSearchTerm("abc");
171     request.setWantedFields(wantedFields);
172
173     String jsonErrorResponse = "";
174     try
175     {
176       jsonErrorResponse = readJsonStringFromFile("test/jalview/io/pdb_request_json_error.txt");
177     } catch (IOException e)
178     {
179       e.printStackTrace();
180     }
181
182     String parsedErrorResponse = PDBFTSRestClient
183             .parseJsonExceptionString(jsonErrorResponse);
184
185     String expectedErrorMsg = "\n============= PDB Rest Client RunTime error =============\n"
186             + "Status: 400\n"
187             + "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"
188             + "query: text:abc OR text:go:abc AND molecule_sequence:['' TO *]\n"
189             + "fl: pdb_id\n";
190
191     assertEquals(expectedErrorMsg, parsedErrorResponse);
192   }
193
194   @Test(
195     groups = { "External", "Network" },
196     expectedExceptions = Exception.class)
197   public void testForExpectedRuntimeException() throws Exception
198   {
199     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
200     wantedFields.add(PDBFTSRestClient.getInstance()
201             .getDataColumnByNameOrCode("pdb_id"));
202
203     FTSRestRequest request = new FTSRestRequest();
204     request.setFieldToSearchBy("text:");
205     request.setSearchTerm("abc OR text:go:abc");
206     request.setWantedFields(wantedFields);
207     PDBFTSRestClient.getInstance().executeRequest(request);
208   }
209
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 }