public ItemScoringConfig GetItemScoringConfigs()
        {
            SqlCommand cmd = CreateCommand(CommandType.StoredProcedure, "SD_GetItemScoringConfigs");

            AddClientParameter(cmd);

            ItemScoringConfig config = new ItemScoringConfig
            {
                LoadTime         = DateTime.Now,
                ItemScoringRules = new List <ItemScoringRule>(),
                Satellites       = new List <ScoreHostInfo>()
            };

            ExecuteReader(cmd, delegate(IColumnReader reader)
            {
                while (reader.Read())
                {
                    ItemScoringRule rule = new ItemScoringRule
                    {
                        Context  = reader.GetString("Context"),
                        ItemType = reader.GetString("ItemType"),
                        Enabled  = reader.GetBoolean("Item_in")
                    };
                    if (reader.GetFieldType("Priority") == typeof(Boolean))
                    {
                        rule.Priority = reader.GetBoolean("Priority") ? 1 : 0;
                    }
                    else
                    {
                        rule.Priority = reader.GetInt32("Priority");
                    }
                    if (!reader.IsDBNull("ServerUrl"))
                    {
                        rule.ServerUrl = reader.GetString("ServerUrl");
                    }

                    config.ItemScoringRules.Add(rule);
                }

                if (reader.NextResult())
                {
                    while (reader.Read())
                    {
                        ScoreHostInfo satellite = new ScoreHostInfo
                        {
                            ScoreHost  = reader.GetString("scoreHost"),
                            StudentApp = reader.GetString("studentApp")
                        };
                        config.Satellites.Add(satellite);
                    }
                }
            });

            if (config.ItemScoringRules.Count == 0)
            {
                return(null);
            }

            return(config);
        }
        /// <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);
        }
Exemple #3
0
        public virtual ItemScoreRequest MakeItemScoreRequest(ReponseRepoMonitor repoMon, ScorableResponse scorableResponse, ItemScoringRule scoringRule, string itemScoringServerUrl)
        {
            // Check if we have a call back url. Without that, ISE can't send us back a score
            if (ScoringDaemonSettings.ItemScoringCallBackHostUrl == null)
            {
                return(null);
            }

            //The actual rubric is retrieved from the satellites student app. We send the item file path and let the student app give us the rubric
            string itemFile      = EncryptionHelper.EncodeToBase64(scorableResponse.ItemFile);
            string studentAppUrl = ScoringDaemonSettings.StudentAppUrlOverride ?? scoringRule.StudentAppUrl;
            Uri    rubricUri;

            if (!Uri.TryCreate(studentAppUrl + "ItemScoringRubric.axd?item=" + itemFile, UriKind.Absolute, out rubricUri))
            {
                return(null);
            }

            // If the item scoring server and the student app are colocated, check if we can use localhost to talk between the 2 instead of thier public URLs
            if (ScoringDaemonSettings.EnableLocalHostUsageForColocatedApps)
            {
                Uri itemScoringServerUri;
                if (Uri.TryCreate(itemScoringServerUrl, UriKind.Absolute, out itemScoringServerUri) &&
                    itemScoringServerUri.Host == rubricUri.Host)
                {
                    rubricUri = (new UriBuilder(rubricUri)
                    {
                        Host = "localhost"
                    }).Uri;
                }
            }

            // If the item format is one that is scored using our Java ISE, we need to send the item bank and key in the rubric URI as opposed to the itemFile
            // Rewrite the rubricUri accordingly
            if (ScoringDaemonSettings.ItemFormatsRequiringItemKeysForRubric.Contains(scorableResponse.Format))
            {
                string[] tokens = scorableResponse.ItemKey.Split('-');  // Item key is something like 195-3456
                if (tokens.Length != 2)
                {
                    return(null);                      // the item key is not parseable
                }
                if (!Uri.TryCreate(studentAppUrl + String.Format("ItemScoringRubric.axd?itembank={0}&itemid={1}", tokens[0], tokens[1]), UriKind.Absolute, out rubricUri))
                {
                    return(null);
                }
            }

            // Create a context token with enough info in it for the item scoring callback handler to persist the score
            // when it receives it
            string contextToken = GetContextToken(repoMon, scorableResponse);

            ResponseInfo responseInfo = new ResponseInfo(scorableResponse.Format, scorableResponse.ItemKey,
                                                         scorableResponse.Response, rubricUri, RubricContentType.Uri,
                                                         contextToken, true);

            return(new ItemScoreRequest
            {
                ResponseInfo = responseInfo,
                CallbackUrl = ScoringDaemonSettings.ItemScoringCallBackHostUrl + "ItemScoringCallback.axd"
            });
        }