Changeset 32830 for main/trunk


Ignore:
Timestamp:
2019-02-28T22:00:57+13:00 (5 years 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 edited

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();
Note: See TracChangeset for help on using the changeset viewer.