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(); } }
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(); } }