public static ReponseRepoMonitor Lookup(String clientName, String environment)
        {
            ReponseRepoMonitor result = null;

            _collection.TryGetValue(MakeKey(clientName, environment), out result);
            return(result);
        }
        public static ReponseRepoMonitor Remove(String clientName, String environment)
        {
            ReponseRepoMonitor reponseRepoMonitor = Lookup(clientName, environment);

            if (reponseRepoMonitor != null)
            {
                _collection.Remove(MakeKey(clientName, environment));
            }
            return(reponseRepoMonitor);
        }
示例#3
0
        protected virtual string GetContextToken(ReponseRepoMonitor repoMon, ScorableResponse scorableResponse)
        {
            WebValueCollection tokenData = new WebValueCollection();

            tokenData.Set("oppKey", scorableResponse.OppKey);
            tokenData.Set("itemKey", scorableResponse.ItemKey);
            tokenData.Set("position", scorableResponse.Position);
            tokenData.Set("sequence", scorableResponse.ResponseSequence);
            tokenData.Set("scoremark", scorableResponse.ScoreMark);
            tokenData.Set("hubDBIP", repoMon.DBIP);
            tokenData.Set("hubDBName", repoMon.DBName);
            tokenData.Set("clientName", repoMon.ClientName);
            tokenData.Set("environment", repoMon.Environment);
            return(EncryptionHelper.EncryptToBase64(tokenData.ToString(false))); // encrypt token (do not url encode)
        }
        public void Start(WindowsIdentity identity, Action initializeCallback)
        {
            if (_started) return;

            ScoringDaemonSettings.AppStartTime = DateTime.Now;

            if (initializeCallback == null)
                // create the thread pool and assign it to the callback handler
                ItemScoringCallbackHandler.WorkerPool = new BoundedThreadPool(
                    ScoringDaemonSettings.CallbackThreadPoolCount, "Item Scoring Callback",
                    ScoringDaemonSettings.CallbackThreadPoolHighWaterMark, ScoringDaemonSettings.CallbackThreadPoolLowWaterMark);
            else
                initializeCallback();

            // Check that the cloud DB connection string is provisioned. If not, nothing we can do here
            if (ScoringDaemonSettings.CloudConnectionString == null)
            {
                throw new InvalidDataException("Connection String for the Cloud DB not provided");
            }

            // Setup the timer to scan the cloud db for hubs to manage
            long interval = (ScoringDaemonSettings.CloudTimerIntervalSeconds * 1000);
            const long startup = 100;
            _cloudTimer = new Timer(delegate
            {
                WindowsImpersonationContext wi = null;
                try
                {
                    wi = identity.Impersonate();

                    IAdminRepository cloudRepository = ServiceLocator.Resolve<IAdminRepository>();
                    List<DataStoreInfo> hubs = cloudRepository.GetMonitoredDataStores(ScoringDaemonSettings.MachineName);
                    ScoringDaemonSettings.CloudLastPollTime = DateTime.Now;

                    // Dispose of any hubs that are no longer present
                    foreach (ReponseRepoMonitor hub in MonitorCollection.GetAll())
                    {
                        bool found = false;
                        foreach (var cloudServiceInfo in hubs)
                        {
                            if (cloudServiceInfo.ClientName == hub.ClientName &&
                                cloudServiceInfo.Environment == hub.Environment &&
                                cloudServiceInfo.DBName == hub.DBName &&
                                ScoringDaemonSettings.HubIP(cloudServiceInfo) == hub.DBIP)
                            {
                                found = true; // OK - so this hub should still be retained
                            }
                        }
                        if (!found)
                        {
                            // Now we have a hub that used to be registered in the cloud and is no longer there. Get rid of it.
                            MonitorCollection.Remove(hub.ClientName, hub.Environment);
                            hub.Dispose();
                            TDSLogger.Application.Info(String.Format("Disposing ReponseRepoMonitor {0}:{1}:{2}:{3}", hub.ClientName, hub.Environment, hub.DBIP, hub.DBName));
                        }
                    }

                    // Add any new hubs that need to be added
                    foreach (DataStoreInfo hubInfo in hubs)
                    {
                        ReponseRepoMonitor reponseRepoMonitor = MonitorCollection.Lookup(hubInfo.ClientName, hubInfo.Environment);
                        if (reponseRepoMonitor == null)
                        {
                            reponseRepoMonitor = new ReponseRepoMonitor(hubInfo.ClientName, hubInfo.Environment, ScoringDaemonSettings.HubIP(hubInfo), hubInfo.DBName);
                            MonitorCollection.Add(reponseRepoMonitor);
                            reponseRepoMonitor.Activate();
                            TDSLogger.Application.Info(String.Format("Adding ReponseRepoMonitor {0}:{1}:{2}:{3}", reponseRepoMonitor.ClientName, reponseRepoMonitor.Environment, reponseRepoMonitor.DBIP, reponseRepoMonitor.DBName));
                        }
                    }

                }
                catch (Exception ex)
                {
                    string errorMessage = String.Format("CloudTimer: Fatal exception occured on Cloud Timer thread");
                    TDSLogger.Application.Fatal(new TraceLog("Application: " + errorMessage, ex));
                }
                finally
                {
                    if (wi != null) wi.Undo();
                }

            }, null, startup, interval);

            _started = true;
        }
示例#5
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"
            });
        }
 public static void Add(ReponseRepoMonitor reponseRepoMonitor)
 {
     _collection.Add(MakeKey(reponseRepoMonitor.ClientName, reponseRepoMonitor.Environment), reponseRepoMonitor);
 }