Changeset 32830 for main

Show
Ignore:
Timestamp:
28.02.2019 22:00:57 (9 months ago)
Author:
ak19
Message:

Second and final part of fixing up OAI stuff so that there's no lock on the index db by OAI servlet side when a collection is being rebuilt. The bug was that the OAI servlet side would still keep a filelock on the db (index col db and etc oai-inf db, to be precise) when a collection was deactivated before moving build to index during the activate.pl stage. That's because the OAIMessageRouter does not responde to (de)activate messages sent to the regular library servlet's MessageRouter?. This commit: Getting servercontrol.pm of activate.pl to send a request to (de)activate a collection to the OAIMessageRouter was far more involved: although OAIMessageRouter inherits from MessageRouter?, it did not recognise the (de)activate query params because it specifically only recognises OAI verbs like Identify and the special case of 'reset' sent to the OAIMessageRouter. So added in pathways for activate and deactivate to be recognised and processed. Now servercontrol.pm will send (de)activate requests to both the MessageRouter? and the OAIMessageRouter. And there's further support for if a collection is not an OAICollection (not part of the list of collections maintained by OAIReceptionist). What I don't have working, is that the collection is still enumerated by ListSets? of the OAI servlet whereas attempting to view records and identifiers of the deactivated set fails. This misbehaviour doesn't impact rebuilding with activate.pl since it both deactivates then activates a collection, so a collection is not meant to remain in the deactivated state. The fix may be more complicated than removing the collection from OAIReceptionist's list of sets, since the OAI side deals with supercollections etc when it first loads OAICollections. So any fix has to take that into account.

Location:
main/trunk
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone2/perllib/servercontrol.pm

    r32826 r32830  
    117117sub config { 
    118118    my $self = shift(@_); 
    119     my ($command, $check_message_against_regex, $expected_error_code, $silent) = @_; 
     119    my ($command, $check_message_against_regex, $expected_error_code, $silent, $oai_servlet) = @_; 
    120120 
    121121    my $library_url = $self->get_library_URL(); #$self->{'library_url'}; 
    122  
     122    if($oai_servlet) { # if asked to contact the oaiserver servlet, then 
     123        # replace the library servlet name with oaiserver servlet name 
     124        $library_url =~ s@([^/]*?)$@$oai_servlet@; 
     125    } 
    123126 
    124127    # Gatherer.java's configGS3Server doesn't use the site variable 
     
    279282    } 
    280283    elsif ($gs_mode eq "gs3") { 
     284    $self->print_msg("\t- Main library servlet\n");  
    281285    my $DEACTIVATE_COMMAND = "?a=s&sa=d&st=collection&sn="; 
    282286    my $check_message_against_regex = "collection: $qualified_collection deactivated"; 
    283287    $self->config($DEACTIVATE_COMMAND.$qualified_collection, $check_message_against_regex); 
     288     
     289    # and deactivate the collection on OAIserver url too. 
     290    # NOTE: if it's not an OAI collection, then the message that the collection is "not enabled for OAI" is EXPECTED. Another possible valid outcome. 
     291    $self->print_msg("\t- OAI servlet\n");   
     292    $DEACTIVATE_COMMAND = "?deactivate="; 
     293    $check_message_against_regex = "(collection\: $qualified_collection deactivated|collection\: $qualified_collection is not enabled for OAI.)"; 
     294    $self->config($DEACTIVATE_COMMAND.$qualified_collection, $check_message_against_regex, undef, undef, "oaiserver"); 
    284295    }    
    285296} 
     
    297308    } 
    298309    elsif ($gs_mode eq "gs3") { 
     310    $self->print_msg("\t- Main library servlet\n");  
    299311    my $ACTIVATE_COMMAND = "?a=s&sa=a&st=collection&sn="; 
    300312    my $check_message_against_regex = "collection: $qualified_collection activated"; 
    301313    $self->config($ACTIVATE_COMMAND.$qualified_collection, $check_message_against_regex); 
     314     
     315    # and activate the collection on OAIserver url too. 
     316    # NOTE: if it's not an OAI collection, then the message that the collection is "not enabled for OAI" is EXPECTED. Another possible valid outcome. 
     317    $self->print_msg("\t- OAI servlet\n");   
     318    $ACTIVATE_COMMAND = "?activate="; 
     319    $check_message_against_regex = "(collection\: $qualified_collection activated|collection\: $qualified_collection is not enabled for OAI.)"; 
     320    $self->config($ACTIVATE_COMMAND.$qualified_collection, $check_message_against_regex, undef, undef, "oaiserver"); 
    302321    }    
    303322} 
     
    544563sub config_old { 
    545564    my $self = shift(@_); 
    546     my ($command, $check_message_against_regex, $expected_error_code, $silent) = @_; 
     565    my ($command, $check_message_against_regex, $expected_error_code, $silent, $oai_servlet) = @_; 
    547566 
    548567    my $library_url = $self->get_library_URL(); #$self->{'library_url'}; 
    549  
     568    if($oai_servlet) { # if asked to contact the oaiserver servlet, then 
     569        # replace the library servlet name with oaiserver servlet name 
     570        $library_url =~ s@([^/]*?)$@$oai_servlet@; 
     571    } 
    550572 
    551573    # Gatherer.java's configGS3Server doesn't use the site variable 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/OAIServer.java

    r29311 r32830  
    140140        this.recept = new OAIReceptionist(); 
    141141 
    142         // the receptionist uses a OAIMessageRouter or Communicator to send its requests to. We either create a OAIMessageRouter here for the designated site (if site_name set), or we create a Communicator for a remote site. The is given to teh Receptionist, and the servlet never talks to it again.directly. 
     142        // the receptionist uses a OAIMessageRouter or Communicator to send its requests to. We either create a OAIMessageRouter here for the designated site (if site_name set), or we create a Communicator for a remote site. The is given to the Receptionist, and the servlet never talks to it again directly. 
    143143        if (site_name != null) 
    144144        { 
     
    342342 
    343343        if (query!=null && query.equals("reset")) { 
    344           logger.error("reset was called*******************"); 
     344          logger.info("reset was called*******************"); 
    345345          out.println("<?xml version='1.0' encoding='UTF-8' ?>"); 
    346346          out.println(this.recept.process("<message><request reset='true'/></message>")); 
     
    348348        } 
    349349        String[] pairs = (query == null) ? null : query.split("&");//split into key/value pairs 
     350         
     351        // besides "reset", the only other non-verb (non-OAI) requests allowed would be: (de)activate="collName" 
     352        if(pairs.length == 1) { 
     353            String command = pairs[0]; 
     354            int index = command.indexOf('='); 
     355            if(index != -1) { 
     356                String collName = command.substring(index+1); 
     357                command = command.substring(0, index); 
     358                if(command.equals(GSXML.SYSTEM_TYPE_ACTIVATE)) { 
     359                    logger.info("activating OAI collection " + collName + " was called*******************"); 
     360                    out.println("<?xml version='1.0' encoding='UTF-8' ?>"); 
     361                    out.println(this.recept.process("<message><request " + GSXML.SYSTEM_TYPE_ACTIVATE+"='"+collName+"'/></message>")); 
     362                    return; 
     363                     
     364                } else if(command.equals(GSXML.SYSTEM_TYPE_DEACTIVATE)) { 
     365                    logger.info("deactivating OAI collection " + collName + " was called*******************"); 
     366                    out.println("<?xml version='1.0' encoding='UTF-8' ?>"); 
     367                    out.println(this.recept.process("<message><request " + GSXML.SYSTEM_TYPE_DEACTIVATE+"='"+collName+"'/></message>")); 
     368                    return; 
     369                } 
     370            } 
     371            // any other format for activate/deactivate command in query is wrong, continue processing and fail with "badVerb" message: 
     372        } 
     373         
    350374         
    351375        String verb = getVerb(query); 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/OAIReceptionist.java

    r31915 r32830  
    297297    logger.info("*** configure response = "+XMLConverter.getPrettyString(response)); 
    298298  } 
     299   
     300  protected boolean activateOrDeactivateCollection(String collName, int activationState) { 
     301    // Send a request like: a=s&sa=<a|d>&st=collection&sn=<collName> 
     302    Document doc = XMLConverter.newDOM(); 
     303    Element mr_request_message = doc.createElement(GSXML.MESSAGE_ELEM); 
     304    Element mr_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_SYSTEM, "", null); 
     305    mr_request_message.appendChild(mr_request); 
     306     
     307    Element system = doc.createElement(GSXML.SYSTEM_ELEM); 
     308    mr_request.appendChild(system); 
     309    if(activationState == OAIXML.ACTIVATION) { 
     310        system.setAttribute(GSXML.TYPE_ATT, GSXML.SYSTEM_TYPE_ACTIVATE); 
     311    } else { 
     312        system.setAttribute(GSXML.TYPE_ATT, GSXML.SYSTEM_TYPE_DEACTIVATE); 
     313    } 
     314    system.setAttribute(GSXML.SYSTEM_MODULE_TYPE_ATT, GSXML.COLLECTION_ELEM); 
     315    system.setAttribute(GSXML.SYSTEM_MODULE_NAME_ATT, collName); 
     316 
     317    Element response = (Element) this.mr.process(mr_request_message); 
     318    logger.info("*** (de)activate response = "+XMLConverter.getPrettyString(response)); 
     319     
     320    boolean success = false; 
     321    NodeList elements = response.getElementsByTagName(GSXML.STATUS_ELEM); 
     322    if(elements.getLength() <= 0) { 
     323        logger.error("***** No result status"); 
     324        return false; 
     325    } 
     326     
     327    String result = GSXML.getNodeText((Element)elements.item(0)); 
     328    if(result.contains("could not be")) { // could not be (de)activated 
     329        return false; 
     330    } else { 
     331        return true; 
     332    } 
     333  } 
     334   
    299335  /** process using strings - just calls process using Elements */ 
    300336  public String process(String xml_in) { 
     
    337373    } 
    338374 
     375    // Special cases: certain non-OAI commands/non-verbs are recognised 
    339376    // special case, reset=true for reloading the MR and recept data 
    340377    String reset = request.getAttribute("reset"); 
     
    344381      return OAIXML.createResetResponse(true); 
    345382    } 
    346  
     383     
     384    // special case 2: activate=<collname> or deactivate=<collname> can be passed to oaiserver servlet too 
     385    if (request.hasAttribute(GSXML.SYSTEM_TYPE_ACTIVATE)) {      
     386        String collname = request.getAttribute(GSXML.SYSTEM_TYPE_ACTIVATE); 
     387        // don't bother activating if it's not an OAI collection 
     388        if (!this.set_set.contains(collname)) { 
     389            return OAIXML.createDeActivationOfNonOAICollResponse(OAIXML.ACTIVATION, collname); 
     390        } 
     391        boolean success = activateOrDeactivateCollection(collname, OAIXML.ACTIVATION); 
     392        return OAIXML.createActivationStateResponse(success, OAIXML.ACTIVATION, collname); 
     393    } else if (request.hasAttribute(GSXML.SYSTEM_TYPE_DEACTIVATE)) { 
     394        String collname = request.getAttribute(GSXML.SYSTEM_TYPE_DEACTIVATE); 
     395        // don't bother deactivating if it's not an OAI collection 
     396        if (!this.set_set.contains(collname)) { 
     397            return OAIXML.createDeActivationOfNonOAICollResponse(OAIXML.DEACTIVATION, collname); 
     398        } 
     399        boolean success = activateOrDeactivateCollection(collname, OAIXML.DEACTIVATION); 
     400        return OAIXML.createActivationStateResponse(success, OAIXML.DEACTIVATION, collname); 
     401    } 
    347402     
    348403    //At this stage, the value of 'to' attribute of the request must be the 'verb' 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/OAIXML.java

    r32212 r32830  
    4040  public static final String VERB = "verb"; 
    4141 
     42  // Possible states for non-OAI/non-verb activate/deactivate requests   
     43  public static final int DEACTIVATION = 0; 
     44  public static final int ACTIVATION = 1; 
     45   
    4246  // six valid oai verbs 
    4347  public static final String GET_RECORD = "GetRecord"; 
     
    383387  } 
    384388 
     389  // This is the response message sent when there's a request to activate/deactivate a non-OAI collection 
     390  // A request to activate a non-existent/non-OAI collection is not invalid, it's just that we won't process it. 
     391  // So we still return status code OK (OK status code is needed for servercontrol.pm of activate.pl to recognise 
     392  // that the command had been "successful" when it runs de/activate). 
     393  public static Element createDeActivationOfNonOAICollResponse(int activationState, String collname) { 
     394    Document doc = converter.newDOM(); 
     395    Element response = doc.createElement(GSXML.RESPONSE_ELEM); 
     396    response.setAttribute("status", "OK");  
     397    String message = "collection: " + collname + " is not enabled for OAI."; 
     398    if(activationState == ACTIVATION) { 
     399        message += " Not attempting to activate it."; 
     400      } else { 
     401        message += " Not attempting to deactivate it."; 
     402      } 
     403      GSXML.setNodeText(response, message); 
     404      return response; 
     405  } 
     406   
     407  // The response message sent when a request comes in to activate/deactivate a proper OAI collection. 
     408   public static Element createActivationStateResponse(boolean success, int activationState, String collname) { 
     409    Document doc = converter.newDOM(); 
     410    Element response = doc.createElement(GSXML.RESPONSE_ELEM); 
     411    if (success) { 
     412      response.setAttribute("status", "OK"); 
     413      if(activationState == ACTIVATION) { 
     414        GSXML.setNodeText(response, "collection: " + collname + " activated"); 
     415      } else { 
     416        GSXML.setNodeText(response, "collection: " + collname + " deactivated");   
     417      } 
     418    } else { 
     419      response.setAttribute("status", "FAIL"); 
     420      if(activationState == ACTIVATION) { 
     421        GSXML.setNodeText(response, "Failed to activate collection " + collname); 
     422      } else { 
     423        GSXML.setNodeText(response, "Failed to deactivate collection " + collname); 
     424      } 
     425    } 
     426    return response; 
     427  } 
     428   
    385429  public static Element createResetResponse(boolean success) { 
    386430    Document doc = converter.newDOM();