public void AppPackageFolder_Remove() { DeleteAll(); CreatePackage(new AppRef("appref://MyApps/Test1.zip?version=1.2.3.4")); CreatePackage(new AppRef("appref://MyApps/Test2.zip?version=5.6.7.8")); using (var folder = new AppPackageFolder(this, tempFolder)) { AppPackageInfo[] infoArr; infoArr = folder.GetPackages(); Assert.AreEqual(2, infoArr.Length); Assert.IsNotNull(FindFile(infoArr, "myapps.test1-0001.0002.0003.0004.zip")); Assert.IsNotNull(FindFile(infoArr, "myapps.test2-0005.0006.0007.0008.zip")); folder.Remove(new AppRef("appref://MyApps/Test2.zip?version=5.6.7.8")); infoArr = folder.GetPackages(); Assert.AreEqual(1, infoArr.Length); Assert.IsNotNull(FindFile(infoArr, "myapps.test1-0001.0002.0003.0004.zip")); Assert.IsNull(FindFile(infoArr, "myapps.test2-0005.0006.0007.0008.zip")); } }
/// <summary> /// Immediately terminates the processing of all client messages. /// </summary> public void Stop() { if (router == null) { return; } using (TimedLock.Lock(syncLock)) { if (packageFolder != null) { packageFolder.Dispose(); packageFolder = null; } if (bkTimer != null) { bkTimer.Dispose(); bkTimer = null; } if (cluster != null) { cluster.Stop(); cluster = null; } if (router != null) { router.Dispatcher.RemoveTarget(this); router = null; } } }
public void AppPackageFolder_Scan_Two() { DeleteAll(); CreatePackage(new AppRef("appref://MyApps/Test1.zip?version=1.2.3.4")); CreatePackage(new AppRef("appref://MyApps/Test2.zip?version=5.6.7.8")); using (var folder = new AppPackageFolder(this, tempFolder)) { AppPackageInfo[] infoArr; AppPackageInfo info; int size; byte[] md5; infoArr = folder.GetPackages(); Assert.AreEqual(2, infoArr.Length); info = FindFile(infoArr, "myapps.test1-0001.0002.0003.0004.zip"); Assert.IsNotNull(info); Assert.AreEqual("myapps.test1-0001.0002.0003.0004.zip", info.FileName); Assert.AreEqual(tempFolder + "\\myapps.test1-0001.0002.0003.0004.zip", info.FullPath); Assert.AreEqual(new AppRef("appref://MyApps/Test1.zip?version=1.2.3.4"), info.AppRef); GetFileInfo(info.FileName, out size, out md5); Assert.AreEqual(size, info.Size); CollectionAssert.AreEqual(md5, info.MD5); info = FindFile(infoArr, "myapps.test2-0005.0006.0007.0008.zip"); Assert.IsNotNull(info); Assert.AreEqual("myapps.test2-0005.0006.0007.0008.zip", info.FileName); Assert.AreEqual(tempFolder + "\\myapps.test2-0005.0006.0007.0008.zip", info.FullPath); Assert.AreEqual(new AppRef("appref://MyApps/Test2.zip?version=5.6.7.8"), info.AppRef); GetFileInfo(info.FileName, out size, out md5); Assert.AreEqual(size, info.Size); CollectionAssert.AreEqual(md5, info.MD5); } }
public void AppPackageFolder_Transit() { DeleteAll(); using (var folder = new AppPackageFolder(this, tempFolder)) { AppRef appRef; AppPackageInfo[] infoArr; AppPackageInfo info; string path; int size; byte[] md5; Assert.AreEqual(0, folder.GetPackages().Length); appRef = new AppRef("appref://MyApps/Test1.zip?version=1.2.3.4"); path = folder.BeginTransit(appRef); CreatePackageAt(path, appRef); Assert.AreEqual(0, folder.GetPackages().Length); folder.Scan(); infoArr = folder.GetPackages(); Assert.AreEqual(0, folder.GetPackages().Length); folder.EndTransit(path, true); infoArr = folder.GetPackages(); Assert.AreEqual(1, infoArr.Length); info = FindFile(infoArr, "myapps.test1-0001.0002.0003.0004.zip"); Assert.IsNotNull(infoArr); Assert.AreEqual("myapps.test1-0001.0002.0003.0004.zip", info.FileName); Assert.AreEqual(tempFolder + "\\myapps.test1-0001.0002.0003.0004.zip", info.FullPath); Assert.AreEqual(new AppRef("appref://MyApps/Test1.zip?version=1.2.3.4"), info.AppRef); GetFileInfo(info.FileName, out size, out md5); Assert.AreEqual(size, info.Size); CollectionAssert.AreEqual(md5, info.MD5); // Try to overwrite an existing package appRef = new AppRef("appref://MyApps/Test1.zip?version=1.2.3.4"); path = folder.BeginTransit(appRef); CreatePackageAt(path, appRef); folder.EndTransit(path, true); // Try cancelling a commit appRef = new AppRef("appref://MyApps/Test2.zip?version=5.6.7.8"); path = folder.BeginTransit(appRef); CreatePackageAt(path, appRef); folder.EndTransit(path, false); Assert.IsFalse(File.Exists(path)); Assert.IsNull(FindFile(folder.GetPackages(), "myapps.test2-0005.0006.0007.0008.zip")); folder.Scan(); Assert.IsNull(FindFile(folder.GetPackages(), "myapps.test2-0005.0006.0007.0008.zip")); } }
public void AppPackageFolder_Scan_Empty() { DeleteAll(); using (var folder = new AppPackageFolder(this, tempFolder)) { Assert.AreEqual(0, folder.GetPackages().Length); folder.Scan(); Assert.AreEqual(0, folder.GetPackages().Length); } }
public void AppPackageFolder_Detect_Change() { DeleteAll(); CreatePackage(new AppRef("appref://MyApps/Test1.zip?version=1.2.3.4")); CreatePackage(new AppRef("appref://MyApps/Test2.zip?version=5.6.7.8")); using (var folder = new AppPackageFolder(this, tempFolder)) { AppPackageInfo[] infoArr; AppPackageInfo info; int size; byte[] md5; Thread.Sleep(2000); using (var fs = new FileStream(tempFolder + "\\myapps.test1-0001.0002.0003.0004.zip", FileMode.Open, FileAccess.ReadWrite)) { byte b; b = (byte)fs.ReadByte(); fs.Position = 0; fs.WriteByte((byte)~b); fs.Position = 0; fs.WriteByte(b); } Thread.Sleep(changeDetectTime); infoArr = folder.GetPackages(); Assert.AreEqual(2, infoArr.Length); info = FindFile(infoArr, "myapps.test1-0001.0002.0003.0004.zip"); Assert.IsNotNull(info); Assert.AreEqual("myapps.test1-0001.0002.0003.0004.zip", info.FileName); Assert.AreEqual(tempFolder + "\\myapps.test1-0001.0002.0003.0004.zip", info.FullPath); Assert.AreEqual(new AppRef("appref://MyApps/Test1.zip?version=1.2.3.4"), info.AppRef); GetFileInfo(info.FileName, out size, out md5); Assert.AreEqual(size, info.Size); CollectionAssert.AreEqual(md5, info.MD5); info = FindFile(infoArr, "myapps.test2-0005.0006.0007.0008.zip"); Assert.IsNotNull(info); Assert.AreEqual("myapps.test2-0005.0006.0007.0008.zip", info.FileName); Assert.AreEqual(tempFolder + "\\myapps.test2-0005.0006.0007.0008.zip", info.FullPath); Assert.AreEqual(new AppRef("appref://MyApps/Test2.zip?version=5.6.7.8"), info.AppRef); GetFileInfo(info.FileName, out size, out md5); Assert.AreEqual(size, info.Size); CollectionAssert.AreEqual(md5, info.MD5); } }
/// <summary> /// Associates the service handler with a message router by registering /// the necessary application message handlers. /// </summary> /// <param name="router">The message router.</param> /// <param name="keyPrefix">The configuration key prefix or (null to use <b>LillTek.Datacenter.AppStore</b>).</param> /// <param name="perfCounters">The application's performance counter set (or <c>null</c>).</param> /// <param name="perfPrefix">The string to prefix any performance counter names (or <c>null</c>).</param> /// <remarks> /// <para> /// Applications that expose performance counters will pass a non-<c>null</c> <b>perfCounters</b> /// instance. The service handler should add any counters it implements to this set. /// If <paramref name="perfPrefix" /> is not <c>null</c> then any counters added should prefix their /// names with this parameter. /// </para> /// </remarks> public void Start(MsgRouter router, string keyPrefix, PerfCounterSet perfCounters, string perfPrefix) { var config = new Config(keyPrefix != null ? keyPrefix : ConfigPrefix); // Make sure the syncLock is set early. this.syncLock = router.SyncRoot; // Make sure that the LillTek.Datacenter message types have been // registered with the LillTek.Messaging subsystem. LillTek.Datacenter.Global.RegisterMsgTypes(); // Verify the router parameter if (router == null) { throw new ArgumentNullException("router", "Router cannot be null."); } if (this.router != null) { throw new InvalidOperationException("This handler has already been started."); } // General initialization mode = config.Get <AppStoreMode>("Mode", AppStoreMode.Primary); primaryBroadcast = config.Get("PrimaryBroadcast", true); packageScanInterval = config.Get("PackageScanInterval", TimeSpan.FromMinutes(5)); primaryPollInterval = config.Get("PrimaryPollInterval", TimeSpan.FromMinutes(15)); primaryPollTime = SysTime.Now; onTransfer = new AsyncCallback(OnTransfer); downloads = new Dictionary <AppRef, PendingDownload>(); forceSync = false; cDownloads = 0; netFail = false; // Initialize the package folder packageFolder = new AppPackageFolder(syncLock, config.Get("PackageFolder", "Packages")); packageFolder.ChangeEvent += new MethodArg1Invoker(OnPackageFolderChange); packageScanTime = SysTime.Now; // Initialize the performance counters startTime = DateTime.UtcNow; perf = new Perf(perfCounters, perfPrefix); // Crank up the background task timer. bkTimer = new GatedTimer(new TimerCallback(OnBkTimer), null, config.Get("BkTaskInterval", TimeSpan.FromSeconds(1))); try { // Initialize the router this.router = router; // Join the cluster, initializing this instance's state. cluster = new ClusterMember(router, ClusterMemberSettings.LoadConfig(config.KeyPrefix + "Cluster")); cluster["Mode"] = this.mode.ToString(); cluster.ClusterStatusUpdate += new ClusterMemberEventHandler(OnClusterStatusUpdate); cluster.Start(); // Rather than calling cluster.JoinWait() which could take a really long // time, I'm going to sleep for two seconds. There are three scenarios: // // 1. This is the first Application Store instance. // // 2. Other instances are running but they haven't // organized into a cluster. // // 3. A cluster is already running. // // If #1 is the current situation, then it will take a very long time // for JoinWait() to return because we have to go through the entire // missed master broadcast and election periods. Since we're the only // instance, we could have started serving content well before this. // // #2 won't be very common but if it is the case, the worst thing // that will happen is that it will take a while to discover the // primary store. // // If #3 is the case, then two seconds should be long enough for the // master to send the instance a cluster update. Thread.Sleep(2000); // Register the message handlers via the cluster member // so that the endpoint used will be the member's instanceEP. cluster.AddTarget(this, AppStoreHandler.DynamicScope); } catch { if (packageFolder != null) { packageFolder.Dispose(); packageFolder = null; } if (bkTimer != null) { bkTimer.Dispose(); bkTimer = null; } router.Dispatcher.RemoveTarget(this); if (cluster != null) { cluster.Stop(); cluster = null; } throw; } }