コード例 #1
0
        /// <summary>
        ///  Items that have
        /// </summary>
        /// <param name="expiredResponses"></param>
        /// <returns></returns>
        private int ProcessExpiredResponses(IEnumerable <ScorableResponse> expiredResponses)
        {
            int failures = 0;

            foreach (ScorableResponse scorableResponse in expiredResponses)
            {
                ScoredResponse scoredResponse = new ScoredResponse
                {
                    ItemKey         = scorableResponse.ItemKey,
                    OppKey          = scorableResponse.OppKey,
                    Position        = scorableResponse.Position,
                    Score           = -1,
                    ScoreDimensions = null,
                    ScoreMark       = scorableResponse.ScoreMark,
                    ScoreRationale  = "Max Score Attempts Exceeded",
                    ScoreStatus     = "ScoringError",
                    Sequence        = scorableResponse.ResponseSequence
                };
                try
                {
                    UpdateItemScore(scoredResponse);
                }
                catch (Exception e)
                {
                    failures++;
                }
            }
            return(failures);
        }
コード例 #2
0
 public void UpdateItemScore(ScoredResponse scoredResponse)
 {
     if (scoredResponse == null)
     {
         return;                           // Should probably log an error here if this were to happen.
     }
     ScorableTest scorableTest = ResponseRepository.UpdateItemScore(scoredResponse);
 }
コード例 #3
0
 private static void OutputScoredResponse(ScoredResponse response)
 {
     OutputResponse(response);
     Console.WriteLine("CustomerId: " + response.Score.CustomerId);
     Console.WriteLine("Action: " + response.Score.Action);
     Console.WriteLine("Source: " + response.Score.Source);
     Console.WriteLine("ScoreId: " + response.Score.ScoreId);
     Console.WriteLine("Comment: " + response.Score.Comment);
 }
コード例 #4
0
        /// <summary>
        /// Will attempt to update the item score for this response.  If there are no more
        /// responses waiting for action, it will also flip the test status to 'handscored'
        /// and submit the file back to the source bin in xmlrepo for TIS to pick up and process.
        /// </summary>
        /// <param name="scoredResponse"></param>
        /// <returns></returns>
        public ScorableTest UpdateItemScore(ScoredResponse scoredResponse)
        {
            ReturnStatus returnStatus = null;
            SqlCommand   cmd          = CreateCommand(CommandType.StoredProcedure, "SD_UpdateItemScore");
            MemoryStream ms           = null;

            int[] itemKey = scoredResponse.GetItemKeyTokens();

            try
            {
                cmd.AddUniqueIdentifier("oppkey", scoredResponse.OppKey);
                cmd.AddInt("itemBank", itemKey[0]);
                cmd.AddInt("itemKey", itemKey[1]);
                //cmd.AddInt("position", scoredResponse.Position);
                cmd.AddInt("sequence", scoredResponse.Sequence); // TODO: this will be reportingversion
                cmd.AddInt("score", scoredResponse.Score);
                cmd.AddVarChar("scorestatus", scoredResponse.ScoreStatus, 150);
                if (!String.IsNullOrEmpty(scoredResponse.ScoreRationale))
                {
                    cmd.AddVarCharMax("scoreRationale", scoredResponse.ScoreRationale);
                }
                //cmd.AddUniqueIdentifier("scoremark", scoredResponse.ScoreMark);
                if (!String.IsNullOrEmpty(scoredResponse.ScoreDimensions))
                {
                    ms = new MemoryStream();
                    scoredResponse.ScoreInfoAsXml().Save(ms);
                    cmd.AddXml("scoreDimensions", new SqlXml(ms));
                }

                ExecuteReader(cmd, delegate(IColumnReader reader)
                {
                    if (reader.Read())
                    {
                        returnStatus = ReturnStatus.Parse(reader);
                    }
                });
            }
            finally
            {
                if (ms != null)
                {
                    ms.Dispose();
                }
            }

            // if the sproc didn't return success, it means that the opp was not in a state that allows
            //  item score updates.  Either the reportingVersion didn't match or the opp was not in handscoring or appeal status
            //  Log the score in this case so that we have a record of it.
            if (!returnStatus.Status.Equals("success"))
            {
                TDSLogger.Application.Info(new TraceLog(String.Format("Item Scoring: Did not accept score: {0}", scoredResponse.AsString())));
            }

            // always returning null for ScorableTest.  Will not support test scoring here.  That will be the responsibility of TIS
            return(null);
        }
        private void ProcessScore(HttpContext context)
        {
            Interlocked.Increment(ref RequestCount);

            // GET RESPONSE
            ItemScoreResponse itemScoreResponse;

            // Get XML
            using (XmlReader reader = XmlReader.Create(context.Request.InputStream))
            {
                itemScoreResponse = HttpWebHelper.DeserializeXml <ItemScoreResponse>(reader);
                reader.Close();
            }

            // get the context token and deserialize it
            string decryptedToken = GetContextToken(itemScoreResponse);
            ItemScoreRequestContextToken tokenData = null;

            // get test data
            try
            {
                tokenData = JsonHelper.Deserialize <ItemScoreRequestContextToken>(decryptedToken);
            }
            catch (Exception ex)
            {
                throw new ApplicationException(String.Format("Could not read contextToken: {0},  Error: {1}.", decryptedToken ?? "(null)", ex.Message));
            }

            // create response
            ScoredResponse scoredResponse = new ScoredResponse()
            {
                ItemKey         = tokenData.ItemKey,
                OppKey          = tokenData.oppKey,
                Sequence        = tokenData.reportingVersion ?? -1,
                Score           = itemScoreResponse.Score.ScoreInfo.Points,
                ScoreStatus     = itemScoreResponse.Score.ScoreInfo.Status.ToString(),
                ScoreRationale  = null,
                ScoreDimensions = HttpWebHelper.SerializeXml(itemScoreResponse.Score.ScoreInfo)
            };

            string hubDBIP     = tokenData.TISIP;
            string hubDBName   = tokenData.TISDbName;
            string clientName  = tokenData.clientName;
            string environment = tokenData.environment;

            // create function for submitting scores
            Action submitScore = delegate
            {
                Interlocked.Increment(ref ProgressCount);

                try
                {
                    if (String.IsNullOrEmpty(hubDBIP))
                    {
                        // must be sending items for scoring in the TDSReport format where we don't send
                        //  this information in the context token.  In this case, we can only support a single configured hub.
                        //  Grab the info from that hub.
                        IAdminRepository     cloudRepository = ServiceLocator.Resolve <IAdminRepository>();
                        List <DataStoreInfo> hubs            = cloudRepository.GetMonitoredDataStores(ScoringDaemonSettings.MachineName);
                        hubs = hubs.FindAll(h => h.ClientName == clientName).ToList <DataStoreInfo>();
                        if (hubs.Count == 0)
                        {
                            throw new ApplicationException(String.Format("No hubs are configured for client: {0} on machine: {1}", clientName, ScoringDaemonSettings.MachineName));
                        }
                        if (hubs.Count > 1)
                        {
                            throw new ApplicationException(String.Format("TIS item scoring callback handler only supports a single hub per client for this type of request.  {0} are configured for client: {1}.", hubs.Count, clientName));
                        }
                        hubDBIP     = ScoringDaemonSettings.HubIP(hubs[0]);
                        hubDBName   = hubs[0].DBName;
                        clientName  = hubs[0].ClientName;
                        environment = hubs[0].Environment;
                    }

                    // Save score to DB
                    IResponseRepository responseRepo = ServiceLocator.Resolve <IResponseRespositoryFactory>()
                                                       .Create(ScoringDaemonSettings.HubConnectionString(hubDBIP, hubDBName), clientName, environment);

                    if (responseRepo == null)
                    {
                        // this is really unusual. We got a item score response for an unknown hub.
                        string errorMessage =
                            String.Format(
                                "Got a score response for a hub that we dont monitor. oppKey:{0}, itemKey: {1}, sequence:{2}, clientName: {3}, environment: {4}",
                                scoredResponse.OppKey, scoredResponse.ItemKey, scoredResponse.Sequence, clientName, environment);
                        throw new InvalidDataException(errorMessage);
                    }

                    //run resolution rule if there is one
                    //Zach 12/11/2014 TODO: Add checks or try/catches around each part of running the rule to give more specific error messages?
                    TISItemResolutionRule rule = TISItemResolutionRule.CreateRule(tokenData.itemType, scoredResponse.ItemKey, clientName);
                    if (rule != null)
                    {
                        TDSQASystemAPI.TestResults.ItemScoreInfo resolvedScore = rule.ResolveItemScore(Serialization.DeserializeXml <TDSQASystemAPI.TestResults.ItemScoreInfo>(scoredResponse.ScoreDimensions));
                        scoredResponse.Score           = (int)resolvedScore.Points;
                        scoredResponse.ScoreStatus     = resolvedScore.Status == TDSQASystemAPI.TestResults.ScoringStatus.Scored ? ScoringStatus.Scored.ToString() : ScoringStatus.ScoringError.ToString();
                        scoredResponse.ScoreDimensions = HttpWebHelper.SerializeXml(resolvedScore);
                    }

                    responseRepo.UpdateItemScore(scoredResponse);
                }
                catch (Exception ex)
                {
                    Interlocked.Decrement(ref ProgressCount);
                    Interlocked.Increment(ref ErrorCount);

                    LastError = String.Format("{0} ({1})", ex.Message, DateTime.Now);

                    // wasn't logging the exception.  See TDS.Shared.Logging.TraceLog.ToString()
                    string id = tokenData == null ? "Unknown" : tokenData.ToString();
                    TDSLogger.Application.Error(new ApplicationException(String.Format("Error submitting callback score for: {0}", id), ex));
                    //TDSLogger.Application.Error(new TraceLog("Error submitting callback score.", ex));

                    return;
                }

                Interlocked.Decrement(ref ProgressCount);
                Interlocked.Increment(ref SuccessCount);
            };

            // check if thread pooling is enabled for callbacks
            if (WorkerPool != null)
            {
                // async
                if (!WorkerPool.Enqueue(submitScore))
                {
                    Interlocked.Increment(ref RejectCount);
                }
            }
            else
            {
                // sync
                submitScore();
            }
        }
コード例 #6
0
        /// <summary>
        /// Submit responses that need scores to the remote item scoring engine
        /// </summary>
        /// <param name="pendingResponses"></param>
        /// <returns></returns>
        private int ProcessPendingResponses(IEnumerable <ScorableResponse> pendingResponses)
        {
            int failures = 0;

            if (ItemScoringConf == null)
            {
                return(pendingResponses.Count());
            }

            foreach (ScorableResponse scorableResponse in pendingResponses)
            {
                ItemScoringRule rule = ItemScoringConf.GetItemScoringRule(scorableResponse.Format, scorableResponse.TestId);

                if (rule == null || (rule.Enabled && (rule.ServerUrl == null || rule.StudentAppUrl == null)))
                {
                    failures++;
                    continue;
                }

                if (!rule.Enabled || scorableResponse.Response == null)
                {
                    // This item is NOT supposed to be machine scored.
                    ScoredResponse scoredResponse = new ScoredResponse
                    {
                        ItemKey         = scorableResponse.ItemKey,
                        OppKey          = scorableResponse.OppKey,
                        Position        = scorableResponse.Position,
                        Score           = -1,
                        ScoreDimensions = null,
                        ScoreMark       = scorableResponse.ScoreMark,
                        ScoreRationale  = !rule.Enabled ? "Item configured not to be scored" : "Item Response is NULL",
                        ScoreStatus     = "NotScored",
                        Sequence        = scorableResponse.ResponseSequence
                    };
                    try
                    {
                        UpdateItemScore(scoredResponse);
                    }
                    catch (Exception e)
                    {
                        failures++;
                    }
                }
                else if (String.IsNullOrEmpty(scorableResponse.ItemFile))   // Sometimes, we get responses that have no item file specified. We cannot do anything with these.
                {
                    // This item is NOT supposed to be machine scored.
                    ScoredResponse scoredResponse = new ScoredResponse
                    {
                        ItemKey         = scorableResponse.ItemKey,
                        OppKey          = scorableResponse.OppKey,
                        Position        = scorableResponse.Position,
                        Score           = -1,
                        ScoreDimensions = null,
                        ScoreMark       = scorableResponse.ScoreMark,
                        ScoreRationale  = "Item file path is null",
                        ScoreStatus     = "ScoringError",
                        Sequence        = scorableResponse.ResponseSequence
                    };
                    try
                    {
                        UpdateItemScore(scoredResponse);
                    }
                    catch (Exception e)
                    {
                        failures++;
                    }
                }
                else
                {
                    // Send this item off to scoring
                    string           itemScoringServerUrl = ScoringDaemonSettings.ItemScoringServerUrlOverride ?? rule.ServerUrl;
                    ItemScoreRequest itemScoreRequest     = ServiceLocator.Resolve <ItemScoreRequestFactory>().MakeItemScoreRequest(this, scorableResponse, rule, itemScoringServerUrl);

                    if (itemScoreRequest == null)
                    {
                        failures++;
                        continue;
                    }

                    ScoreRequestSender.SendRequestAsync(itemScoringServerUrl, itemScoreRequest, null);
                }
            }

            return(failures);
        }
        private void ProcessScore(HttpContext context)
        {
            Interlocked.Increment(ref RequestCount);

            // GET RESPONSE
            ItemScoreResponse itemScoreResponse;

            // Get XML
            using (XmlReader reader = XmlReader.Create(context.Request.InputStream))
            {
                itemScoreResponse = HttpWebHelper.DeserializeXml <ItemScoreResponse>(reader);
                reader.Close();
            }

            // decrypt token
            string decryptedToken = EncryptionHelper.DecryptFromBase64(itemScoreResponse.Score.ContextToken);

            // get test data
            WebValueCollection tokenData = new WebValueCollection();

            tokenData.FillFromString(decryptedToken);

            // parse test data and collect up the information needed to persist this score
            ScoredResponse scoredResponse = new ScoredResponse
            {
                OppKey          = tokenData.Get <Guid>("oppKey"),
                ItemKey         = tokenData.Get("itemKey"),
                Position        = tokenData.Get <int>("position"),
                Sequence        = tokenData.Get <int>("sequence"),
                ScoreMark       = tokenData.Get <Guid>("scoremark"),
                Score           = itemScoreResponse.Score.ScoreInfo.Points,
                ScoreStatus     = itemScoreResponse.Score.ScoreInfo.Status.ToString(),
                ScoreRationale  = HttpWebHelper.SerializeXml(itemScoreResponse.Score.ScoreInfo),
                ScoreDimensions = GetDimensionsXmlForSP(itemScoreResponse.Score.ScoreInfo)
            };

            string hubDBIP     = tokenData.Get <String>("hubDBIP");
            string hubDBName   = tokenData.Get <String>("hubDBName");
            string clientName  = tokenData.Get <String>("clientName");
            string environment = tokenData.Get <String>("environment");

            // create function for submitting scores
            Action submitScore = delegate
            {
                Interlocked.Increment(ref ProgressCount);

                try
                {
                    // Save score to DB
                    IResponseRepository responseRepo = ServiceLocator.Resolve <IResponseRespositoryFactory>()
                                                       .Create(ScoringDaemonSettings.HubConnectionString(hubDBIP, hubDBName), clientName, environment);

                    if (responseRepo != null)
                    {
                        responseRepo.UpdateItemScore(scoredResponse);
                    }
                    else
                    {
                        // this is really unusual. We got a item score response for an unknown hub.
                        string errorMessage =
                            String.Format(
                                "Got a score response for a hub that we dont monitor. oppKey:{0}, itemKey: {1}, position: {2}, sequence:{3}, scoreMark: {4}, clientName: {5}, environment: {6}",
                                scoredResponse.OppKey, scoredResponse.ItemKey, scoredResponse.Position,
                                scoredResponse.Sequence, scoredResponse.ScoreMark, clientName, environment);
                        throw new InvalidDataException(errorMessage);
                    }
                }
                catch (Exception ex)
                {
                    Interlocked.Decrement(ref ProgressCount);
                    Interlocked.Increment(ref ErrorCount);

                    LastError = String.Format("{0} ({1})", ex.Message, DateTime.Now);
                    TDSLogger.Application.Error(new TraceLog("Item Scoring: Error submitting callback score.", ex));

                    return;
                }

                Interlocked.Decrement(ref ProgressCount);
                Interlocked.Increment(ref SuccessCount);
            };

            // check if thread pooling is enabled for callbacks
            if (WorkerPool != null)
            {
                // async
                if (!WorkerPool.Enqueue(submitScore))
                {
                    Interlocked.Increment(ref RejectCount);
                }
            }
            else
            {
                // sync
                submitScore();
            }
        }