/// <summary> /// Returns all scheduled <c>IImagingTask</c>s for the <c>plateID</c>. /// </summary> public IImagingTask[] GetImagingTasks(Formulatrix.Integrations.ImagerLink.IRobot robot, string plateID) { // Check arguments - do it up front to avoid possible inconsistencies later if (null == robot) { throw new System.NullReferenceException("robot must not be null"); } if (null == plateID) { throw new System.NullReferenceException("plateID must not be null"); } // Log the call to the method if (_log.IsDebugEnabled) { string msg = "Called " + this + ".GetImagingTasks(robot=" + RobotUtils.iRobotToString(robot) + ", plateID=\"" + plateID + "\")"; _log.Debug(msg); } // Declare the array that will be populated and returned - default to a zero-length array IImagingTask[] iImagingTasks = new IImagingTask[0]; // Bail out on test plates if ("ReliabilityTestPlate".Equals(plateID) || "ReservedSlot".Equals(plateID)) { return(iImagingTasks); } // Ensure connected to database - may throw an exception but we don't need/want to catch it if ((null == _dbConnection) || (System.Data.ConnectionState.Closed.Equals(_dbConnection.State))) { //connectToDB(); } // Try and read the imaging tasks from the db OdbcDataReader dataReader = null; try { // TODO - unnecessary check? Can connectToDB fail without throwing an exception? if (System.Data.ConnectionState.Open.Equals(_dbConnection.State)) { // Update the parameters _command.Parameters["@p1"].Value = plateID; // If we care which imager if (2 == _command.Parameters.Count) { _command.Parameters["@p2"].Value = robot.Name; } // Execute the select dataReader = _command.ExecuteReader(); // Read the data reader's rows into the ProjectList if (dataReader.HasRows) { // Get an ArrayList to hold the tasks System.Collections.ArrayList tasks = new System.Collections.ArrayList(); // Loop over all the returned rows while (dataReader.Read()) { // Create and populate a new ImagingTask global::OPPF.Integrations.ImagerLink.Scheduling.ImagingTask task = new global::OPPF.Integrations.ImagerLink.Scheduling.ImagingTask(); // .NET < 2.0 //task.DateToImage = dataReader.GetDateTime(0); // .NET >= 2.0 Only! task.SetDateToImage(DateTime.SpecifyKind(dataReader.GetDateTime(0), DateTimeKind.Utc)); if (dataReader.IsDBNull(1)) { task.SetDateImaged(DateTime.MinValue); } else { // .NET < 2.0 //task.DateImaged = dataReader.GetDateTime(1); // .NET >= 2.0 Only! task.SetDateImaged(DateTime.SpecifyKind(dataReader.GetDateTime(1), DateTimeKind.Utc)); //task.DateImaged = dataReader.GetDateTime(1).ToLocalTime(); } if (dataReader.IsDBNull(2)) { _log.Warn("Got null priority for plateID: " + plateID + " task: " + task.DateToImage.ToLongTimeString()); task.SetPriority(5); } else { task.SetPriority(dataReader.GetInt32(2)); } if (dataReader.IsDBNull(3)) { _log.Warn("Got null state for plateID: " + plateID + " task: " + task.DateToImage.ToLongTimeString()); if (dataReader.IsDBNull(1)) { task.SetState(Formulatrix.Integrations.ImagerLink.Scheduling.ImagingState.NotCompleted); } else { task.SetState(Formulatrix.Integrations.ImagerLink.Scheduling.ImagingState.Completed); } } else { task.SetState((Formulatrix.Integrations.ImagerLink.Scheduling.ImagingState)dataReader.GetInt32(3)); } task.SetInQueue(true); // Store this task in the ArrayList tasks.Add(task); //_log.Debug("> Got task: DateToImage=" + task.DateToImage + ", Priority=" + task.Priority + ", State=" + task.State + ", InQueue= " + task.InQueue); } // Convert ArrayList to IImagingTask[] iImagingTasks = (IImagingTask[])tasks.ToArray(typeof(IImagingTask)); } // Close the dataReader dataReader.Close(); } } catch (Exception e) { // Log it string msg = "Exception " + e.Message + " during direct db part of getImagingTasks() for plate " + plateID + " - will fail down to webservice call"; _log.Error(msg, e); try { // Clean up the dataReader if ((null != dataReader) && (!dataReader.IsClosed)) { dataReader.Close(); } dataReader = null; if (null != _dbConnection) { _dbConnection.Close(); } } catch (Exception e1) { // Log it string msg1 = "Exception " + e1.Message + " while handling exception during direct db part of direct db part of getImagingTasks() for plate " + plateID + " - will fail down to webservice call"; _log.Error(msg1, e1); } // Don't rethrow - fail down to webservice call } // If we got no or not enough tasks if ((null == iImagingTasks) || (iImagingTasks.GetLength(0) < MIN_IMAGING_TASKS)) { // Hit the webservice, which may cause a schedule to be created iImagingTasks = GetImagingTasksFromWebService(robot, plateID); } // Set an appropriate value for InQueue setInQueue(iImagingTasks); // Ensure we never return null if (null == iImagingTasks) { // Fix it iImagingTasks = new IImagingTask[0]; // Log it _log.Warn("Fixed null iImagingTasks at end of WSPlate.getImagingTasks() for plate " + plateID); } // Return the array of IImagingTasks return(iImagingTasks); }
/// <summary> /// Web service version of GetImagingTasks - useful because it will /// cause a full schedule to be written if one doesn't already /// exist. /// /// Warning - this is a lot slower than going straight to platedb! /// </summary> /// <param name="robot">The robot</param> /// <param name="plateID">The barcode of the plate</param> /// <returns></returns> public IImagingTask[] GetImagingTasksFromWebService(Formulatrix.Integrations.ImagerLink.IRobot robot, string plateID) { // Check arguments - do it up front to avoid possible inconsistencies later if (null == robot) { throw new System.NullReferenceException("robot must not be null"); } if (null == plateID) { throw new System.NullReferenceException("plateID must not be null"); } // Log the call if (_log.IsInfoEnabled) { string msg = "Calling WSPlate.getImagingTasks() for plate " + plateID + ", robot " + RobotUtils.iRobotToString(robot); _log.Info(msg); } // Declare the array that will be populated and returned // - default to a zero-length array IImagingTask[] iImagingTasks = new IImagingTask[0]; // Set the request getImagingTasks request = new getImagingTasks(); request.robot = global::OPPF.Utilities.Robot2Utils.createProxy(robot); request.plateID = plateID; // Make the call getImagingTasksResponse response = null; try { WSPlate wsPlate = WSPlateFactory.getWSPlate2(); wsPlate.Timeout = 10000; response = wsPlate.getImagingTasks(request); } catch (Exception e) { // Log it string msg = "WSPlate.getImagingTasks threw " + e.GetType() + ": " + e.Message + " for plateid \"" + plateID + "\" in robot \"" + robot.Name + "\" - returning empty IImagingTask[]"; msg = msg + WSPlateFactory.SoapExceptionToString(e); _log.Error(msg, e); // Don't rethrow - just return empty array return(iImagingTasks); } // If we got a response if (null != response) { // Get the array of ImagingTasks from the response global::OPPF.Proxies2.ImagingTask[] wrapper = response.wrapper; // Convert to IImagingTasks iImagingTasks = new IImagingTask[wrapper.GetLength(0)]; for (int i = 0; i < wrapper.GetLength(0); i++) { global::OPPF.Integrations.ImagerLink.Scheduling.ImagingTask task = new global::OPPF.Integrations.ImagerLink.Scheduling.ImagingTask(); if (wrapper[i].dateImaged.HasValue) { task.SetDateImaged(wrapper[i].dateImaged.Value); } task.SetDateToImage(wrapper[i].dateToImage); task.SetInQueue(wrapper[i].inQueue); task.SetPriority(wrapper[i].priority); task.SetState((Formulatrix.Integrations.ImagerLink.Scheduling.ImagingState)wrapper[i].state); iImagingTasks[i] = task; } } // Return the IImagingTask array return(iImagingTasks); }