/// <summary> /// Submit the search request with the user supplied configuration parameters /// and sequence. Implementation should make use of the Bio.IO formatters /// to convert the sequence into the web interface compliant sequence format. /// This method performs parameter validation and throw Exception on invalid input. /// </summary> /// <remarks>An exception is thrown if the request does not succeed.</remarks> /// <param name="sequence">The sequence to search with</param> /// <param name="parameters">Blast input parameters</param> /// <returns>Request Identifier</returns> public string SubmitRequest(ISequence sequence, BlastParameters parameters) { if (null == sequence) { throw new ArgumentNullException("sequence"); } if (null == parameters) { throw new ArgumentNullException("parameters"); } string requestIdentifier; // Create blast client object if not created already or if connection string has changed. if (blastClient == null || blastClient.Endpoint.Address.Uri != configuration.Connection) { InitializeBlastClient(); } // Validate the Parameter ParameterValidationResult valid = ValidateParameters(parameters); if (!valid.IsValid) { throw new Exception(valid.ValidationErrors); } // Submit the job to server BlastSerivceRequest blastRequest = GetRequestParameter( sequence, parameters); try { requestIdentifier = blastClient.SubmitJob(blastRequest).ToString(); } catch (FaultException <BlastFault> fault) { throw new Exception(fault.Message); } // Only if the event is registered, invoke the thread if (null != RequestCompleted) { BlastThreadParameter threadParameter = new BlastThreadParameter( requestIdentifier, sequence, parameters); // Start the BackGroundThread to check the status of job workerThread = new BackgroundWorker(); workerThread.WorkerSupportsCancellation = true; workerThread.DoWork += new DoWorkEventHandler(ProcessRequestThread); workerThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompletedRequestThread); workerThread.RunWorkerAsync(threadParameter); } return(requestIdentifier); }
/// <summary> /// Process the request. This method takes care of executing the rest of the steps /// to complete the blast search request in a background thread. Which involves /// 1. Submit the job to server /// 2. Ping the service with the request identifier to get the status of request. /// 3. Repeat step 1, at "RetryInterval" for "RetryCount" till a "success"/"failure" /// status. /// 4. If the status is a "failure" raise an completed event to notify the user /// with appropriate details. /// 5. If the status "success". Get the output of search from server in xml format. /// 6. Parse the xml and the framework object model. /// 7. Raise the completed event and notify user with the output. /// </summary> /// <param name="sender">Client request NCBI Blast search</param> /// <param name="argument">Thread event argument</param> private void ProcessRequestThread(object sender, DoWorkEventArgs argument) { BlastThreadParameter threadParameter = (BlastThreadParameter)argument.Argument; string requestIdentifier = threadParameter.RequestIdentifier; try { ServiceRequestInformation requestInfo = new ServiceRequestInformation(); requestInfo.Status = ServiceRequestStatus.Queued; int retryCount = 0; do { requestInfo = GetRequestStatus(requestIdentifier); if (requestInfo.Status == ServiceRequestStatus.Ready || requestInfo.Status == ServiceRequestStatus.Error || workerThread.CancellationPending) { break; } retryCount++; Thread.Sleep(RetryInterval * retryCount); }while (retryCount < RetryCount); if (workerThread.CancellationPending) { argument.Cancel = true; } else { BlastRequestCompletedEventArgs eventArgument = null; string message; if (requestInfo.Status == ServiceRequestStatus.Ready) { string output = GetResult( requestIdentifier, threadParameter.Parameters); IList <BlastResult> result = Parser.Parse(new StringReader(output)); eventArgument = new BlastRequestCompletedEventArgs( requestIdentifier, true, result, null, string.Empty, workerThread.CancellationPending); argument.Result = eventArgument; } else if (requestInfo.Status == ServiceRequestStatus.Error) { message = String.Format(CultureInfo.InvariantCulture, Resources.BLASTREQUESTFAILED, requestIdentifier, requestInfo.Status, requestInfo.StatusInformation); eventArgument = new BlastRequestCompletedEventArgs( requestIdentifier, false, null, new Exception(message), message, workerThread.CancellationPending); argument.Result = eventArgument; } else { message = String.Format(CultureInfo.InvariantCulture, Resources.BLASTRETRIESEXCEEDED, requestIdentifier, requestInfo.Status, requestInfo.StatusInformation); eventArgument = new BlastRequestCompletedEventArgs( requestIdentifier, false, null, new TimeoutException(message), message, workerThread.CancellationPending); argument.Result = eventArgument; } } } catch (Exception ex) { BlastRequestCompletedEventArgs eventArgument = new BlastRequestCompletedEventArgs( string.Empty, false, null, ex, ex.Message, workerThread.CancellationPending); argument.Result = eventArgument; } }
/// <summary> /// Submit the search request with the user supplied configuration parameters and sequence /// Implementation should make use of the Bio.IO formatters to convert the sequence into /// the web interface compliant sequence format /// </summary> /// <remarks>An exception is thrown if the request does not succeed.</remarks> /// <param name="sequences">List of sequence to search with</param> /// <param name="parameters">Blast input parameters</param> /// <returns>Request Identifier</returns> public string SubmitRequest(IList <ISequence> sequences, BlastParameters parameters) { if (null == parameters) { throw new ArgumentNullException("parameters"); } if (null != sequences) { StringBuilder sb = new StringBuilder(); foreach (ISequence seq in sequences) { sb.Append(FastAFormatter.FormatString(seq)); sb.Append("\n"); } parameters.Add("Query", sb.ToString()); } if (!string.IsNullOrEmpty(Configuration.EmailAddress)) { if (!parameters.Settings.ContainsKey(PARAMETEREMAIL)) { parameters.Add(PARAMETEREMAIL, Configuration.EmailAddress); } } string requestIdentifier = string.Empty; // Validate the Parameter ParameterValidationResult valid = ValidateParameters(parameters); if (!valid.IsValid) { throw new Exception(valid.ValidationErrors); } parameters.Add(PARAMETERCOMMAND, COMMANDPUT); WebAccessor accessor = new WebAccessor(); WebAccessorResponse webAccessorResponse; if (Configuration.UseBrowserProxy) { accessor.GetBrowserProxy(); } webAccessorResponse = accessor.SubmitHttpRequest( ServiceUri, true, // do POST parameters.Settings); // request parameters if (!webAccessorResponse.IsSuccessful) { // failed accessor.Close(); throw new Exception(String.Format(CultureInfo.InvariantCulture, Resources.HTTPSUBMITFAILED, webAccessorResponse.StatusDescription)); } string info = ExtractInfoSection(webAccessorResponse.ResponseString); if (!String.IsNullOrEmpty(info)) { int ridStart = info.IndexOf("RID = ", StringComparison.OrdinalIgnoreCase); if (ridStart >= 0) { ridStart += "RID = ".Length; int ridEnd = info.IndexOf('\n', ridStart); if (ridEnd >= 0) { requestIdentifier = info.Substring(ridStart, ridEnd - ridStart); } } } accessor.Close(); if (string.IsNullOrEmpty(requestIdentifier)) { string message = String.Format(CultureInfo.InvariantCulture, Resources.RIDEXTRACTFAILED, ExtractError(webAccessorResponse.ResponseString)); throw new Exception(message); } // Only if the event is registered, invoke the thread if (null != RequestCompleted) { BlastThreadParameter threadParameter = new BlastThreadParameter( requestIdentifier, null, // Sequence parameter is not used any where, hence passing null. parameters); // Start the BackGroundThread to check the status of job workerThread = new BackgroundWorker(); workerThread.WorkerSupportsCancellation = true; workerThread.DoWork += new DoWorkEventHandler(ProcessRequestThread); workerThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompletedRequestThread); workerThread.RunWorkerAsync(threadParameter); } return(requestIdentifier); }
/// <summary> /// Submit the search request with the user supplied configuration parameters and sequence list. /// Implementation should make use of the Bio.IO formatters to convert the sequence into /// the web interface compliant sequence format /// </summary> /// <remarks>An exception is thrown if the request does not succeed.</remarks> /// <param name="sequences">List of sequence to search with</param> /// <param name="parameters">Blast input parameters</param> /// <returns>Unique Search ID generated by Bio</returns> public string SubmitRequest(IList <ISequence> sequences, BlastParameters parameters) { if (sequences == null) { throw new Exception(Resources.BIOHPCNOSEQUENCE); } if (parameters == null) { throw new ArgumentNullException("parameters"); } string requestIdentifier; // Start of BioHPC-specific code // we are submitting BLAST and give the job a name tAppId appID = tAppId.P_BLAST; string jobname = BlastParameters.Parameters["JobName"].DefaultValue; if (parameters.Settings.ContainsKey(PARAMETERJOBNAME)) { if (!String.IsNullOrEmpty(parameters.Settings[PARAMETERJOBNAME])) { jobname = parameters.Settings[PARAMETERJOBNAME]; } } if (parameters.Settings.ContainsKey(PARAMETEREMAIL)) { if (string.IsNullOrEmpty(Configuration.EmailAddress)) { Configuration.EmailAddress = parameters.Settings[PARAMETEREMAIL]; } } // initialize input parameters with defaults AppInputData pars = blastClient.InitializeApplicationParams(appID, jobname); // Retrieve database names for easy access by parameter validator dnaDatabases = GetServiceMetadata(MetadataDatabasesDna); protDatabases = GetServiceMetadata(MetadataDatabasesProt); // Validate the parameter ParameterValidationResult valid = ValidateParameters(parameters, pars); if (!valid.IsValid) { throw new Exception(valid.ValidationErrors); } // ValidateParameters updated some of the entries in pars and put them // into its ParametersObject - we need to fetch the updated pars pars = valid.ParametersObject as AppInputData; // Set some remaining parameters... pars.blast.querysource = QuerySrcType.paste; // We request XML as format, since this is what we can parse... pars.blast.options.format = OutputFormat.XML; // Query sequence should be in full Fasta format. // We concatenate all the sequences from the list into a single string. pars.blast.query = String.Empty; foreach (ISequence auxseq in sequences) { pars.blast.query += FastAFormatter.FormatString(auxseq) + "\n"; } pars.blast.query = pars.blast.query.Substring(0, pars.blast.query.Length - 1); // remobe trailing newline... // Run parameters and query string are ready. Submit the job to server: // Create a new BLAST job. string jobid = String.Empty; string cntrl = String.Empty; try { string[] outtab = blastClient.CreateJob(appID, jobname, "1", Configuration.EmailAddress, Configuration.Password, "Auto"); if (outtab[0].IndexOf(MsgError, StringComparison.Ordinal) != -1) { throw new Exception(String.Format(CultureInfo.InvariantCulture, Resources.BIOHPCJOBNOTCREATED, outtab[0])); } jobid = outtab[1]; cntrl = outtab[2]; requestIdentifier = jobid + "_" + cntrl; } catch { throw new Exception(Resources.BIOHPCSERVERABSENT); } // Finally, we can submit the job try { string result = blastClient.SubmitJob(jobid, cntrl, pars); if (result.IndexOf(MsgError, StringComparison.Ordinal) != -1) { throw new Exception(String.Format(CultureInfo.InvariantCulture, Resources.BIOHPCJOBNOTSUBMITTED, jobid, result)); } } catch { throw new Exception(Resources.BIOHPCSERVERABSENT); } // end of BioHPC-specific code // Only if the event is registered, invoke the thread if (null != RequestCompleted) { // ThreadParameter wants a single sequence - nor sure what this is for. // We'll give it the first sequence from the list, i.e., sequence[0] BlastThreadParameter threadParameter = new BlastThreadParameter( requestIdentifier, sequences[0], parameters); // Start the BackGroundThread to check the status of job workerThread = new BackgroundWorker(); workerThread.WorkerSupportsCancellation = true; workerThread.DoWork += new DoWorkEventHandler(ProcessRequestThread); workerThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompletedRequestThread); workerThread.RunWorkerAsync(threadParameter); } return(requestIdentifier); }
/// <summary> /// Submit the search request with the user supplied configuration parameters and sequence /// Implementation should make use of the Bio.IO formatters to convert the sequence into /// the web interface compliant sequence format /// </summary> /// <remarks>An exception is thrown if the request does not succeed.</remarks> /// <param name="sequences">List of sequence to search with</param> /// <param name="parameters">Blast input parameters</param> /// <returns>Request Identifier</returns> public string SubmitRequest(IList <ISequence> sequences, BlastParameters parameters) { string emailAddress = string.Empty; if (null == sequences) { throw new ArgumentNullException("sequences"); } if (null == parameters) { throw new ArgumentNullException("parameters"); } string tempEmail; if (parameters.Settings.TryGetValue(ParameterEmail, out tempEmail) && !string.IsNullOrEmpty(tempEmail)) { emailAddress = tempEmail; } string requestIdentifier = string.Empty; // Validate the Parameter ParameterValidationResult valid = ValidateParameters(parameters); if (!valid.IsValid) { throw new Exception(valid.ValidationErrors); } // Submit the job to server InputParameters blastRequest = GetRequestParameter(parameters); StringBuilder seqBuilder = new StringBuilder(); foreach (ISequence sequence in sequences) { byte[] buffer = new byte[80]; int bufferIndex = 0, maxLineSize = 80; seqBuilder.AppendLine(">" + sequence.ID); for (long index = 0; index < sequence.Count; index += maxLineSize) { for (bufferIndex = 0; bufferIndex < maxLineSize && index + bufferIndex < sequence.Count; bufferIndex++) { buffer[bufferIndex] = sequence[index + bufferIndex]; } string line = ASCIIEncoding.ASCII.GetString(buffer, 0, bufferIndex); seqBuilder.AppendLine(line); } } blastRequest.sequence = seqBuilder.ToString(); requestIdentifier = blastClient.run(emailAddress, string.Empty, blastRequest); // Only if the event is registered, invoke the thread if (null != RequestCompleted) { BlastThreadParameter threadParameter = new BlastThreadParameter( requestIdentifier, null, parameters); // Start the BackGroundThread to check the status of job workerThread = new BackgroundWorker(); workerThread.WorkerSupportsCancellation = true; workerThread.DoWork += new DoWorkEventHandler(ProcessRequestThread); workerThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompletedRequestThread); workerThread.RunWorkerAsync(threadParameter); } return(requestIdentifier); }
/// <summary> /// Submit the search request with the user supplied configuration parameters /// and sequence. Implementation should make use of the Bio.IO formatters /// to convert the sequence into the web interface compliant sequence format. /// This method performs parameter validation and throw Exception on invalid input. /// </summary> /// <remarks>An exception is thrown if the request does not succeed.</remarks> /// <param name="sequence">The sequence to search with</param> /// <param name="parameters">Blast input parameters</param> /// <returns>Request Identifier</returns> public string SubmitRequest(ISequence sequence, BlastParameters parameters) { if (null == sequence) { throw new ArgumentNullException("sequence"); } if (null == parameters) { throw new ArgumentNullException("parameters"); } if (!string.IsNullOrEmpty(Configuration.EmailAddress)) { if (!parameters.Settings.ContainsKey(ParameterEmail)) { parameters.Add(ParameterEmail, Configuration.EmailAddress); } } string requestIdentifier = string.Empty; // Validate the Parameter ParameterValidationResult valid = ValidateParameters(parameters); if (!valid.IsValid) { throw new Exception(valid.ValidationErrors); } // Submit the job to server inputParams blastRequest = GetRequestParameter(parameters); blastRequest.appxml = AppXmlYes; blastRequest.async = true; data[] mydata = new data[1]; mydata[0] = new data(); mydata[0].type = SequenceType; mydata[0].content = FastAFormatter.FormatString(sequence); requestIdentifier = blastClient.runWUBlast(blastRequest, mydata); // Only if the event is registered, invoke the thread if (null != RequestCompleted) { BlastThreadParameter threadParameter = new BlastThreadParameter( requestIdentifier, sequence, parameters); // Start the BackGroundThread to check the status of job workerThread = new BackgroundWorker(); workerThread.WorkerSupportsCancellation = true; workerThread.DoWork += new DoWorkEventHandler(ProcessRequestThread); workerThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompletedRequestThread); workerThread.RunWorkerAsync(threadParameter); } return(requestIdentifier); }