JAL-3985 split PDB id queries into multiple queries so server doesn’t 414
authorJim Procter <j.procter@dundee.ac.uk>
Thu, 31 Mar 2022 13:06:04 +0000 (14:06 +0100)
committerJim Procter <j.procter@dundee.ac.uk>
Thu, 31 Mar 2022 13:06:04 +0000 (14:06 +0100)
src/jalview/gui/structurechooser/ThreeDBStructureChooserQuerySource.java

index 9e4ee21..175ad77 100644 (file)
@@ -195,7 +195,7 @@ public class ThreeDBStructureChooserQuerySource
       lastTdbRequest = tdbRequest;
       if (resultList != null)
       { // Query the PDB and add additional metadata
-        FTSRestResponse pdbResponse = fetchStructuresMetaDataFor(
+        List<FTSRestResponse> pdbResponse = fetchStructuresMetaDataFor(
                 getPDBQuerySource(), resultList);
 
         resultList = joinResponses(resultList, pdbResponse);
@@ -266,7 +266,7 @@ public class ThreeDBStructureChooserQuerySource
       {
         // tdb returns custom object
         TDB_FTSData row = (TDB_FTSData) _row;
-        String provider = (String) row.getProvider();
+        String provider = row.getProvider();
         FilterOption providerOpt = new FilterOption(
                 "3DB Provider - " + provider,
                 FILTER_SOURCE_PREFIX + provider, VIEWS_FILTER, false, this);
@@ -472,8 +472,9 @@ public class ThreeDBStructureChooserQuerySource
    * @return
    */
 
-  public String buildPDBFTSQueryFor(FTSRestResponse upResponse)
+  public List<String> buildPDBFTSQueryFor(FTSRestResponse upResponse)
   {
+    List<String> ftsQueries = new ArrayList<String>();
     Set<String> pdbIds = new HashSet<String>();
     int idx_modelId = getLastFTSRequest().getFieldIndex("Model id");
     int idx_provider = getLastFTSRequest().getFieldIndex("Provider");
@@ -486,7 +487,25 @@ public class ThreeDBStructureChooserQuerySource
         pdbIds.add(id);
       }
     }
-    return String.join(" OR ", pdbIds).toString();
+    StringBuilder sb = new StringBuilder();
+    for (String pdbId : pdbIds)
+    {
+      if (sb.length() > 2500)
+      {
+        ftsQueries.add(sb.toString());
+        sb.setLength(0);
+      }
+      if (sb.length() > 0)
+      {
+        sb.append(" OR ");
+      }
+      sb.append(pdbId);
+    }
+    if (sb.length() > 0)
+    {
+      ftsQueries.add(sb.toString());
+    }
+    return ftsQueries;
   }
 
   /**
@@ -496,34 +515,48 @@ public class ThreeDBStructureChooserQuerySource
    * @param upResponse
    * @return FTSRestResponse via PDBStructureChooserQuerySource
    */
-  public FTSRestResponse fetchStructuresMetaDataFor(
+  public List<FTSRestResponse> fetchStructuresMetaDataFor(
           PDBStructureChooserQuerySource pdbquery,
           FTSRestResponse upResponse) throws Exception
   {
-
-    String pdb_Query = buildPDBFTSQueryFor(upResponse);
-    if (pdb_Query.length() == 0)
+    List<String> pdb_Queries = buildPDBFTSQueryFor(upResponse);
+    if (pdb_Queries.size() == 0)
     {
       return null;
     }
-    FTSRestResponse resultList;
-    FTSRestRequest pdbRequest = new FTSRestRequest();
-    pdbRequest.setAllowEmptySeq(false);
-    pdbRequest.setResponseSize(500);
-    pdbRequest.setFieldToSearchBy("(");
-    // pdbRequest.setFieldToSortBy("pdb_id");
-    pdbRequest.setWantedFields(
-            pdbquery.getDocFieldPrefs().getStructureSummaryFields());
-    pdbRequest.setSearchTerm(pdb_Query + ")");
+    List<FTSRestResponse> results = new ArrayList<FTSRestResponse>();
+
+    for (String pdb_Query : pdb_Queries)
+    {
+      FTSRestResponse resultList;
+      FTSRestRequest pdbRequest = new FTSRestRequest();
+      pdbRequest.setAllowEmptySeq(false);
+      pdbRequest.setResponseSize(500);
+      pdbRequest.setFieldToSearchBy("(");
+      // pdbRequest.setFieldToSortBy("pdb_id");
+      pdbRequest.setWantedFields(
+              pdbquery.getDocFieldPrefs().getStructureSummaryFields());
+      pdbRequest.setSearchTerm(pdb_Query + ")");
+
+      // handle exceptions like server errors here - means the threedbeacons
+      // discovery isn't broken by issues to do with the PDBe SOLR api
+      try
+      {
+        resultList = pdbquery.executePDBFTSRestRequest(pdbRequest);
+        results.add(resultList);
+        lastPdbRequest = pdbRequest;
+      } catch (Exception ex)
+      {
+        Console.error("PDBFTSQuery failed", ex);
+      }
 
-    resultList = pdbquery.executePDBFTSRestRequest(pdbRequest);
+    }
 
-    lastPdbRequest = pdbRequest;
-    return resultList;
+    return results;
   }
 
   public FTSRestResponse joinResponses(FTSRestResponse upResponse,
-          FTSRestResponse pdbResponse)
+          List<FTSRestResponse> pdbResponses)
   {
     boolean hasPdbResp = lastPdbRequest != null;
 
@@ -548,13 +581,16 @@ public class ThreeDBStructureChooserQuerySource
         }
         else
         {
-          for (final FTSData pdbrow : pdbResponse.getSearchSummary())
+          for (final FTSRestResponse pdbResponse : pdbResponses)
           {
-            String pdbid = (String) pdbrow.getSummaryData()[pdbIdx];
-            if (id.equalsIgnoreCase(pdbid))
+            for (final FTSData pdbrow : pdbResponse.getSearchSummary())
             {
-              row.getSummaryData()[tdbTitle_idx] = pdbrow
-                      .getSummaryData()[pdbTitle_idx];
+              String pdbid = (String) pdbrow.getSummaryData()[pdbIdx];
+              if (id.equalsIgnoreCase(pdbid))
+              {
+                row.getSummaryData()[tdbTitle_idx] = pdbrow
+                        .getSummaryData()[pdbTitle_idx];
+              }
             }
           }
         }