Example #1
0
        public void OnMsg(ReliableTransferMsg msg)
        {
            if (netFail)
            {
                return;
            }

            StreamTransferSession session;
            ArgCollection         args;
            AppRef         appRef;
            AppPackageInfo packageInfo;
            string         path;

            args   = ArgCollection.Parse(msg.Args);
            appRef = AppRef.Parse(args["appref"]);

            if (msg.Direction == TransferDirection.Upload)
            {
                path    = packageFolder.BeginTransit(appRef);
                session = StreamTransferSession.ServerUpload(router, msg, path);
                session.BeginTransfer(onTransfer, new TransferInfo(session, path, msg.Direction));
            }
            else
            {
                packageInfo = packageFolder.GetPackageInfo(appRef);
                if (packageInfo == null)
                {
                    throw SessionException.Create(null, "Package [{0}] cannot be found.", appRef);
                }

                path    = packageInfo.FullPath;
                session = StreamTransferSession.ServerDownload(router, msg, path);
                session.BeginTransfer(onTransfer, new TransferInfo(session, path, msg.Direction));
            }
        }
Example #2
0
        public void AppStoreMsgs_Ack()
        {
            EnhancedStream es = new EnhancedMemoryStream();

            AppPackageInfo[] packages = new AppPackageInfo[] {
                new AppPackageInfo(AppRef.Parse("appref://myapps/app01.zip?version=1.2.3.4"), "app01.zip", "", new byte[] { 0, 1, 2 }, 55, DateTime.MinValue),
                new AppPackageInfo(AppRef.Parse("appref://myapps/app02.zip?version=5.6.7.8"), "app02.zip", "", new byte[] { 3, 4, 5 }, 66, DateTime.MinValue)
            };

            AppStoreAck msgIn, msgOut;

            msgOut          = new AppStoreAck();
            msgOut.StoreEP  = "logical://foo/bar";
            msgOut.Packages = packages;

            Msg.Save(es, msgOut);
            es.Position = 0;
            msgIn       = (AppStoreAck)Msg.Load(es);

            Assert.IsNotNull(msgIn);
            Assert.AreEqual("logical://foo/bar", msgIn.StoreEP);

            Assert.AreEqual(2, msgIn.Packages.Length);

            Assert.AreEqual(AppRef.Parse("appref://myapps/app01.zip?version=1.2.3.4"), msgIn.Packages[0].AppRef);
            CollectionAssert.AreEqual(new byte[] { 0, 1, 2 }, msgIn.Packages[0].MD5);
            Assert.AreEqual(55, msgIn.Packages[0].Size);

            Assert.AreEqual(AppRef.Parse("appref://myapps/app02.zip?version=5.6.7.8"), msgIn.Packages[1].AppRef);
            CollectionAssert.AreEqual(new byte[] { 3, 4, 5 }, msgIn.Packages[1].MD5);
            Assert.AreEqual(66, msgIn.Packages[1].Size);
        }
Example #3
0
        public void AppPackage_MultiRead()
        {
            // Verify that a package can be opened for reading by multiple streams.

            string       tempPath = GetTempFileName();
            string       tempDir  = Helper.AddTrailingSlash(Path.GetTempPath());
            AppRef       appRef   = AppRef.Parse("appref://myapps/mypackage.zip?version=1.2.3.4");
            AppPackage   pack1    = null;
            AppPackage   pack2    = null;
            FileStream   fs       = null;
            MemoryStream ms;

            try
            {
                pack1 = AppPackage.Create(tempPath, appRef, @"
LaunchType   = Test.MyType:MyAssembly.dll;
LaunchMethod = Foo;
LaunchArgs   = Bar;
");
                using (ms = new MemoryStream(4096))
                {
                    for (int i = 0; i < 4096; i++)
                    {
                        ms.WriteByte((byte)i);
                    }

                    ms.Position = 0;
                    pack1.AddFile("Test.dat", ms);
                }

                pack1.Close();
                pack1 = null;

                pack1 = AppPackage.Open(tempPath);
                pack2 = AppPackage.Open(tempPath);
                fs    = new FileStream(tempPath, FileMode.Open, FileAccess.Read);
            }
            finally
            {
                if (pack1 != null)
                {
                    pack1.Close();
                }

                if (pack2 != null)
                {
                    pack2.Close();
                }

                if (fs != null)
                {
                    fs.Close();
                }

                Delete(tempPath);
            }
        }
Example #4
0
        public void AppPackage_MD5()
        {
            string       tempPath = GetTempFileName();
            string       tempDir  = Helper.AddTrailingSlash(Path.GetTempPath());
            AppPackage   package  = null;
            MemoryStream ms;

            byte[] md5;

            try
            {
                package = AppPackage.Create(tempPath, AppRef.Parse("appref://myapps/mypackage.zip?version=1.2.3.4"), @"
LaunchType   = Test.MyType:MyAssembly.dll;
LaunchMethod = Foo;
LaunchArgs   = Bar;
");
                using (ms = new MemoryStream(4096))
                {
                    for (int i = 0; i < 4096; i++)
                    {
                        ms.WriteByte((byte)i);
                    }

                    ms.Position = 0;
                    package.AddFile("Test.dat", ms);
                }

                package.Close();
                package = null;

                // Verify that a MD5 hash computed manually on the package file jibes
                // with what AppPackage computes.

                using (var fs = new EnhancedFileStream(tempPath, FileMode.Open, FileAccess.Read))
                {
                    md5 = MD5Hasher.Compute(fs, fs.Length);
                }

                package = AppPackage.Open(tempPath);
                CollectionAssert.AreEqual(md5, package.MD5);

                package.Close();
                package = null;
            }
            finally
            {
                if (package != null)
                {
                    package.Close();
                }

                Delete(tempPath);
            }
        }
Example #5
0
        public void AppStoreMsgs_Query()
        {
            EnhancedStream es = new EnhancedMemoryStream();
            AppStoreQuery  msgIn, msgOut;

            msgOut = new AppStoreQuery(AppStoreQuery.GetPrimaryCmd, AppRef.Parse("appref://myapps/theapp.zip?version=1.2.3.4"));

            Msg.Save(es, msgOut);
            es.Position = 0;
            msgIn       = (AppStoreQuery)Msg.Load(es);

            Assert.IsNotNull(msgIn);
            Assert.AreEqual(AppStoreQuery.GetPrimaryCmd, msgIn.Command);
            Assert.AreEqual(AppRef.Parse("appref://myapps/theapp.zip?version=1.2.3.4"), msgIn.AppRef);
        }
Example #6
0
        public void AppPackage_ExtractTo()
        {
            string     tempPath = GetTempFileName();
            string     tempDir  = Helper.AddTrailingSlash(Path.GetTempPath());
            AppPackage package  = null;

            try
            {
                package = AppPackage.Create(tempPath, AppRef.Parse("appref://myapps/mypackage.zip?version=1.2.3.4"), @"
LaunchType   = Test.MyType:MyAssembly.dll;
LaunchMethod = Foo;
LaunchArgs   = Bar;
");
                package.AddFile("File1.txt", Helper.ToUTF8("Hello World! #1\r\n"));
                package.AddFile("File2.txt", Helper.ToUTF8("Hello World! #2\r\n"));
                package.Close();
                package = null;

                package = AppPackage.Open(tempPath);
                package.ExtractTo(tempDir);
                package.Close();
                package = null;

                Assert.IsTrue(File.Exists(tempDir + "Package.ini"));
                Assert.IsTrue(File.Exists(tempDir + "File1.txt"));
                Assert.IsTrue(File.Exists(tempDir + "File2.txt"));

                using (var reader = new StreamReader(tempDir + "File1.txt"))
                {
                    Assert.AreEqual("Hello World! #1", reader.ReadLine());
                }

                using (var reader = new StreamReader(tempDir + "File2.txt"))
                {
                    Assert.AreEqual("Hello World! #2", reader.ReadLine());
                }
            }
            finally
            {
                if (package != null)
                {
                    package.Close();
                }

                Delete(tempPath);
            }
        }
Example #7
0
        public void AppRef_Basic()
        {
            AppRef appRef;

            appRef = AppRef.Parse("appref://jeff/code/mycode.zip?version=1.2.3.4");
            Assert.AreEqual("appref://jeff/code/mycode.zip?version=1.2.3.4", appRef.ToString());
            Assert.AreEqual(new Uri("appref://jeff/code/mycode.zip?version=1.2.3.4"), appRef.Uri);
            Assert.AreEqual("jeff.code.mycode-0001.0002.0003.0004.zip", appRef.FileName);
            Assert.AreEqual(new Version(1, 2, 3, 4), appRef.Version);
            Assert.AreEqual("appref://jeff/code/mycode.zip?version=1.2.3.4", appRef.ToString());

            appRef = AppRef.Parse("APPREF://JEFF/CODE/MYCODE.ZIP?VERSION=1.2&extra=param");
            Assert.AreEqual("appref://jeff/code/mycode.zip?version=1.2", appRef.ToString());
            Assert.AreEqual(new Uri("appref://jeff/code/mycode.zip?version=1.2"), appRef.Uri);
            Assert.AreEqual("jeff.code.mycode-0001.0002.-1.-1.zip", appRef.FileName);
            Assert.AreEqual(new Version(1, 2), appRef.Version);
            Assert.AreEqual("appref://jeff/code/mycode.zip?version=1.2", appRef.ToString());
        }
Example #8
0
        public void AppStore_EndToEnd()
        {
            // This test peforms a simple end-to-end test of the AppStore
            // service by starting the service, uploading, downloading
            // and then deleting a package file.

            Process        svcProcess = null;
            LeafRouter     router     = null;
            AppStoreClient client     = null;
            Assembly       assembly;
            string         packageFolder;
            string         tempFolder;
            AppRef         appRef;

            Helper.InitializeApp(Assembly.GetExecutingAssembly());

            assembly      = typeof(LillTek.Datacenter.AppStore.Program).Assembly;
            tempFolder    = Helper.AddTrailingSlash(Path.GetTempPath());
            packageFolder = Helper.GetAssemblyFolder(assembly) + "packages\\";
            appRef        = AppRef.Parse("appref://MyApps/App00.zip?version=1.2.0.0");

            try
            {
                // Start a local router and open a client.

                Config.SetConfig(@"

//-----------------------------------------------------------------------------
// LeafRouter Settings

&section MsgRouter

    AppName                = LillTek.Test Router
    AppDescription         = Unit Test
    RouterEP			   = physical://DETACHED/$(LillTek.DC.DefHubName)/$(Guid)
    CloudEP                = $(LillTek.DC.CloudEP)
    CloudAdapter           = ANY
    UdpEP				   = ANY:0
    TcpEP				   = ANY:0
    TcpBacklog			   = 100
    TcpDelay			   = off
    BkInterval			   = 1s
    MaxIdle				   = 5m
    EnableP2P              = yes
    AdvertiseTime		   = 1m
    DefMsgTTL			   = 5
    Encryption		       = PLAINTEXT
    Key					   = 00
    SessionCacheTime       = 2m
    SessionRetries         = 3
    SessionTimeout         = 10s
    MaxLogicalAdvertiseEPs = 256
    DeadRouterTTL          = 2s
    
    // This maps the abstract AppStore endpoints to their default logical endpoints.

    AbstractMap[abstract://LillTek/DataCenter/AppStore]   = logical://LillTek/DataCenter/AppStore
    AbstractMap[abstract://LillTek/DataCenter/AppStore/*] = logical://LillTek/DataCenter/AppStore/*

&endsection

".Replace('&', '#'));

                router = new LeafRouter();
                router.Start();

                client = new AppStoreClient();
                client.Open(router, AppStoreClientSettings.LoadConfig("AppStore.Client"));

                // Start the application store service

                svcProcess = Helper.StartProcess(assembly, "-mode:form -start");
                Thread.Sleep(10000);    // Give the process a chance to spin up

                // Upload a package to the server

                CreatePackage(tempFolder, appRef);
                client.UploadPackage(null, appRef, tempFolder + appRef.FileName);
                Thread.Sleep(1000);
                CompareFiles(tempFolder + appRef.FileName, packageFolder + appRef.FileName);

                // Download the package

                File.Delete(tempFolder + appRef.FileName);
                client.DownloadPackage(null, appRef, tempFolder + appRef.FileName);
                Thread.Sleep(1000);
                CompareFiles(tempFolder + appRef.FileName, packageFolder + appRef.FileName);

                // Delete the package

                client.RemoveRemotePackage(null, appRef);
                Thread.Sleep(1000);
                Assert.IsFalse(File.Exists(packageFolder + appRef.FileName));
            }
            finally
            {
                if (svcProcess != null)
                {
                    svcProcess.Kill();
                    svcProcess.Close();
                }

                if (client != null)
                {
                    client.Close();
                }

                if (router != null)
                {
                    router.Stop();
                }

                if (File.Exists(tempFolder + appRef.FileName))
                {
                    File.Delete(tempFolder + appRef.FileName);
                }

                Config.SetConfig(null);
            }
        }
Example #9
0
        /// <summary>
        /// Executes the specified PACK command.
        /// </summary>
        /// <param name="args">The command arguments.</param>
        /// <returns>0 on success, a non-zero error code otherwise.</returns>
        public static int Execute(string[] args)
        {
            const string usage =
                @"
Usage: 

-------------------------------------------------------------------------------
vegomatic pack [-r] [-out:<path>] <appref> <path-0> <path-1>... <path-N>

Creates an application package from a set of assembly and data files.

    -r          Indicates that subfolders are to be searched
                recursively for files to be added to the 
                archive.

    -out:path   Specifies where the generated packaged file is
                to be written.  If this specifies a folder then
                the package will be named using the standard
                package file naming convention in that folder.
                If this option is not present, then the package
                will be saved in the current folder using the
                standard name.

    <appref>    The application reference to be used for this package.
                See the note below describing how the version number
                can be loaded from an assembly.

    <path-#>    Path of the files or directories to be added to
                the archive.  File specifications may include
                wildcards.

AppRef Format
-------------

Application references are URIs formatted as:

    appref://Root/Segment0/Segment1/../SegmentN.zip?version=1.2.3.4

where the Root and Segment#s uniquely identify the application
and the version query parameter specifies the version number.
Note that vegomatic supports a specialized notation for apprefs
that indicate that the version should be loaded from an assembly's
version number rather than being specified directly on the command
line.  This can make it easy to automate the creation of application
packages during the build process.

To accomplish this, set the version to an ""@"" followed by the
path to the assembly file.  Here's an example:

    vegomatic pack appref://myapps/[email protected]

In this case, vegomatic will load myassembly.dll from the current folder
and use the assembly's version number when creating the package.

Package.ini File
----------------

One of the files that must be included in all applications is the
PACKAGE.INI file.  This is a text file formatted using the standard
LillTek Platform config conventions that describes the metadata
to be associated with the package.  One required setting is the
APPREF setting which should be set to the same appref value
specified on the command line.  This can be accomplished via
the $(appref) macro as in:

    AppRef = $(appref)

Vegomatic will replace this macro with the appref specified on
the command line before adding the PACKAGE.INI file to the
package.
";
            AppPackage package   = null;
            bool       recursive = false;
            string     outPath   = null;
            string     sAppRef;
            AppRef     appRef;
            int        argPos;
            int        cAdded;
            bool       packageIni;

            if (args.Length < 2)
            {
                Program.Error(usage);
                return(1);
            }

            for (argPos = 0; argPos < args.Length; argPos++)
            {
                string arg = args[argPos];

                if (!arg.StartsWith("-"))
                {
                    break;
                }
                else if (arg == "-r")
                {
                    recursive = true;
                }
                else if (arg.StartsWith("-out:"))
                {
                    outPath = arg.Substring(5);
                }
                else
                {
                    Program.Error(usage);
                    return(1);
                }
            }

            // Parse the application reference, reading the version number
            // from the referenced assembly file if requested.

            // $todo(jeff.lill):
            //
            // The version parsing code is really simplistic.
            // It assumes that "version" is the only possible
            // query parameter or than it appears first in
            // the appref URI.

            string assemblyPath;
            string appName;
            int    pos;

            sAppRef = args[argPos++];
            pos     = sAppRef.ToLowerInvariant().IndexOf("?version=@");

            if (pos == -1)
            {
                appRef = AppRef.Parse(sAppRef);
            }
            else
            {
                appName      = sAppRef.Substring(0, pos);
                assemblyPath = sAppRef.Substring(pos + 10);
                appRef       = AppRef.Parse(appName + "?version=" + Helper.GetVersion(Assembly.ReflectionOnlyLoadFrom(assemblyPath)).ToString());
            }

            if (outPath == null)
            {
                outPath = appRef.FileName;
            }
            else if (Directory.Exists(outPath))
            {
                outPath = Helper.AddTrailingSlash(outPath) + appRef.FileName;
            }

            if (argPos == args.Length)
            {
                Program.Error(usage);
                return(1);
            }

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

            package    = AppPackage.Create(outPath, appRef, null);
            cAdded     = 0;
            packageIni = false;

            try
            {
                for (; argPos < args.Length; argPos++)
                {
                    string path = args[argPos];
                    bool   hasWildcards;
                    bool   isFolder;
                    string basePath;

                    hasWildcards = path.IndexOfAny(Helper.FileWildcards) != -1;
                    if (!hasWildcards)
                    {
                        isFolder = (File.GetAttributes(path) & FileAttributes.Directory) != 0;
                    }
                    else
                    {
                        isFolder = false;
                    }

                    basePath = Path.GetFullPath(path.Replace('?', 'x').Replace('*', 'x'));
                    pos      = basePath.LastIndexOf(Helper.PathSepChar);
                    if (pos == -1)
                    {
                        throw new Exception(string.Format("Invalid file path [{0}].", path));
                    }

                    basePath = basePath.Substring(0, pos);

                    if (isFolder)
                    {
                        Program.Output("Adding: {0}", path);
                        foreach (string file in Helper.GetFilesByPattern(path + Helper.PathSepString + "*.*", SearchOption.AllDirectories))
                        {
                            if (String.Compare(outPath, file, true) == 0)
                            {
                                continue;   // Ignore the zip archive being created
                            }
                            Program.Output("Adding: {0}", file);
                            packageIni = AddFile(package, file, basePath) || packageIni;
                            cAdded++;
                        }
                    }
                    else
                    {
                        foreach (string file in Helper.GetFilesByPattern(path, recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
                        {
                            if (String.Compare(outPath, file, true) == 0)
                            {
                                continue;   // Ignore the zip archive being created
                            }
                            Program.Output("Adding: {0}", file);
                            packageIni = AddFile(package, file, basePath) || packageIni;
                            cAdded++;
                        }
                    }
                }

                package.Close();

                if (!packageIni)
                {
                    throw new Exception("PACKAGE.INI file with the package metadata is missing.");
                }
            }
            catch (Exception e)
            {
                Program.Error("{0}: {1}", e.GetType().Name, e.Message);
            }
            finally
            {
                if (package != null)
                {
                    package.Close();
                }
            }

            Program.Output("");
            Program.Output("[{0}] files added.", cAdded);

            return(0);
        }
Example #10
0
        public void AppPackage_Basic()
        {
            string       tempPath = GetTempFileName();
            string       tempDir  = Helper.AddTrailingSlash(Path.GetTempPath());
            string       testPath = tempDir + "Test.txt";
            AppPackage   package  = null;
            MemoryStream ms;
            StreamReader reader;

            try
            {
                // Generate the package

                package = AppPackage.Create(tempPath, AppRef.Parse("appref://myapps/mypackage.zip?version=1.2.3.4"), @"
LaunchType   = Test.MyType:MyAssembly.dll;
LaunchMethod = Foo;
LaunchArgs   = Bar;
");

                using (StreamWriter writer = new StreamWriter(testPath))
                {
                    for (int i = 0; i < 4000; i++)
                    {
                        writer.WriteLine("Hello World!");
                    }
                }

                package.AddFile(testPath, tempDir);

                using (ms = new MemoryStream(4096))
                {
                    for (int i = 0; i < 4096; i++)
                    {
                        ms.WriteByte((byte)i);
                    }

                    ms.Position = 0;
                    package.AddFile("Test.dat", ms);
                }

                package.Close();
                package = null;

                // Verify that the package can be opened and the contents look good.

                package = AppPackage.Open(tempPath);

                Assert.AreEqual(new AppRef("appref://myapps/mypackage.zip?version=1.2.3.4"), package.AppRef);
                Assert.AreEqual(new Version(1, 2, 3, 4), package.Version);

                Assert.AreEqual("Test.MyType:MyAssembly.dll", package.Settings.Get("LaunchType"));
                Assert.AreEqual("Foo", package.Settings.Get("LaunchMethod"));
                Assert.AreEqual("Bar", package.Settings.Get("LaunchArgs"));

                Assert.IsTrue(package.ContainsFile("Test.txt"));
                Assert.IsTrue(package.ContainsFile("Test.dat"));

                ms = new MemoryStream();
                package.CopyFile("Test.txt", ms);
                ms.Position = 0;
                reader      = new StreamReader(ms);
                for (int i = 0; i < 4000; i++)
                {
                    Assert.AreEqual("Hello World!", reader.ReadLine());
                }

                string tempPath2 = Path.GetTempFileName();

                try
                {
                    using (var fs = new FileStream(tempPath2, FileMode.Create, FileAccess.ReadWrite))
                    {
                        package.CopyFile("test.dat", fs);
                        Assert.AreEqual(4096, fs.Length);
                        fs.Position = 0;

                        for (int i = 0; i < 4096; i++)
                        {
                            Assert.AreEqual((byte)i, fs.ReadByte());
                        }
                    }
                }
                finally
                {
                    File.Delete(tempPath2);
                }

                package.Close();
                package = null;
            }
            finally
            {
                if (package != null)
                {
                    package.Close();
                }

                Delete(tempPath);
                Delete(testPath);
            }
        }