public void RemoveAnItemByKeyFromTheMirrorCacheTest()
        {
            #region ASSEMBLE

            int totalCandidates            = 5000;
            int indexMiddle                = totalCandidates / 2;
            int indexCurrent               = 0;
            var random                     = new Random();
            var data                       = Enumerable.Range(1, totalCandidates).OrderBy(i => random.Next(1, totalCandidates));
            ManualResetEventSlim gate      = new ManualResetEventSlim();
            CountdownEvent       countdown = new CountdownEvent(1);
            TheMirrorCache <TheStorageEngineTSM> mirror;
            TheStorageEngineTSM        tsmCurrent = null;
            TheStorageEngineTSM        tsmMiddle  = null;
            TheStorageEngineTSM        tsmRemoved = null;
            TheStorageEngineTSM        tsmMatch   = null;
            List <TheStorageEngineTSM> TSMs       = new List <TheStorageEngineTSM>();
            List <TheStorageEngineTSM> myRecords  = new List <TheStorageEngineTSM>();

            // Build the collection of TSMs and cache the middle one
            foreach (var payload in data)
            {
                tsmCurrent = new TheStorageEngineTSM()
                {
                    cdeMID     = Guid.NewGuid(),
                    TXTPattern = payload.ToString()
                };
                TSMs.Add(tsmCurrent);
                if ((indexCurrent++ >= indexMiddle) && (tsmMiddle == null))
                {
                    tsmMiddle = tsmCurrent;
                }
            }
            if (tsmMiddle == null)
            {
                Assert.Fail("Unable to cache the middle TSM!");
            }

            // Spin up your mirror
            mirror = new TheMirrorCache <TheStorageEngineTSM>(10)
            {
                CacheStoreInterval       = 1,
                IsStoreIntervalInSeconds = true,
                IsCachePersistent        = true,
                UseSafeSave      = true,
                AllowFireUpdates = true,
            };

            // Add your items...
            mirror.AddItems(TSMs, response =>
            {
                myRecords = response;
                countdown.Signal();
            });

            countdown.Wait();
            if (TSMs.Count != myRecords.Count)
            {
                Assert.Fail("Not all test records were not added successfully.");
            }

            #endregion

            #region ACT

            // Attempt to remove your middle item
            Task.Factory.StartNew(() =>
            {
                mirror.RemoveAnItemByKey(tsmMiddle.cdeMID.ToString(), payload =>
                {
                    tsmRemoved = payload;
                    gate.Set();
                });
            });

            // Wait for response
            gate.Reset();
            gate.Wait(30000);
            if (tsmRemoved == null)
            {
                Assert.Fail("Unable to remove item by ID!");
            }

            // Attempt to retrieve your middle item
            tsmMatch = mirror.GetEntryByID(tsmMiddle.cdeMID);

            mirror?.Dispose();

            #endregion

            #region ASSERT

            Assert.IsTrue(tsmMatch == null);

            #endregion
        }
        private void InterceptHttpRequest(TheRequestData pRequest, Guid MyApp, IBaseEngine MyBaseEngine, int pRequestTimeout) // TheRelayAppInfo MyApp)
        {
            if (MyApp == Guid.Empty)
            {
                return;
            }
            TheRequestData tOutBuffer = null;
            //NEW BY CM
            string tMagixc = Guid.NewGuid().ToString();

            ReqBuffer.AddOrUpdateItem(TheCommonUtils.CGuid(tMagixc), null, null);
            if (!MyBaseEngine.GetEngineState().IsService) // || string.IsNullOrEmpty(MyApp.TargetUrl) || !TheCommonUtils.IsLocalhost(MyApp.HostUrl)) //  !MyApp.HostUrl.Equals(TheBaseAssets.MyServiceHostInfo.MyStation URL))
            {
                TSM tTSM = new TSM(MyBaseEngine.GetEngineName(), "WEBRELAY_REQUEST")
                {
                    PLB = pRequest.PostData
                };
                pRequest.PostData       = null;
                pRequest.ResponseBuffer = null;
                if (!string.IsNullOrEmpty(pRequest.CookieString))
                {
                    pRequest.CookieString += ";";
                }
                else
                {
                    pRequest.CookieString = "";
                }
                pRequest.CookieString += tMagixc;
                //if (string.IsNullOrEmpty(MyApp.CloudUrl)) MyApp.CloudUrl = TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false);
                if (string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.RootDir))
                {
                    pRequest.RequestUriString = pRequest.RequestUri.ToString();
                }
                else
                {
                    pRequest.RequestUriString = pRequest.RequestUri.Scheme + "://" + pRequest.RequestUri.Host + ":" + pRequest.RequestUri.Port + pRequest.cdeRealPage;
                    if (!string.IsNullOrEmpty(pRequest.RequestUri.Query))
                    {
                        pRequest.RequestUriString += "?" + pRequest.RequestUri.Query;
                    }
                }
                TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Requesting Page:{0}", pRequest.RequestUriString), eMsgLevel.l6_Debug));

                tTSM.PLS = TheCommonUtils.SerializeObjectToJSONString(pRequest);
                tTSM.SID = pRequest.SessionState.GetSID(); //.SScopeID;
                TheCommCore.PublishCentral(tTSM);          //  .PublishToNode(MyApp.HostUrl, pRequest.SessionState.SScopeID, tTSM);
            }
            else
            {
                TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("AppID:{1} Requesting Page:{0}", pRequest.cdeRealPage, MyApp)));
                ReadHttpPage(pRequest, MyApp, tMagixc, sinkResults);
            }
            int SyncFailCount      = 0;
            ManualResetEvent MyMRE = new ManualResetEvent(false);

            do
            {
                try
                {
                    tOutBuffer = ReqBuffer.GetEntryByID(TheCommonUtils.CGuid(tMagixc));
                    if (tOutBuffer != null)
                    {
                        pRequest.ResponseBuffer   = tOutBuffer.ResponseBuffer;
                        pRequest.ResponseMimeType = tOutBuffer.ResponseMimeType;
                        if (pRequest.SessionState.StateCookies == null)
                        {
                            pRequest.SessionState.StateCookies = new cdeConcurrentDictionary <string, string>();
                        }
                        if (tOutBuffer.SessionState != null && tOutBuffer.SessionState.StateCookies != null && tOutBuffer != pRequest)
                        {
                            foreach (KeyValuePair <String, String> kvp in tOutBuffer.SessionState.StateCookies.GetDynamicEnumerable())
                            {
                                string value;
                                if (!pRequest.SessionState.StateCookies.TryGetValue(kvp.Key, out value))
                                {
                                    pRequest.SessionState.StateCookies.TryAdd(kvp.Key, kvp.Value);
                                }
                                else
                                {
                                    pRequest.SessionState.StateCookies[kvp.Key] = kvp.Value;
                                }
                            }
                        }

                        if (!string.IsNullOrEmpty(tOutBuffer.ResponseBufferStr))
                        {
                            pRequest.ResponseBufferStr = tOutBuffer.ResponseBufferStr;
                        }
                        else
                        {
                            if (pRequest.ResponseMimeType.StartsWith("text/html") || pRequest.ResponseMimeType.Contains("javascript"))  //OK
                            {
                                pRequest.ResponseBufferStr = TheCommonUtils.CArray2UTF8String(tOutBuffer.ResponseBuffer);
                            }
                        }
                        string tReqUri = pRequest.RequestUri.Host;
                        if (pRequest.RequestUri.Port != 80)
                        {
                            tReqUri += ":" + pRequest.RequestUri.Port;
                        }
                        TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Got Response Page:{0}", tReqUri), eMsgLevel.l6_Debug));

                        if (!string.IsNullOrEmpty(pRequest.ResponseBufferStr) && (pRequest.ResponseMimeType.StartsWith("text/html") || pRequest.ResponseMimeType.Contains("javascript")) && pRequest.ResponseBufferStr.IndexOf(tReqUri, StringComparison.CurrentCultureIgnoreCase) >= 0)
                        {
                            if (pRequest.SessionState.ARApp != null && pRequest.SessionState.ARApp != Guid.Empty)
                            {
                                TheRelayAppInfo tMyApp = TheThingRegistry.GetThingObjectByMID(MyBaseEngine.GetEngineName(), pRequest.SessionState.ARApp) as TheRelayAppInfo;
                                //MyRelayApps.MyMirrorCache.GetEntryByFunc(s => s.cdeMID.Equals(pRequest.SessionState.ARApp));

                                if (tMyApp != null && tMyApp.CloudUrl != null)
                                {
                                    Uri tCloudUri = TheCommonUtils.CUri(tMyApp.CloudUrl, false);
                                    if (!string.IsNullOrEmpty(pRequest.NewLocation))
                                    {
                                        pRequest.NewLocation = pRequest.NewLocation.Replace(pRequest.RequestUri.Scheme + "://" + tReqUri, tCloudUri.Scheme + "://" + tCloudUri.Host + ":" + tCloudUri.Port);
                                    }
                                    TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Patching Uri from:{0} to:{1}", tReqUri, tCloudUri), eMsgLevel.l6_Debug));

                                    pRequest.ResponseBufferStr = pRequest.ResponseBufferStr.Replace(pRequest.RequestUri.Scheme + "://" + tReqUri, tCloudUri.Scheme + "://" + tCloudUri.Host + ":" + tCloudUri.Port);
                                    pRequest.ResponseBuffer    = TheCommonUtils.CUTF8String2Array(pRequest.ResponseBufferStr);
                                }
                            }
                        }
                        break;
                    }
                    MyMRE.WaitOne(50);
                    SyncFailCount++; if (SyncFailCount > (pRequestTimeout * 20))
                    {
                        if (TheCommonUtils.IsMono())
                        {
                            TheBaseAssets.MySYSLOG.WriteToLog(400, new TSM(MyBaseEngine.GetEngineName(), string.Format("Requesting Page:{0} FAILED", pRequest.cdeRealPage), eMsgLevel.l1_Error));
                        }
                        else
                        {
                            TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Requesting Page:{0} FAILED", pRequest.cdeRealPage), eMsgLevel.l1_Error));
                        }
                        break;
                    }
                }
                catch (Exception ee)
                {
                    TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Error during HttpIntercept for Page:{0}", pRequest.cdeRealPage), eMsgLevel.l1_Error, ee.ToString()));
                }
            } while (tOutBuffer == null);
            if (MyMRE != null)
            {
                MyMRE = null; //.Dispose();
            }
            if ((pRequest.ResponseBuffer == null && string.IsNullOrEmpty(pRequest.ResponseBufferStr)) || pRequest.StatusCode != 0)
            {
                if (pRequest.StatusCode == 0)
                {
                    pRequest.StatusCode = 404;
                }
            }
            else
            {
                pRequest.AllowStatePush = true;
                pRequest.StatusCode     = 200;
            }
            ReqBuffer.RemoveAnItemByID(TheCommonUtils.CGuid(tMagixc), null);
        }
        public void GetRecordsFromTheMirrorCache(
            [Values(0, 500, 5000)] int maxCount,
            [Values(50, 5000)] int totalCandidates
            )
        {
            #region ASSEMBLE
            bool entryNotFound             = false;
            var  random                    = new Random();
            var  data                      = Enumerable.Range(1, totalCandidates).OrderBy(i => random.Next(1, totalCandidates));
            ManualResetEventSlim gate      = new ManualResetEventSlim();
            CountdownEvent       countdown = new CountdownEvent(1);
            TheMirrorCache <TheStorageEngineTSM> mirror;
            List <TheStorageEngineTSM>           TSMs      = new List <TheStorageEngineTSM>();
            List <TheStorageEngineTSM>           myRecords = new List <TheStorageEngineTSM>();

            // Build the collection of TSMs
            var baseTime = DateTimeOffset.Now;
            int counter  = 0;
            foreach (var payload in data)
            {
                TSMs.Add(new TheStorageEngineTSM()
                {
                    cdeMID     = Guid.NewGuid(),
                    TXTPattern = payload.ToString(),
                    cdeCTIM    = baseTime.AddTicks(counter++),
                });
            }

            // Spin up your mirror
            mirror = new TheMirrorCache <TheStorageEngineTSM>(10)
            {
                CacheStoreInterval       = 1,
                IsStoreIntervalInSeconds = true,
                IsCachePersistent        = true,
                UseSafeSave      = true,
                AllowFireUpdates = true,
            };
            if (maxCount != 0)
            {
                mirror.SetMaxStoreSize(maxCount);
            }

            // Add your items...
            mirror.AddItems(TSMs, response =>
            {
                myRecords = response;
                countdown.Signal();
            });

            countdown.Wait();

            Assert.AreEqual(totalCandidates, myRecords.Count, "Not all test records were added successfully.");

            #endregion

            #region ACT

            var expectedCount = maxCount == 0 ? totalCandidates : Math.Min(maxCount, totalCandidates);
            Assert.AreEqual(expectedCount, mirror.Count, "Not all test records were not added successfully.");

            // Retrieve your items...
            counter = 0;
            foreach (var tsm in TSMs)
            {
                TheStorageEngineTSM match = mirror.GetEntryByID(tsm.cdeMID);
                if (counter >= TSMs.Count - expectedCount)
                {
                    if (match == null)
                    {
                        entryNotFound = true;
                        break;
                    }
                }
                else
                {
                    if (match != null)
                    {
                        Assert.IsNull(match, "Item found that was supposed to have been removed due to max count limit", counter);
                    }
                }
                counter++;
            }

            mirror?.Dispose();

            #endregion

            #region ASSERT

            Assert.IsFalse(entryNotFound, "TheMirrorCache was missing one or more test entries!");

            #endregion
        }