Пример #1
0
        public void ParallelQuerySession_WaitAll_SingleError()
        {
            // Test a single error query just to make sure it actually works.

            try
            {
                router = new LeafRouter();
                router.Start();
                router.Dispatcher.AddTarget(this);

                Thread.Sleep(1000);

                var parallelQuery = new ParallelQuery();
                var queryMsg1     = new PropertyMsg();

                queryMsg1["cmd"]   = "error";
                queryMsg1["value"] = "1";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg1));

                router.ParallelQuery(parallelQuery);

                Assert.IsNotNull(parallelQuery.Operations[0].Error);
            }
            finally
            {
                if (router != null)
                {
                    router.Stop();
                    router = null;
                }

                Config.SetConfig(null);
            }
        }
Пример #2
0
        public void StreamTransferSession_Upload_Sync()
        {
            StreamTransferSession clientSession;
            LeafRouter            router;

            InitServer();

            router = null;
            try
            {
                SetConfig("DefBlockSize=1000");

                router = new LeafRouter();
                router.Start();
                router.Dispatcher.AddTarget(this);

                clientSession      = StreamTransferSession.ClientUpload(router, "logical://Test/Upload", CreateStream(TransferSize));
                clientSession.Args = "Upload";
                clientSession.Transfer();

                Verify(msServer, TransferSize);
                Assert.IsTrue(serverNotify);
                Assert.IsNull(serverException);
                Assert.AreEqual("Upload", serverArgs);
            }
            finally
            {
                if (router != null)
                {
                    router.Stop();
                }

                Config.SetConfig(null);
            }
        }
Пример #3
0
        public void StreamTransferSession_Upload_Async()
        {
            StreamTransferSession clientSession;
            LeafRouter            router;

            InitServer();

            router = null;
            try
            {
                SetConfig("DefBlockSize=1000");

                router = new LeafRouter();
                router.Start();
                router.Dispatcher.AddTarget(this);

                clientSession = StreamTransferSession.ClientUpload(router, "logical://Test/Upload", CreateStream(TransferSize));
                clientSession.BeginTransfer(new AsyncCallback(OnClientDone), clientSession);
                clientWait.WaitOne(TimeSpan.FromSeconds(30), false);

                Verify(msServer, TransferSize);
                Assert.IsTrue(serverNotify);
                Assert.IsNull(serverException);
            }
            finally
            {
                if (router != null)
                {
                    router.Stop();
                }

                Config.SetConfig(null);
            }
        }
Пример #4
0
        private LeafRouter CreateLeaf(string root, string hub, string name, string cloudEP)
        {
            const string settings =
                @"
MsgRouter.AppName               = Test
MsgRouter.AppDescription        = Test Description
MsgRouter.RouterEP				= physical://{0}/{1}/{2}
MsgRouter.DiscoveryMode         = MULTICAST
MsgRouter.CloudEP               = {3}
MsgRouter.CloudAdapter          = ANY
MsgRouter.UdpEP					= ANY:0
MsgRouter.TcpEP					= ANY:0
MsgRouter.TcpBacklog			= 100
MsgRouter.TcpDelay				= off
MsgRouter.BkInterval			= 1s
MsgRouter.MaxIdle				= 5m
MsgRouter.EnableP2P             = yes
MsgRouter.AdvertiseTime			= 1m
MsgRouter.DefMsgTTL				= 5
MsgRouter.SharedKey             = PLAINTEXT
MsgRouter.SessionCacheTime      = 2m
MsgRouter.SessionRetries        = 3
MsgRouter.SessionTimeout        = 10s
";
            LeafRouter router;

            Config.SetConfig(string.Format(settings, root, hub, name, cloudEP));
            router = new LeafRouter();
            router.Start();

            return(router);
        }
Пример #5
0
            public void Start()
            {
                Router = new LeafRouter();
                Router.Start();
                Thread.Sleep(1000);

                Node = new GeoTrackerNode();
                Node.Start(Router, new GeoTrackerServerSettings(), null, null);
            }
Пример #6
0
        public void ParallelQuerySession_WaitAll_PartialFail()
        {
            // Test 4 parallel queries where 2 succeed and two fail.

            try
            {
                router = new LeafRouter();
                router.Start();
                router.Dispatcher.AddTarget(this);

                Thread.Sleep(1000);

                var parallelQuery = new ParallelQuery();
                var queryMsg1     = new PropertyMsg();
                var queryMsg2     = new PropertyMsg();
                var queryMsg3     = new PropertyMsg();
                var queryMsg4     = new PropertyMsg();

                queryMsg1["cmd"]   = "reply";
                queryMsg1["value"] = "1";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg1));

                queryMsg2["cmd"]   = "error";
                queryMsg2["value"] = "2";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg2));

                queryMsg3["cmd"]   = "reply";
                queryMsg3["value"] = "3";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg3));

                queryMsg4["cmd"]   = "error";
                queryMsg4["value"] = "4";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg4));

                router.ParallelQuery(parallelQuery);

                Assert.AreEqual("1", ((PropertyMsg)parallelQuery.Operations[0].ReplyMsg)["value"]);
                Assert.AreEqual("3", ((PropertyMsg)parallelQuery.Operations[2].ReplyMsg)["value"]);

                Assert.AreEqual("Error: 2", parallelQuery.Operations[1].Error.Message);
                Assert.AreEqual("Error: 4", parallelQuery.Operations[3].Error.Message);
            }
            finally
            {
                if (router != null)
                {
                    router.Stop();
                    router = null;
                }

                Config.SetConfig(null);
            }
        }
Пример #7
0
        private void startButton_Click(object sender, EventArgs args)
        {
            if (running)
            {
                return;
            }

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

            running = true;
            SetUIState();
        }
Пример #8
0
        private LeafRouter CreateRouter()
        {
            const string settings =
                @"
&section LillTek.Datacenter.ConfigService

    SettingsFolder = {0}

&endsection

&section MsgRouter

    AppName                = Test
    AppDescription         = Test Description
    RouterEP		       = physical://detached/test/leaf
    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
    SharedKey		       = PLAINTEXT
    SessionCacheTime       = 2m
    SessionRetries         = 3
    SessionTimeout         = 10s
    MaxLogicalAdvertiseEPs = 256
    DeadRouterTTL          = 2s

&endsection
";
            LeafRouter           router;
            ConfigServiceHandler configHandler;
            string folder;

            folder = Path.GetTempPath() + "Settings";
            Config.SetConfig(string.Format(settings, folder).Replace('&', '#'));
            MsgEP.ReloadAbstractMap();

            router        = new LeafRouter();
            configHandler = new ConfigServiceHandler();

            configHandler.Start(router, null, null, null);
            router.Start();

            return(router);
        }
Пример #9
0
        /// <summary>
        /// Starts the service, associating it with an <see cref="IServiceHost" /> instance.
        /// </summary>
        /// <param name="serviceHost">The service user interface.</param>
        /// <param name="args">Command line arguments.</param>
        public void Start(IServiceHost serviceHost, string[] args)
        {
            lock (syncLock)
            {
                if (router != null)
                {
                    return;     // Already started
                }
                // Global initialization

                NetTrace.Start();

                Program.Config = new Config(MsgQueueHandler.ConfigPrefix);
                Program.InstallPerfCounters();

                // Service initialization

                this.serviceHost = serviceHost;
                SysLog.LogInformation("Message Queue v{0} Start", Helper.GetVersionString());

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

                    handler = new MsgQueueHandler();
                    handler.Start(router, null, Program.PerfCounters, null);

                    state = ServiceState.Running;
                }
                catch (Exception e)
                {
                    if (handler != null)
                    {
                        handler.Stop();
                        handler = null;
                    }

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

                    SysLog.LogException(e);
                    throw;
                }
            }
        }
Пример #10
0
        private void TestInit(string appConfig)
        {
            Config.SetConfig((RouterConfig + appConfig).Replace('&', '#'));
            router = new LeafRouter();
            router.Start();

            client = new GeoTrackerClient(router, null);

            var serverSettings = GeoTrackerServerSettings.LoadConfig("LillTek.GeoTracker.Server");

            serverSettings.IPGeocodeEnabled = false;

            server = new GeoTrackerNode();
            server.Start(router, serverSettings, null, null);
        }
Пример #11
0
        /// <summary>
        /// Starts the service, associating it with an <see cref="IServiceHost" /> instance.
        /// </summary>
        /// <param name="serviceHost">The service user interface.</param>
        /// <param name="args">Command line arguments.</param>
        public void Start(IServiceHost serviceHost, string[] args)
        {
            lock (syncLock)
            {
                if (router != null)
                {
                    return;     // Already started
                }
                // Global initialization

                NetTrace.Start();
                Program.Config       = new Config(ConfigServiceHandler.ConfigPrefix);
                Program.PerfCounters = null;    // $todo(jeff.lill): new PerfCounterSet(true,Const.ConfigServicePerf,Const.ConfigServiceName);

                // Service initialization

                this.serviceHost = serviceHost;
                SysLog.LogInformation("Config Service v{0} Start", Helper.GetVersionString());

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

                    handler = new ConfigServiceHandler();
                    handler.Start(router, null, null, null);

                    state = ServiceState.Running;
                }
                catch (Exception e)
                {
                    if (handler != null)
                    {
                        handler.Stop();
                        handler = null;
                    }

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

                    SysLog.LogException(e);
                    throw;
                }
            }
        }
Пример #12
0
        private void TestInit(bool enable, bool copyDatabase)
        {
            const string cfg =
                @"
MsgRouter.AppName               = Test
MsgRouter.AppDescription        = Test Description
MsgRouter.DiscoveryMode         = MULTICAST
MsgRouter.RouterEP				= physical://DETACHED/$(LillTek.DC.DefHubName)/$(Guid)
MsgRouter.CloudEP               = $(LillTek.DC.CloudEP)
MsgRouter.CloudAdapter          = ANY
MsgRouter.UdpEP					= ANY:0
MsgRouter.TcpEP					= ANY:0
MsgRouter.TcpBacklog			= 100
MsgRouter.TcpDelay				= off
MsgRouter.BkInterval			= 1s
MsgRouter.MaxIdle				= 5m
MsgRouter.EnableP2P             = yes
MsgRouter.AdvertiseTime			= 1m
MsgRouter.DefMsgTTL				= 5
MsgRouter.SharedKey             = PLAINTEXT
MsgRouter.SessionCacheTime      = 2m
MsgRouter.SessionRetries        = 3
MsgRouter.SessionTimeout        = 10s
";

            Config.SetConfig(cfg);
            router = new LeafRouter();
            router.Start();
            Thread.Sleep(1000);

            client = new GeoTrackerClient(router, null);

            var serverSettings = new GeoTrackerServerSettings()
            {
                IPGeocodeEnabled       = enable,
                IPGeocodeSourceTimeout = TimeSpan.FromMinutes(2),
            };

            if (copyDatabase)
            {
                Helper.DeleteFile(IPGeocoder.DataPath);
                File.Copy(exteralDataPath, IPGeocoder.DataPath);
            }

            server = new GeoTrackerNode();
            server.Start(router, serverSettings, null, null);
            Thread.Sleep(2000);
        }
Пример #13
0
        /// <summary>
        /// Starts the service, associating it with an <see cref="IServiceHost" /> instance.
        /// </summary>
        /// <param name="serviceHost">The service user interface.</param>
        /// <param name="args">Command line arguments.</param>
        public void Start(IServiceHost serviceHost, string[] args)
        {
            lock (syncLock)
            {
                if (router != null)
                {
                    return;     // Already started
                }
                // Global initialization

                NetTrace.Start();
                Program.Config = new Config("LillTek.Datacenter.DynDNSClient");
                Program.InstallPerfCounters();

                // Service initialization

                this.serviceHost = serviceHost;
                SysLog.LogInformation("Dynamic DNS Client v{0} Start", Helper.GetVersionString());

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

                    client = new DynDnsClient();
                    client.Open(router, new DynDnsClientSettings("LillTek.Datacenter.DynDNSClient"));

                    state = ServiceState.Running;
                }
                catch (Exception e)
                {
                    if (client != null)
                    {
                        client.Close();
                        client = null;
                    }

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

                    SysLog.LogException(e);
                    throw;
                }
            }
        }
Пример #14
0
        public void StreamTransferSession_Upload_ErrorOnClient()
        {
            StreamTransferSession clientSession;
            LeafRouter            router;
            IAsyncResult          ar;

            InitServer();

            router = null;
            try
            {
                SetConfig("DefBlockSize=1000");

                router = new LeafRouter();
                router.Start();
                router.Dispatcher.AddTarget(this);

                clientSession               = StreamTransferSession.ClientUpload(router, "logical://Test/Upload", CreateStream(TransferSize));
                clientSession.Delay         = 500;
                clientSession.SimulateError = true;
                ar = clientSession.BeginTransfer(null, null);

                Thread.Sleep(1000);
                clientSession.Cancel();

                clientSession.EndTransfer(ar);
                Assert.Fail("Expected an exception");
            }
            catch
            {
                // Expecting an exception
            }
            finally
            {
                if (router != null)
                {
                    router.Stop();
                }

                Config.SetConfig(null);
            }

            Thread.Sleep(1000);
            Assert.IsTrue(serverNotify);
            Assert.IsInstanceOfType(serverException, typeof(SessionException));
        }
Пример #15
0
        public void StreamTransferSession_Cancel_OnServer()
        {
            StreamTransferSession clientSession;
            LeafRouter            router;

            InitServer();

            router = null;
            try
            {
                SetConfig("DefBlockSize=1000");

                router = new LeafRouter();
                router.Start();
                router.Dispatcher.AddTarget(this);

                simServerCancel = true;

                clientSession       = StreamTransferSession.ClientUpload(router, "logical://Test/Upload", CreateStream(TransferSize));
                clientSession.Delay = 500;
                clientSession.Transfer();
                Assert.Fail("Expected a CancelException");
            }
            catch (SessionException e)
            {
                SysLog.LogException(e);
            }
            catch (Exception e)
            {
                Assert.IsInstanceOfType(e, typeof(CancelException));
            }
            finally
            {
                if (router != null)
                {
                    router.Stop();
                }

                Config.SetConfig(null);
            }

            Thread.Sleep(1000);
            Assert.IsTrue(serverNotify);
            Assert.IsInstanceOfType(serverException, typeof(CancelException));
        }
Пример #16
0
        public void StreamTransferSession_Download_ErrorOnServer()
        {
            StreamTransferSession clientSession;
            LeafRouter            router;
            EnhancedMemoryStream  msClient;

            InitServer();

            router = null;
            try
            {
                SetConfig("DefBlockSize=1000");

                router = new LeafRouter();
                router.Start();
                router.Dispatcher.AddTarget(this);

                msServer = CreateStream(TransferSize);
                msClient = new EnhancedMemoryStream();

                simServerError = true;

                clientSession       = StreamTransferSession.ClientDownload(router, "logical://Test/Download", msClient);
                clientSession.Delay = 500;
                clientSession.Transfer();
                Assert.Fail("Expecting a SessionException");
            }
            catch (Exception e)
            {
                Assert.IsInstanceOfType(e, typeof(SessionException));
            }
            finally
            {
                if (router != null)
                {
                    router.Stop();
                }

                Config.SetConfig(null);
            }

            Thread.Sleep(1000);
            Assert.IsTrue(serverNotify);
            Assert.IsInstanceOfType(serverException, typeof(Exception));
        }
Пример #17
0
        /// <summary>
        /// Starts the service, associating it with an <see cref="IServiceHost" /> instance.
        /// </summary>
        /// <param name="serviceHost">The service user interface.</param>
        /// <param name="args">Command line arguments.</param>
        public void Start(IServiceHost serviceHost, string[] args)
        {
            lock (syncLock) {
                if (router != null)
                {
                    return;     // Already started
                }
                // Global initialization

                NetTrace.Start();
                Program.Config = new Config("LillTek.GeoTracker.Service");
                Program.InstallPerfCounters();

                // Service initialization

                this.serviceHost = serviceHost;
                SysLog.LogInformation("GeoTracker Service v{0} Start", Helper.GetVersionString());

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

                    node = new GeoTrackerNode();
                    node.Start(router, GeoTrackerNode.ConfigPrefix, Program.PerfCounters, null);

                    state = ServiceState.Running;
                }
                catch (Exception e) {
                    if (node != null)
                    {
                        node.Stop();
                        node = null;
                    }

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

                    SysLog.LogException(e);
                    throw;
                }
            }
        }
Пример #18
0
        public void Initialize()
        {
            NetTrace.Start();
            NetTrace.Enable(MsgRouter.TraceSubsystem, 0);

            const string settings =
                @"
&section MsgRouter

    AppName                = Test
    AppDescription         = Test Description
    RouterEP			   = physical://detached/test/leaf
    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
    SharedKey		       = PLAINTEXT
    SessionCacheTime       = 2m
    SessionRetries         = 3
    SessionTimeout         = 10s
    MaxLogicalAdvertiseEPs = 256
    DeadRouterTTL          = 2s

&endsection
";

            Config.SetConfig(settings.Replace('&', '#'));
            MsgEP.ReloadAbstractMap();

            router  = new LeafRouter();
            handler = new ServerManagerHandler();

            handler.Start(router, null, null, null);
            router.Start();
        }
Пример #19
0
        public void StreamTransferSession_WrongDirection_Upload()
        {
            StreamTransferSession clientSession;
            LeafRouter            router;
            EnhancedMemoryStream  msClient;

            InitServer();

            router = null;
            try
            {
                SetConfig("DefBlockSize=1000");

                router = new LeafRouter();
                router.Start();
                router.Dispatcher.AddTarget(this);

                msServer = CreateStream(TransferSize);
                msClient = new EnhancedMemoryStream();

                clientSession = StreamTransferSession.ClientUpload(router, "logical://Test/Download", msClient);
                clientSession.Transfer();
                Assert.Fail("Expected a SessionException");
            }
            catch (Exception e)
            {
                Assert.IsInstanceOfType(e, typeof(SessionException));
            }
            finally
            {
                if (router != null)
                {
                    router.Stop();
                }

                Config.SetConfig(null);
            }
        }
Пример #20
0
        private void TestInit()
        {
            const string cfg =
                @"
MsgRouter.AppName               = Test
MsgRouter.AppDescription        = Test Description
MsgRouter.DiscoveryMode         = MULTICAST
MsgRouter.RouterEP				= physical://DETACHED/$(LillTek.DC.DefHubName)/$(Guid)
MsgRouter.CloudEP               = $(LillTek.DC.CloudEP)
MsgRouter.CloudAdapter          = ANY
MsgRouter.UdpEP					= ANY:0
MsgRouter.TcpEP					= ANY:0
MsgRouter.TcpBacklog			= 100
MsgRouter.TcpDelay				= off
MsgRouter.BkInterval			= 1s
MsgRouter.MaxIdle				= 5m
MsgRouter.EnableP2P             = yes
MsgRouter.AdvertiseTime			= 1m
MsgRouter.DefMsgTTL				= 5
MsgRouter.SharedKey             = PLAINTEXT
MsgRouter.SessionCacheTime      = 2m
MsgRouter.SessionRetries        = 3
MsgRouter.SessionTimeout        = 10s
";

            Config.SetConfig(cfg);
            router = new LeafRouter();
            router.Start();

            client = new GeoTrackerClient(router, null);

            var serverSettings = new GeoTrackerServerSettings();

            serverSettings.IPGeocodeEnabled = false;

            server = new GeoTrackerNode();
            server.Start(router, serverSettings, null, null);
        }
Пример #21
0
        public void ParallelQuerySession_WaitAny_SingleSuccess()
        {
            // Test a single successful query just to make sure it actually works.

            try
            {
                router = new LeafRouter();
                router.Start();
                router.Dispatcher.AddTarget(this);

                Thread.Sleep(1000);

                var parallelQuery = new ParallelQuery()
                {
                    WaitMode = ParallelWait.ForAny
                };
                var queryMsg1 = new PropertyMsg();

                queryMsg1["cmd"]   = "reply";
                queryMsg1["value"] = "1";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg1));

                router.ParallelQuery(parallelQuery);

                Assert.AreEqual("1", ((PropertyMsg)parallelQuery.Operations[0].ReplyMsg)["value"]);
            }
            finally
            {
                if (router != null)
                {
                    router.Stop();
                    router = null;
                }

                Config.SetConfig(null);
            }
        }
Пример #22
0
        private LeafRouter CreateLeaf(string root, string hub, string name, string cloudEP, bool enableP2P)
        {
            const string settings =
                @"
MsgRouter.AppName               = Test
MsgRouter.AppDescription        = Test Description
MsgRouter.DiscoveryMode         = MULTICAST
MsgRouter.RouterEP				= physical://{0}/{1}/{2}
MsgRouter.CloudEP	            = {3}
MsgRouter.CloudAdapter          = ANY
MsgRouter.UdpEP					= ANY:0
MsgRouter.TcpEP					= ANY:0
MsgRouter.TcpBacklog			= 100
MsgRouter.TcpDelay				= off
MsgRouter.BkInterval			= 1s
MsgRouter.MaxIdle				= 5m
MsgRouter.EnableP2P             = {4}
MsgRouter.AdvertiseTime			= 1m
MsgRouter.DefMsgTTL				= 5
MsgRouter.SharedKey             = PLAINTEXT
MsgRouter.SessionCacheTime      = 2m
MsgRouter.SessionRetries        = 3
MsgRouter.SessionTimeout        = 10s
";

            LeafRouter router;

            Config.SetConfig(string.Format(settings, root, hub, name, cloudEP, enableP2P ? "yes" : "no"));

            router = new LeafRouter();
            router.Dispatcher.AddTarget(this);
            router.Dispatcher.AddLogical(new MsgHandlerDelegate(OnMsg), "logical://" + name, typeof(PropertyMsg), false, null);
            router.Start();

            return(router);
        }
Пример #23
0
        public void ParallelQuerySession_WaitAny_MultipleSuccess()
        {
            // Test 4 parallel queries that all succeed and verify that
            // only one result is actually returned.

            try
            {
                router = new LeafRouter();
                router.Start();
                router.Dispatcher.AddTarget(this);

                Thread.Sleep(1000);

                var parallelQuery = new ParallelQuery()
                {
                    WaitMode = ParallelWait.ForAny
                };
                var queryMsg1 = new PropertyMsg();
                var queryMsg2 = new PropertyMsg();
                var queryMsg3 = new PropertyMsg();
                var queryMsg4 = new PropertyMsg();

                queryMsg1["cmd"]   = "reply";
                queryMsg1["value"] = "1";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg1));

                queryMsg2["cmd"]   = "reply";
                queryMsg2["value"] = "2";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg2));

                queryMsg3["cmd"]   = "reply";
                queryMsg3["value"] = "3";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg3));

                queryMsg4["cmd"]   = "reply";
                queryMsg4["value"] = "4";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg4));

                router.ParallelQuery(parallelQuery);

                int cCompleted = 0;

                for (int i = 0; i < 4; i++)
                {
                    var operation = parallelQuery.Operations[i];

                    if (operation.IsComplete)
                    {
                        cCompleted++;
                        Assert.AreEqual((i + 1).ToString(), ((PropertyMsg)parallelQuery.Operations[i].ReplyMsg)["value"]);
                    }
                }

                Assert.AreEqual(1, cCompleted);
            }
            finally
            {
                if (router != null)
                {
                    router.Stop();
                    router = null;
                }

                Config.SetConfig(null);
            }
        }
Пример #24
0
        private void TestInit()
        {
            const string cfg =
                @"
Diagnostics.TraceEnable[-] = 0:LillTek.Messaging
--Diagnostics.TraceEnable[-] = 1:LillTek.GeoTracker

MsgRouter.AppName               = Test
MsgRouter.AppDescription        = Test Description
MsgRouter.DiscoveryMode         = MULTICAST
MsgRouter.RouterEP				= physical://DETACHED/$(LillTek.DC.DefHubName)/$(Guid)
MsgRouter.CloudEP               = $(LillTek.DC.CloudEP)
MsgRouter.CloudAdapter          = ANY
MsgRouter.UdpEP					= ANY:0
MsgRouter.TcpEP					= ANY:0
MsgRouter.TcpBacklog			= 100
MsgRouter.TcpDelay				= off
MsgRouter.BkInterval			= 1s
MsgRouter.MaxIdle				= 5m
MsgRouter.EnableP2P             = yes
MsgRouter.AdvertiseTime			= 1s
MsgRouter.DefMsgTTL				= 5
MsgRouter.SharedKey             = PLAINTEXT
MsgRouter.SessionCacheTime      = 2m
MsgRouter.SessionRetries        = 3
MsgRouter.SessionTimeout        = 10s
";

            Config.SetConfig(cfg);
            //NetTrace.Start();

            router = new LeafRouter();
            router.Start();
            Thread.Sleep(1000);

            client = new GeoTrackerClient(router, null);

            var serverSettings = new GeoTrackerServerSettings();

            serverSettings.IPGeocodeEnabled = false;

            // Crank up the cluster instances on separate threads.

            var threads = new List <Thread>();
            var fail    = false;

            clusterInstances = new ClusterInstance[InstanceCount];

            for (int i = 0; i < InstanceCount; i++)
            {
                clusterInstances[i] = new ClusterInstance();
            }

            for (int i = 0; i < InstanceCount; i++)
            {
                threads.Add(
                    Helper.StartThread(null, i,
                                       index =>
                {
                    try
                    {
                        clusterInstances[(int)index].Start();
                    }
                    catch (Exception e)
                    {
                        SysLog.LogException(e);
                        fail = true;
                    }
                }));
            }

            foreach (var thread in threads)
            {
                thread.Join();
            }

            if (fail)
            {
                Assert.Fail("Instance Creation Failure");
            }

            Thread.Sleep(5000);     // Wait for routes to be replicated
        }
Пример #25
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);
            }
        }
Пример #26
0
        public void MessageQueue_EndToEnd_Disk()
        {
            // This test peforms a simple end-to-end test of the Message
            // Queue Service by starting the service and processing
            // some messages.

            Process    svcProcess = null;
            LeafRouter router     = null;
            MsgQueue   queue      = null;
            Assembly   assembly;

            Helper.InitializeApp(Assembly.GetExecutingAssembly());
            assembly = typeof(LillTek.Datacenter.MessageQueue.Program).Assembly;

            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
    SharedKey		       = PLAINTEXT
    SessionCacheTime       = 2m
    SessionRetries         = 3
    SessionTimeout         = 10s
    MaxLogicalAdvertiseEPs = 256
    DeadRouterTTL          = 2s

&endsection

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

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

                // Start the application store service

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

                // Send and receive some messages

                queue = new MsgQueue(router);
                queue.EnqueueTo("logical://LillTek/DataCenter/MsgQueue/10", new QueuedMsg(10));

                //for (int i=0;i<10;i++)
                //    queue.EnqueueTo("logical://LillTek/DataCenter/MsgQueue/" + i.ToString(),new QueuedMsg(i));

                //for (int i=0;i<10;i++)
                //    Assert.AreEqual(i,queue.DequeueFrom("logical://LillTek/DataCenter/MsgQueue/" + i.ToString(),TimeSpan.FromSeconds(1)).Body);
            }
            finally
            {
                if (svcProcess != null)
                {
                    svcProcess.Kill();
                    svcProcess.Close();
                }

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

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

                Config.SetConfig(null);
            }
        }
Пример #27
0
        public void DynDnsService_EndToEnd()
        {
            LeafRouter   router     = null;
            Process      svcProcess = null;
            Assembly     assembly   = typeof(LillTek.Datacenter.DynDnsService.Program).Assembly;
            DynDnsClient client     = null;

            Helper.InitializeApp(assembly);

            try
            {
                Config.SetConfig(@"

&section MsgRouter

    AppName                = LillTek.DynDNS Service
    AppDescription         = Dynamic DNS
    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
    SharedKey		       = PLAINTEXT
    SessionCacheTime       = 2m
    SessionRetries         = 3
    SessionTimeout         = 10s
    MaxLogicalAdvertiseEPs = 256
    DeadRouterTTL          = 2s
    
    // This maps the abstract Dynamic DNS endpoints to their default logical endpoints.

    AbstractMap[abstract://LillTek/DataCenter/DynDNS] = logical://LillTek/DataCenter/DynDNS

&endsection

&section MsgRouter

    AppName                = LillTek.DynDNS Service
    AppDescription         = Dynamic DNS
    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
    SharedKey		       = PLAINTEXT
    SessionCacheTime       = 2m
    SessionRetries         = 3
    SessionTimeout         = 10s
    MaxLogicalAdvertiseEPs = 256
    DeadRouterTTL          = 2s
    
    // This maps the abstract Dynamic DNS endpoints to their default logical endpoints.

    AbstractMap[abstract://LillTek/DataCenter/DynDNS] = logical://LillTek/DataCenter/DynDNS

&endsection

//-----------------------------------------------------------------------------
// Dynamic DNS Service Settings

&section LillTek.Datacenter.DynDNS

    // Specifies the network binding the DNS server should listen on.
    
    NetworkBinding = ANY:DNS

    // Specifies the NetworkBinding the DNS server 
    // should listen on to receive UDP host registration messages
    // from DynDnsClients.

    UdpBinding = ANY:DYNAMIC-DNS
    
    // Controls how the server is to be configured to obtain host
    // registrations from dynamic DNS clients.  The possible values
    // are UDP, CLUSTER, or BOTH.
    
    Mode = UDP

    // Shared symmetric encryption key used to decrypt UDP registration messages
    // sent by DNS clients while in UDP or BOTH mode.  This key must match the shared
    // key configured for the client.  This defaults to the same reasonable default 
    //  used by the DNS client class.

    SharedKey = aes:BcskocQ2W4aIGEemkPsy5dhAxuWllweKLVToK1NoYzg=:5UUVxRPml8L4WH82unR74A==

    // The maximum delta to be allowed between the timestamp of messages received from
    // UDP broadcast clients and servers and the current system time.
    //
    // Messages transmitted between clients and servers in the UDP broadcast cluster are
    // timestamped with the time they were sent (UTC) to avoid replay attacks.  This
    // setting controls which messages will be discarded for being having a timestamp
    // too far in the past or too far into the future.
    //
    // Ideally, this value would represent the maximum time a message could realistically
    // remain in transit on the network (a few seconds), but this setting also needs to
    // account for the possibility that the server system clocks may be out of sync.  So,
    // this value is a tradeoff between security and reliability.

    MessageTTL = 15m

    // Specifies the time-to-live setting to use when replying to
    // DNS queries.  This indicates how long the operating system
    // on the client side should cache the response.
    
    ResponseTTL = 5s
    
    // Indicates whether DNS host lookup failures should be logged
    // as warnings.
    
    LogFailures = yes
    
    &section Cluster
    
        // The cluster's logical base endpoint.  Instance endpoints will be constructed
        // by appending a GUID segment to this and the cluster broadcast endpoint
        // will be generated by appending '/*'.  This setting is required.
        
        ClusterBaseEP = abstract://LillTek/DataCenter/DynDNS
        
        // Specifies the startup mode for the instance.  This can be one of
        // the following values:
        // 
        //      NORMAL          Indicates that the cluster member should go through the normal 
        //                      master election cycle and eventually enter into the MASTER or SLAVE
        //                      state.
        //
        //      OBSERVER        Indicates that the cluster member should immediately enter the
        //                      OBSERVER state and remain there.  Cluster observer state information
        //                      is replicated across the cluster so other instances know
        //                      about these instances but observers will never be elected 
        //                      as the master.
        //
        //      MONITOR         Indicates that the cluster member should immediately enter the 
        //                      MONITOR state and remain there.  Monitors collect and maintain 
        //                      cluster status but do not actively participate in the cluster.  
        //                      No member status information about a monitor will be replicated
        //                      across the cluster.
        //
        //      PREFERSLAVE     Indicates that the cluster member prefers to be started as a 
        //                      cluster slave
        //
        //      PREFERMASTER    Indicates that the cluster member prefers to be started as the 
        //                      cluster master.  If a master is already running and it does not 
        //                      have this preference then a master election will be called.
        
        Mode = Normal

        // The interval at which the cluster master should broadcast cluster update
        // messages.  Default is 1m.
        
        MasterBroadcastInterval = 10s

        // The interval at which slaves send their status updates to the master.
        // Default is 1m.

        SlaveUpdateInterval = 10s

        // The time period cluster members will wait while collecting member status
        // broadcasts from peers before concluding a master election.  Default
        // is 5s.

        ElectionInterval = 10s

        // The number of times a cluster slave member should allow for missed
        // cluster status messages before calling for a master election.
        // Default is 3.

        MissingMasterCount = 2

        // The number of times the cluster master should allow for missed
        // slave status transmissions before removing the slave from the cluster 
        // state.  Default is 3.

        MissingSlaveCount = 2

        // The interval at which the cluster master instance should raise its
        // ClusterMember.MasterTask event so that derived classes can implement 
        // custom background processing behavior.  Default is 1s.

        MasterBkInterval = 1s

        // The interval at which the cluster slaves should raise their
        // ClusterMember.SlaveTask event so that derived classes
        // can implement custom background processing behavior.
        // Default is 1s.

        SlaveBkInterval = 1s

        // The background task polling interval.  This value should be less than
        // or equal to the minimum of MasterBroadcastInterval, MasterBkInterval, 
        // and SlaveBkInterval.  Default is 1s.

        BkInterval = 1s

    &endsection

&endsection

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

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

                // Start the Dynamic DNS service

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

                // Open a dynamic DNS client and register a host and then
                // verify that it worked.

                DynDnsClientSettings clientSettings;

                clientSettings                     = new DynDnsClientSettings();
                clientSettings.Mode                = DynDnsMode.Udp;
                clientSettings.NameServers         = new NetworkBinding[] { new NetworkBinding(NetHelper.GetActiveAdapter(), NetworkPort.DynamicDns) };
                clientSettings.UdpRegisterInterval = TimeSpan.FromSeconds(1);

                client = new DynDnsClient();
                client.Register(new DynDnsHostEntry("test.com", IPAddress.Parse("10.1.2.3")));
                client.Register(new DynDnsHostEntry("www.lilltek.com", IPAddress.Parse("192.168.1.202")));
                client.Open(router, clientSettings);
                Thread.Sleep(3000);

                Assert.AreEqual(IPAddress.Parse("10.1.2.3"), DnsLookup("test.com"));

                // Uncomment this for manual interop testing

                // Thread.Sleep(10000000);
            }
            finally
            {
                if (client != null)
                {
                    client.Close();
                }

                if (svcProcess != null)
                {
                    svcProcess.Kill();
                    svcProcess.Close();
                }

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

                Config.SetConfig(null);
            }
        }
Пример #28
0
        public void ParallelQuerySession_WaitAny_PartialSuccess()
        {
            // Test 4 parallel queries where two succeed (after a bit of a delay) and
            // two fail immediately and verify that the two failures were recorded and
            // we have a single successful response.

            try
            {
                router = new LeafRouter();
                router.Start();
                router.Dispatcher.AddTarget(this);

                Thread.Sleep(1000);

                var parallelQuery = new ParallelQuery()
                {
                    WaitMode = ParallelWait.ForAny
                };
                var queryMsg1 = new PropertyMsg();
                var queryMsg2 = new PropertyMsg();
                var queryMsg3 = new PropertyMsg();
                var queryMsg4 = new PropertyMsg();

                queryMsg1["cmd"]   = "delay-reply";
                queryMsg1["value"] = "1";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg1));

                queryMsg2["cmd"]   = "delay-reply";
                queryMsg2["value"] = "2";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg2));

                queryMsg3["cmd"]   = "error";
                queryMsg3["value"] = "3";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg3));

                queryMsg4["cmd"]   = "error";
                queryMsg4["value"] = "4";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg4));

                router.ParallelQuery(parallelQuery);

                int cCompleted = 0;

                for (int i = 0; i < 2; i++)
                {
                    var operation = parallelQuery.Operations[i];

                    if (operation.IsComplete)
                    {
                        cCompleted++;
                        Assert.AreEqual((i + 1).ToString(), ((PropertyMsg)parallelQuery.Operations[i].ReplyMsg)["value"]);
                    }
                }

                Assert.AreEqual(1, cCompleted);
                Assert.AreEqual("Error: 3", parallelQuery.Operations[2].Error.Message);
                Assert.AreEqual("Error: 4", parallelQuery.Operations[3].Error.Message);
            }
            finally
            {
                if (router != null)
                {
                    router.Stop();
                    router = null;
                }

                Config.SetConfig(null);
            }
        }
Пример #29
0
        public void ParallelQuerySession_WaitAny_MultipleFail()
        {
            // Test 4 parallel queries where all fail and verify that we got
            // all of the error responses.

            try
            {
                router = new LeafRouter();
                router.Start();
                router.Dispatcher.AddTarget(this);

                Thread.Sleep(1000);

                var parallelQuery = new ParallelQuery()
                {
                    WaitMode = ParallelWait.ForAny
                };
                var queryMsg1 = new PropertyMsg();
                var queryMsg2 = new PropertyMsg();
                var queryMsg3 = new PropertyMsg();
                var queryMsg4 = new PropertyMsg();

                queryMsg1["cmd"]   = "error";
                queryMsg1["value"] = "1";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg1));

                queryMsg2["cmd"]   = "error";
                queryMsg2["value"] = "2";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg2));

                queryMsg3["cmd"]   = "error";
                queryMsg3["value"] = "3";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg3));

                queryMsg4["cmd"]   = "error";
                queryMsg4["value"] = "4";
                parallelQuery.Operations.Add(new ParallelOperation("logical://parallel/test", queryMsg4));

                router.ParallelQuery(parallelQuery);

                int cCompleted = 0;

                for (int i = 0; i < 4; i++)
                {
                    var operation = parallelQuery.Operations[i];

                    if (operation.IsComplete)
                    {
                        cCompleted++;
                        Assert.AreEqual("Error: " + (i + 1).ToString(), parallelQuery.Operations[i].Error.Message);
                    }
                }

                Assert.AreEqual(4, cCompleted);
            }
            finally
            {
                if (router != null)
                {
                    router.Stop();
                    router = null;
                }

                Config.SetConfig(null);
            }
        }
Пример #30
0
        /// <summary>
        /// Returns configuration information formatted as an .ini file as
        /// specified by <see cref="Config" />.
        /// </summary>
        /// <param name="settings">Provider specific settings.</param>
        /// <param name="cacheFile">File path to use for cached settings.</param>
        /// <param name="machineName">The requesting machine's name.</param>
        /// <param name="exeFile">The unqualified name of the current process' executable file.</param>
        /// <param name="exeVersion">The version number of the current executable file.</param>
        /// <param name="usage">Used to indicate a non-default usage for this application instance.</param>
        /// <returns>The configuration file data (or <c>null</c>).</returns>
        /// <remarks>
        /// <para>
        /// The settings parameter must specify the <b>RouterEP</b> and <b>CloudEP</b> setting values,
        /// (the rest are optional):
        /// </para>
        /// <code language="none">
        /// RouterEP  = &lt;Router Physical Endpoint&gt;
        /// CloudEP   = &lt;IP Endpoint&gt;
        /// ConfigEP  = &lt;logical or physical endpoint&gt; (optional)
        /// EnableP2P = 0 | 1 (optional)
        /// </code>
        /// <para>
        /// <b>RouterEP</b> specifies the unique physical endpoint to be assigned to the
        /// bootstrap router.  This must be unique across all routers so it's best to
        /// use the $(Guid) environment variable somewhere within the definition.
        /// </para>
        /// <para>
        /// <b>CloudEP</b> specifies the IP endpoint to be used by a bootstrap
        /// message router to discover the other routers on the network, and <b>ConfigEP</b>
        /// specifies the logical or physical messaging endpoint of the configuration service.
        /// The class uses this information to start a leaf bootstrap router which will
        /// be used to discover and communicate with the configuration service.
        /// </para>
        /// <para>
        /// The <b>EnableP2P</b> setting indicates whether the bootstrap router should be
        /// peer-to-peer enabled.  This parameter is optional and defaults to "1".  This
        /// setting is present for scalability reasons.  P2P enabling the bootstrap router
        /// will cause a lot of network traffic in environments with a lot of servers since
        /// every other P2P enabled router will establish a connection to the bootstrap
        /// router to discover its logical routes.  This is a significant overhead for a
        /// router that exposes no routes.  <b>EnableP2P</b> should be set to "0" in production
        /// environments with a lot of servers and with a hub server present to avoid this
        /// problem.
        /// </para>
        /// <para>
        /// The cacheFile parameter specifies the name of the file where the provider
        /// may choose to cache configuration settings.  This implementation will save a copy
        /// of the last set of settings returned by a remote service in this file and
        /// then use these settings if the remote service is unavailable the next time
        /// the service is started.  This improves the operational robustness of a
        /// large network of servers.  Choosing to implement this behavior is completely
        /// up to the discretion of the provider.  Specify <b>(no-cache)</b> to disable
        /// caching behavior.
        /// </para>
        /// <para>
        /// Note that the method will return null if the requested configuration
        /// information could not be loaded for any reason.
        /// </para>
        /// <para>
        /// This class queries the configuration service via the following message
        /// endpoints:
        /// </para>
        /// <code language="none">
        /// abstract://LillTek/DataCenter/ConfigService
        /// </code>
        /// <para>
        /// This may be remapped to another logical endpoint via the message
        /// routers <b>MsgRouter.AbstractMap</b> configuation setting.
        /// </para>
        /// </remarks>
        public string GetConfig(ArgCollection settings, string cacheFile, string machineName, string exeFile, Version exeVersion, string usage)
        {
            LeafRouter     router = null;
            RouterSettings rSettings;
            string         s;
            MsgEP          routerEP;
            IPEndPoint     cloudEP;
            MsgEP          configEP;
            bool           enableP2P;
            GetConfigAck   ack;
            string         configText     = null;
            Exception      queryException = null;

            // Make sure that the assembly's message types have been
            // registered with the LillTek.Messaging subsystem.

            Global.RegisterMsgTypes();

            // Parse the settings

            s = settings["RouterEP"];
            if (s == null)
            {
                throw new ArgumentException("[RouterEP] setting expected.", "settings");
            }

            try
            {
                routerEP = MsgEP.Parse(s);
            }
            catch
            {
                throw new ArgumentException("[RouterEP] is invalid.", "settings");
            }

            if (!routerEP.IsPhysical)
            {
                throw new ArgumentException("[RouterEP] must specify a physical endpoint.", "settings");
            }

            s = settings["CloudEP"];
            if (s == null)
            {
                throw new ArgumentException("[CloudEP] setting expected.", "settings");
            }

            cloudEP = Serialize.Parse(s, new IPEndPoint(IPAddress.Any, 0));
            if (cloudEP == new IPEndPoint(IPAddress.Any, 0))
            {
                throw new ArgumentException("[CloudEP] setting is invalid.", "settings");
            }

            configEP  = Serialize.Parse(settings["ConfigEP"], GetConfigEP);
            enableP2P = Serialize.Parse(settings["EnableP2P"], true);

            // Crank up a bootstrap leaf router and perform the query.

            try
            {
                router              = new LeafRouter();
                rSettings           = new RouterSettings(routerEP);
                rSettings.AppName   = rSettings.AppName + " (config boot)";
                rSettings.CloudEP   = cloudEP;
                rSettings.EnableP2P = enableP2P;

                router.Start(rSettings);

                ack        = (GetConfigAck)router.Query(configEP, new GetConfigMsg(machineName, exeFile, exeVersion, usage));
                configText = ack.ConfigText;
            }
            catch (Exception e)
            {
                queryException = e;
                configText     = null;
            }
            finally
            {
                if (router != null)
                {
                    router.Stop();
                }
            }

            if (configText != null)
            {
                // Cache the query result if requested

                if (!string.IsNullOrWhiteSpace(cacheFile) && String.Compare(cacheFile, "(no-cache)", true) != 0)
                {
                    StreamWriter writer;

                    try
                    {
                        writer = new StreamWriter(cacheFile);
                        writer.Write(configText);
                        writer.Close();
                    }
                    catch
                    {
                    }
                }
            }
            else
            {
                // Try loading a cached configuration

                if (string.IsNullOrWhiteSpace(cacheFile))
                {
                    SysLog.LogException(queryException, "GetConfig query failed with no cached settings.");
                }
                else
                {
                    StreamReader reader;

                    SysLog.LogWarning("GetConfig query failed: Loading cached settings.");

                    try
                    {
                        reader     = new StreamReader(cacheFile);
                        configText = reader.ReadToEnd();
                        reader.Close();
                    }
                    catch
                    {
                        configText = null;
                    }
                }
            }

            return(configText);
        }