Example #1
0
        /// <summary>
        /// Deletes a package from the folder if it is present.
        /// </summary>
        /// <param name="appRef">The package <see cref="AppRef" />.</param>
        public void Remove(AppRef appRef)
        {
            if (isDisposed)
            {
                throw new ObjectDisposedException(typeof(AppPackageFolder).Name);
            }

            AppPackageInfo info;
            bool           deleted = false;

            using (TimedLock.Lock(syncLock))
            {
                if (packages.TryGetValue(appRef, out info))
                {
                    try
                    {
                        fileWatcher.EnableRaisingEvents = false;
                        File.Delete(info.FullPath);
                        packages.Remove(appRef);
                        deleted = true;
                    }
                    finally
                    {
                        fileWatcher.EnableRaisingEvents = true;
                    }
                }
            }

            if (deleted)
            {
                RaiseChangeEvent();
            }
        }
Example #2
0
        /// <summary>
        /// Removes a specific application package on an application store.
        /// </summary>
        /// <param name="storeEP">
        /// The application store endpoint or <c>null</c> to query any
        /// application store instance in the cluster.
        /// </param>
        /// <param name="appRef">The <see cref="AppRef" /> specifying the package to be removed.</param>
        public void RemoveRemotePackage(MsgEP storeEP, AppRef appRef)
        {
            if (storeEP == null)
            {
                storeEP = settings.ClusterEP;
            }

            router.Query(storeEP, new AppStoreQuery(AppStoreQuery.RemoveCmd, appRef));
        }
Example #3
0
        /// <summary>
        /// Returns <c>true</c> if the <see cref="AppRef" /> object passed equals
        /// this instance.
        /// </summary>
        /// <param name="obj">The object to test.</param>
        /// <returns><c>true</c> if the two objects are equal.</returns>
        public override bool Equals(object obj)
        {
            AppRef appRef = obj as AppRef;

            if (appRef == null)
            {
                return(false);
            }

            return(String.Compare(this.uri, appRef.uri, true) == 0);
        }
Example #4
0
        /// <summary>
        /// Returns the requested <see cref="AppPackage" /> from the local cache opened for read access,
        /// optionally querying an application store service if the package is not available locally.
        /// </summary>
        /// <param name="storeEP">
        /// The application store endpoint or <c>null</c> to query any
        /// application store instance in the cluster.
        /// </param>
        /// <param name="appRef">The <see cref="AppRef" /> identifing the desired application package.</param>
        /// <param name="queryStore">
        /// Pass <c>true</c> if an application store is to be queried if the package
        /// is not cached locally.
        /// </param>
        /// <returns></returns>
        /// <exception cref="ObjectDisposedException">Thrown if the cache is not open.</exception>
        /// <exception cref="InvalidOperationException">Thrown if local package caching is disabled.</exception>
        /// <exception cref="AppPackageException">Thrown if the package cannot be found.</exception>
        public AppPackage GetPackage(MsgEP storeEP, AppRef appRef, bool queryStore)
        {
            AppPackageInfo info;
            string         transitPath;

            if (storeEP == null)
            {
                storeEP = settings.ClusterEP;
            }

            using (TimedLock.Lock(syncLock))
            {
                VerifyOpen();
                VerifyLocal();

                info = packageFolder.GetPackageInfo(appRef);
                if (info != null)
                {
                    return(AppPackage.Open(info.FullPath));
                }
            }

            // $hack(jeff.lill):
            //
            // The code below isn't strictly threadsafe
            // but should exhibit problems only when
            // closing the client under load so I'm
            // not going to worry about this right now.

            // Download the package from an application store.

            transitPath = packageFolder.BeginTransit(appRef);
            try
            {
                DownloadPackage(null, appRef, transitPath);
                packageFolder.EndTransit(transitPath, true);
            }
            catch
            {
                packageFolder.EndTransit(transitPath, false);
                throw;
            }

            info = packageFolder.GetPackageInfo(appRef);
            if (info == null)
            {
                throw new AppPackageException("Package [{0}] not found.", appRef);
            }

            return(AppPackage.Open(info.FullPath));
        }
Example #5
0
        /// <summary>
        /// Initiates the loading of an application package file into the folder.
        /// </summary>
        /// <param name="appRef">The new application package's <see cref="AppRef" />.</param>
        /// <returns>The fully qualified path to where the new package should be written.</returns>
        public string BeginTransit(AppRef appRef)
        {
            string path;

            if (isDisposed)
            {
                throw new ObjectDisposedException(typeof(AppPackageFolder).Name);
            }

            path = transitFolder + appRef.FileName;
            Helper.CreateFileTree(path);

            return(path);
        }
Example #6
0
        /// <summary>
        /// Uploads an application package to a remote application store instance.
        /// </summary>
        /// <param name="storeEP">
        /// The application store endpoint or <c>null</c> to query any
        /// application store instance in the cluster.
        /// </param>
        /// <param name="appRef">The <see cref="AppRef" /> for the file.</param>
        /// <param name="path">The path to the application package file.</param>
        public void UploadPackage(MsgEP storeEP, AppRef appRef, string path)
        {
            StreamTransferSession session;

            if (storeEP == null)
            {
                storeEP = settings.ClusterEP;
            }

            session      = StreamTransferSession.ClientUpload(router, storeEP, path);
            session.Args = "appref=" + appRef.ToString();

            session.Transfer();
        }
Example #7
0
        /// <summary>
        /// Determines if a specific <see cref="AppPackage" /> is present in the local cache.
        /// </summary>
        /// <param name="appRef">The <see cref="AppRef" /> identifing the desired application package.</param>
        /// <returns><c>true</c> if the application package is present.</returns>
        /// <exception cref="ObjectDisposedException">Thrown if the cache is not open.</exception>
        /// <exception cref="InvalidOperationException">Thrown if local package caching is disabled.</exception>
        public bool IsCached(AppRef appRef)
        {
            using (TimedLock.Lock(syncLock))
            {
                VerifyOpen();
                VerifyLocal();

                if (packageFolder == null)
                {
                    return(false);
                }

                return(packageFolder.GetPackageInfo(appRef) != null);
            }
        }
Example #8
0
        /// <summary>
        /// Private read constructor.
        /// </summary>
        /// <param name="path">The package path on the file system.</param>
        private AppPackage(string path)
        {
            this.path       = path;
            this.readMode   = true;
            this.zipArchive = new ZipFile(path);
            this.zipOutput  = null;
            this.md5Hash    = null;

            // Load the "Package.ini" file from the archive.

            if (!ContainsFile("Package.ini"))
            {
                throw new FormatException("Application package cannot be opened. Package.ini file is missing.");
            }

            StreamReader reader = null;
            MemoryStream ms;
            string       v;

            try
            {
                ms = new MemoryStream();
                CopyFile("Package.ini", ms);
                ms.Position = 0;
                reader      = new StreamReader(ms);

                settings = new Config(ConfigPrefix, reader);

                v = settings.Get("AppRef");
                if (v == null)
                {
                    throw new FormatException("[AppRef] property is missing in the application package metadata.");
                }
                else
                {
                    appRef = new AppRef(v);
                }
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
            }
        }
Example #9
0
        /// <summary>
        /// Downloads an application package from a remote application store instance.
        /// </summary>
        /// <param name="storeEP">
        /// The application store endpoint or <c>null</c> to query any
        /// application store instance in the cluster.
        /// </param>
        /// <param name="appRef">The <see cref="AppRef" /> for the file.</param>
        /// <param name="path">The path to the output application package file.</param>
        public void DownloadPackage(MsgEP storeEP, AppRef appRef, string path)
        {
            StreamTransferSession session;
            AppStoreAck           ack;

            if (storeEP == null)
            {
                storeEP = settings.ClusterEP;
            }

            ack     = (AppStoreAck)router.Query(storeEP, new AppStoreQuery(AppStoreQuery.DownloadCmd, appRef));
            storeEP = ack.StoreEP;

            session      = StreamTransferSession.ClientDownload(router, storeEP, path);
            session.Args = "appref=" + appRef.ToString();

            session.Transfer();
        }
Example #10
0
        /// <summary>
        /// Returns information about a specific application package if it's present
        /// in the package folder.
        /// </summary>
        /// <param name="appRef">The application package <see cref="AppRef" />.</param>
        /// <returns>The package information or <c>null</c>.</returns>
        public AppPackageInfo GetPackageInfo(AppRef appRef)
        {
            if (isDisposed)
            {
                throw new ObjectDisposedException(typeof(AppPackageFolder).Name);
            }

            using (TimedLock.Lock(syncLock))
            {
                AppPackageInfo info;

                if (packages.TryGetValue(appRef, out info))
                {
                    return(info);
                }
                else
                {
                    return(null);
                }
            }
        }
Example #11
0
 /// <summary>
 /// Returns the requested <see cref="AppPackage" /> from the local cache opened for read access.
 /// </summary>
 /// <param name="storeEP">
 /// The application store endpoint or <c>null</c> to query any
 /// application store instance in the cluster.
 /// </param>
 /// <param name="appRef">The <see cref="AppRef" /> identifing the desired application package.</param>
 /// <returns>The open <see cref="AppPackage" />.</returns>
 /// <exception cref="ObjectDisposedException">Thrown if the cache is not open.</exception>
 /// <remarks>
 /// <para>
 /// This method first looks in the local <see cref="AppPackageFolder" /> cache for the
 /// requested package.  If the package is not present locally, then the package will
 /// be requested from an application store service instance.  If the application
 /// store returns a package, it will be added to the local package folder and
 /// an open <see cref="AppPackage" /> will be returned.
 /// </para>
 /// <note>
 /// Some care should be taken to ensure that the <see cref="AppPackage" />
 /// instances returned are promptly disposed when they are no longer needed.
 /// </note>
 /// </remarks>
 /// <exception cref="ObjectDisposedException">Thrown if the cache is not open.</exception>
 /// <exception cref="InvalidOperationException">Thrown if local package caching is disabled.</exception>
 /// <exception cref="AppPackageException">Thrown if the package cannot be found.</exception>
 public AppPackage GetPackage(MsgEP storeEP, AppRef appRef)
 {
     return(GetPackage(storeEP, appRef, true));
 }
Example #12
0
        /// <summary>
        /// Private create constructor.
        /// </summary>
        /// <param name="path">The package path on the file system.</param>
        /// <param name="appRef">The package's <see cref="AppRef" />.</param>
        /// <param name="settings">The package metadata settings (or <c>null</c>).</param>
        /// <remarks>
        /// <note>
        /// No <b>Package.ini</b> entry will be created if <paramref name="settings" />
        /// is passed as <c>null</c>.
        /// </note>
        /// </remarks>
        private AppPackage(string path, AppRef appRef, ArgCollection settings)
        {
            this.path       = path;
            this.readMode   = false;
            this.appRef     = appRef;
            this.zipArchive = null;
            this.settings   = null;
            this.md5Hash    = null;

            // Create the archive

            Helper.CreateFileTree(path);
            if (File.Exists(path))
            {
                File.Delete(path);
            }

            zipOutput = new ZipOutputStream(new FileStream(path, FileMode.Create, FileAccess.ReadWrite));
            zipOutput.SetLevel(9);

            if (settings != null)
            {
                // Generate the Package.ini file and save it to the archive.

                StreamWriter writer;
                MemoryStream ms;
                ZipEntry     entry;
                DateTime     utcNow;

                utcNow = DateTime.UtcNow;
                ms     = new MemoryStream();
                writer = new StreamWriter(ms);

                try
                {
                    writer.WriteLine("// Application Package Metadata");
                    writer.WriteLine("//");
                    writer.WriteLine("// Generated by: {0} v{1}", Path.GetFileName(Helper.GetAssemblyPath(Assembly.GetExecutingAssembly())), Helper.GetVersion(Assembly.GetExecutingAssembly()));
                    writer.WriteLine("// Create Date:  {0}", Helper.ToInternetDate(utcNow));
                    writer.WriteLine();

                    writer.WriteLine("#section AppPackage");
                    writer.WriteLine();
                    writer.WriteLine("    appref = {0}", appRef.ToString());

                    foreach (string key in settings)
                    {
                        writer.WriteLine("    {0} = {1}", key, settings[key]);
                    }

                    writer.WriteLine();
                    writer.WriteLine("#endsection");
                    writer.WriteLine();
                    writer.Flush();

                    entry          = new ZipEntry("Package.ini");
                    entry.DateTime = utcNow;
                    zipOutput.PutNextEntry(entry);
                    zipOutput.Write(ms.GetBuffer(), 0, (int)ms.Length);
                }
                finally
                {
                    writer.Close();
                }
            }
        }
Example #13
0
 /// <summary>
 /// Opens an <see cref="AppPackage" /> for writing, overwritting
 /// any existing package file.
 /// </summary>
 /// <param name="path">File system path to the package.</param>
 /// <param name="appRef">The package's <see cref="AppRef" />.</param>
 /// <param name="settings">The fully qualified package metadata settings.</param>
 /// <remarks>
 /// <note>
 /// The standard arguments passed in the <paramref name="settings" /> parameter
 /// must include the leading <b>"AppPackage.</b> prefix.
 /// </note>
 /// </remarks>
 public static AppPackage Create(string path, AppRef appRef, ArgCollection settings)
 {
     return(new AppPackage(path, appRef, settings));
 }