コード例 #1
0
        protected JobbrServer GivenRunningServerWithWebApi(string url = "")
        {
            var builder = new JobbrBuilder();

            if (string.IsNullOrWhiteSpace(url))
            {
                var nextTcpPort = NextFreeTcpPort();
                this.BackendAddress = $"http://localhost:{nextTcpPort}";
            }
            else
            {
                this.BackendAddress = url;
            }

            builder.AddWebApi(conf =>
            {
                conf.BackendAddress = this.BackendAddress;
            });

            builder.Register <IJobbrComponent>(typeof(ExposeStorageProvider));

            var server = builder.Create();

            server.Start();

            return(server);
        }
コード例 #2
0
        public void WithInMemoryServer_InvalidPort_ServerStartFails()
        {
            var nextFreeTcpPort = TcpPortHelper.NextFreeTcpPort();

            // intentionally block port
            var listener = new TcpListener(IPAddress.Any, nextFreeTcpPort);

            listener.Start();

            var backendAddress = "http://*****:*****@"c:\windows\System32\cmd.exe";
            });

            var server = builder.Create();

            try
            {
                server.Start();
            }
            catch
            {
                // ignored
            }

            Assert.IsNotNull(listener);
            Assert.AreEqual(JobbrState.Error, server.State, "The server should be in error state if a component didn't start");
        }
コード例 #3
0
        protected static JobbrServer GivenAServerInstance()
        {
            var builder = new JobbrBuilder();

            builder.Register <IJobbrComponent>(typeof(ExposeAllServicesComponent));

            var server = builder.Create();

            return(server);
        }
コード例 #4
0
        public void StartingJobbr_ComponentFails_ExceptionIsThrown()
        {
            var builder = new JobbrBuilder();

            builder.Register <IJobbrComponent>(typeof(FaultyComponent));

            var jobbr = builder.Create();

            jobbr.Start();
        }
コード例 #5
0
        static void Main(string[] args)
        {
            var jobbrBuilder = new JobbrBuilder();

            jobbrBuilder.AddForkedExecution(config =>
            {
                config.JobRunDirectory             = "C:/temp";
                config.JobRunnerExecutable         = "Sandbox.JobRunner.exe";
                config.MaxConcurrentProcesses      = 4;
                config.IsRuntimeWaitingForDebugger = false;
            });

            jobbrBuilder.AddJobs(repo =>
            {
                repo.Define("ProgressJob", "Sandbox.JobRunner.Jobs.ProgressJob")
                .WithTrigger("* * * * *")
                .WithTrigger(DateTime.UtcNow.AddSeconds(30), new RunParameter {
                    Param1 = "foo", Param2 = 1337
                });

                repo.Define("ParameterizedJob", "Sandbox.JobRunner.Jobs.ParameterizedJob")
                .WithParameter(new RunParameter {
                    Param1 = "default job param", Param2 = 1000
                })
                .WithTrigger("* * * * *")
                .WithTrigger(DateTime.UtcNow.AddSeconds(30), new RunParameter {
                    Param1 = "customized", Param2 = 5000
                });

                repo.Define("ArtefactJob", "Sandbox.JobRunner.Jobs.JobWithArtefacts")
                .WithTrigger("* * * * *");
            });

            jobbrBuilder.AddWebApi(config =>
            {
                config.BackendAddress = "http://localhost:1337";
            });

            jobbrBuilder.AddMsSqlStorage(c =>
            {
                c.ConnectionString        = "Data Source=localhost\\sqlexpress;Initial Catalog=JobbrWebApiSandbox;Integrated Security=True";
                c.DialectProvider         = new SqlServer2017OrmLiteDialectProvider();
                c.CreateTablesIfNotExists = true;
            });

            using (var server = jobbrBuilder.Create())
            {
                server.Start(20000);

                Console.ReadLine();

                server.Stop();
            }
        }
コード例 #6
0
        public void CreateJobber_WithConsoleCapturer_CaptureMessagesFromConsole()
        {
            using (var capture = new ConsoleCapturer())
            {
                var builder = new JobbrBuilder();

                builder.Create();

                var allLogEntries = capture.GetLines();
                Assert.IsTrue(allLogEntries.Any());
            }
        }
コード例 #7
0
        public void ValidatorForSettings_ThrowsException_PreventsStart()
        {
            var builder = new JobbrBuilder();

            builder.Add <DemoSettings>(new DemoSettings());

            builder.Add <IConfigurationValidator>(new DemoComponentValidator(validationShouldFail: false, throwExecption: true));

            var jobbr = builder.Create();

            jobbr.Start();
        }
コード例 #8
0
        public void RegisterCustomJobStorageProvider_AfterCreation_CorrectTypeIsActivated()
        {
            var builder = new JobbrBuilder();

            builder.Register <IJobStorageProvider>(typeof(CustomJobStorageProvider));
            builder.Register <IJobbrComponent>(typeof(ExposeAllServicesComponent));

            builder.Create();

            Assert.IsNotNull(ExposeAllServicesComponent.Instance.ArtefactsStorageProvider);
            Assert.AreEqual(typeof(CustomJobStorageProvider),
                            ExposeAllServicesComponent.Instance.JobStorageProvider.GetType());
        }
コード例 #9
0
        public void Configuration_WithInvalidPath_ThrowsExceptionOnJobStart()
        {
            var builder = new JobbrBuilder();

            builder.AddFileSystemArtefactStorage(config =>
            {
                config.DataDirectory = ":\\\\$^09//";
            });

            using (var server = builder.Create())
            {
                server.Start();
            }
        }
コード例 #10
0
        public void Configuration_WithPossibleUncPath_ThrowsExceptionOnJobStart()
        {
            var builder = new JobbrBuilder();

            builder.AddFileSystemArtefactStorage(config =>
            {
                config.DataDirectory = @"\\localhost\folder";
            });

            using (var server = builder.Create())
            {
                server.Start();
                Assert.AreEqual(JobbrState.Running, server.State);
            }
        }
コード例 #11
0
        public void RegisteredAsComponent_JobbrIsStarted_ProviderHasCorrectType()
        {
            var builder = new JobbrBuilder();

            builder.Register <IJobbrComponent>(typeof(ExposeStorageProvider));

            builder.AddMsSqlStorage(config =>
            {
                config.ConnectionString = @"Server=.\INSTANCENAME;Integrated Security=true;InitialCatalog=NotUsed;";
            });

            builder.Create();

            Assert.AreEqual(typeof(MsSqlStorageProvider), ExposeStorageProvider.Instance.JobStorageProvider.GetType());
        }
コード例 #12
0
        public void RegisteredAsComponent_WithoutConfiguration_DoesStart()
        {
            var builder = new JobbrBuilder();

            builder.AddWebApi();

            var server = builder.Create();

            server.Start();

            using (server)
            {
                Assert.AreEqual(JobbrState.Running, server.State, "Server should be possible to start with default configuration");
            }
        }
コード例 #13
0
        public void ValidatorForSettings_WhenRegistered_IsCalled()
        {
            var builder = new JobbrBuilder();

            builder.Add <DemoSettings>(new DemoSettings());
            var isCalled = false;

            builder.Add <IConfigurationValidator>(new DemoComponentValidator(s => isCalled = true));

            var jobbr = builder.Create();

            jobbr.Start();

            Assert.IsTrue(isCalled);
        }
コード例 #14
0
        public void Jobbr_WithRegisteredFileStorage_CanBeStarted()
        {
            var builder = new JobbrBuilder();

            builder.AddFileSystemArtefactStorage(config =>
            {
                config.DataDirectory = Directory.GetCurrentDirectory();
            });

            using (var server = builder.Create())
            {
                server.Start();

                Assert.AreEqual(JobbrState.Running, server.State);
            }
        }
コード例 #15
0
        public void RegisteredAsComponent_JobbrIsStarted_ProviderHasCorrectType()
        {
            GivenRavenFs();
            var builder = new JobbrBuilder();
            builder.Register<IJobbrComponent>(typeof(ExposeArtefactStorageProvider));

            builder.AddRavenFsArtefactStorage(config =>
            {
                config.FileSystem = Store.DefaultDatabase;
                config.Url = Store.Url;
            });

            builder.Create();

            Assert.AreEqual(typeof(RavenFsArtefactStorageProvider), ExposeArtefactStorageProvider.Instance.ArtefactStorageProvider.GetType());
        }
コード例 #16
0
        public void StartingJobber_GetsRunning_WhenStorageProviderTurnsHealthy()
        {
            var builder = new JobbrBuilder();

            builder.Register <IJobStorageProvider>(typeof(FaultyJobStorageProvider));

            var jobbr = builder.Create();
            var faultyJobStorageProvider = FaultyJobStorageProvider.Instance;

            faultyJobStorageProvider.DisableImplementation();
            jobbr.Start(1000);

            faultyJobStorageProvider.EnableImplementation();

            this.WaitForStatusChange(() => jobbr.State, 5000);

            Assert.AreEqual(JobbrState.Running, jobbr.State);
        }
コード例 #17
0
        public void ValidatorForSettings_WhenCalled_SettingsIsPassedThrough()
        {
            var builder = new JobbrBuilder();

            var    demoSettings       = new DemoSettings();
            object settingsToValidate = null;

            builder.Add <DemoSettings>(demoSettings);

            builder.Add <IConfigurationValidator>(new DemoComponentValidator(s => settingsToValidate = s));

            var jobbr = builder.Create();

            jobbr.Start();

            Assert.IsNotNull(settingsToValidate);
            Assert.AreSame(demoSettings, settingsToValidate);
        }
コード例 #18
0
        public void Configuration_WithInvalidDrive_ThrowsExceptionOnJobStart()
        {
            var builder = new JobbrBuilder();

            var possibleDriveLetters = Enumerable.Range(65, 91).Select(i => (char)i);
            var usedDriveLetters     = DriveInfo.GetDrives().Select(d => d.Name[0]);
            var invalidDrives        = possibleDriveLetters.Except(usedDriveLetters);

            builder.AddFileSystemArtefactStorage(config =>
            {
                config.DataDirectory = invalidDrives.First().ToString() + ":\\test";
            });

            using (var server = builder.Create())
            {
                server.Start();
            }
        }
コード例 #19
0
        public void CreateJobbr_WithNoExecutor_IssuesError()
        {
            using (var capture = new ConsoleCapturer())
            {
                var builder = new JobbrBuilder();

                // Register only Artefacts and JoStorage
                builder.Register <IArtefactsStorageProvider>(typeof(PseudoArfetacstStorageProvider));
                builder.Register <IJobStorageProvider>(typeof(PseudoJobStorageProvider));

                builder.Create();

                var artefactsWarnings = capture.GetLines("ERROR", "Executor").ToList();

                Assert.IsTrue(artefactsWarnings.Any());
                Assert.AreEqual(1, artefactsWarnings.Count);
            }
        }
コード例 #20
0
        public void CreateJobbr_WithNoArtefactsProvider_IssuesWarn()
        {
            using (var capture = new ConsoleCapturer())
            {
                var builder = new JobbrBuilder();

                // Register only Executor and JobStorage
                builder.Register <IJobExecutor>(typeof(PseudoExecutor));
                builder.Register <IJobStorageProvider>(typeof(PseudoJobStorageProvider));

                builder.Create();

                var artefactsWarnings = capture.GetLines("WARN", "Artefacts").ToList();

                Assert.IsTrue(artefactsWarnings.Any());
                Assert.AreEqual(1, artefactsWarnings.Count);
            }
        }
コード例 #21
0
        public void StartingJobbr_ComponentFails_IsInErrorState()
        {
            var builder = new JobbrBuilder();

            builder.Register <IJobbrComponent>(typeof(FaultyComponent));

            var jobbr = builder.Create();

            try
            {
                jobbr.Start();
            }
            catch (Exception)
            {
                // Eat exception if any to check for the state
            }

            Assert.AreEqual(JobbrState.Error, jobbr.State);
        }
コード例 #22
0
        public void Jobbr_WithRegisteredFileStorage_StorageProviderHasCorrectType()
        {
            var builder = new JobbrBuilder();

            builder.AddFileSystemArtefactStorage(config =>
            {
                config.DataDirectory = Directory.GetCurrentDirectory();
            });

            builder.Register <IJobbrComponent>(typeof(DirectServiceAccessComponent));

            using (var server = builder.Create())
            {
                server.Start();

                Assert.IsNotNull(DirectServiceAccessComponent.Instance.artefactStorageProvider);
                Assert.AreEqual(typeof(FileSystemArtefactsStorageProvider), DirectServiceAccessComponent.Instance.artefactStorageProvider.GetType());
            }
        }
コード例 #23
0
        public void CreateJobbr_WithAllRequiredComponents_NoErrorNoWarn()
        {
            using (var capture = new ConsoleCapturer())
            {
                var builder = new JobbrBuilder();

                // Register only Artefacts and JoStorage
                builder.Register <IArtefactsStorageProvider>(typeof(PseudoArfetacstStorageProvider));
                builder.Register <IJobStorageProvider>(typeof(PseudoJobStorageProvider));
                builder.Register <IJobExecutor>(typeof(PseudoExecutor));

                builder.Create();

                var errors   = capture.GetLines("ERROR").ToList();
                var warnings = capture.GetLines("WARN").ToList();

                Assert.IsFalse(errors.Any());
                Assert.IsFalse(warnings.Any());
            }
        }
コード例 #24
0
        public void WithInMemoryServer_ServerHasStarted_StatusEndpointIsAvailable()
        {
            var backendAddress = "http://*****:*****@"c:\windows\System32\cmd.exe";
            });

            var server = builder.Create();

            server.Start();

            var statusResponse = new HttpClient().GetAsync(backendAddress + "/fex/status").Result;

            Assert.AreEqual(HttpStatusCode.OK, statusResponse.StatusCode);
        }
コード例 #25
0
        public void RegisteredAsComponent_WithBasicConfiguration_ServerDoesStart()
        {
            GivenRavenFs();

            var builder = new JobbrBuilder();
            builder.Register<IJobbrComponent>(typeof(ExposeArtefactStorageProvider));

            builder.AddRavenFsArtefactStorage(config =>
            {
                config.FileSystem = Store.DefaultDatabase;
                config.Url = Store.Url;
            });


            using (var server = builder.Create())
            {
                server.Start();

                Assert.AreEqual(JobbrState.Running, server.State, "Server should be possible to start with a proper configuration.");
            }
        }
コード例 #26
0
        public void StartJobbr_WithAllRequiredComponents_NoErrorNoWarn()
        {
            using (var capture = new ConsoleCapturer())
            {
                var builder = new JobbrBuilder();

                // Register only Artefacts and JoStorage
                builder.Register <IArtefactsStorageProvider>(typeof(PseudoArfetacstStorageProvider));
                builder.Register <IJobStorageProvider>(typeof(PseudoJobStorageProvider));
                builder.Register <IJobExecutor>(typeof(PseudoExecutor));

                var server = builder.Create();

                server.Start(20000);

                var errors   = capture.GetLines("ERROR").ToList();
                var warnings = capture.GetLines("WARN").ToList();
                var fatals   = capture.GetLines("FATAL").ToList();

                Assert.IsFalse(fatals.Any(), "Got too manny fatals: \n\n * " + string.Join("\n * ", fatals));
                Assert.IsFalse(errors.Any(), "Got too manny errors: \n\n * " + string.Join("\n * ", errors));
                Assert.IsFalse(warnings.Any(), "Got too manny warnings: \n\n * " + string.Join("\n * ", warnings));
            }
        }
コード例 #27
0
        public static void Main(string[] args)
        {
            var jobbrBuilder = new JobbrBuilder();

            // Dispatch the execution to a separate process. See the Project "Demo.JobRunner" for details
            jobbrBuilder.AddForkedExecution(config =>
            {
                config.JobRunDirectory             = "C:/temp";
                config.JobRunnerExecutable         = "../../../Demo.JobRunner/bin/Debug/Demo.JobRunner.exe";
                config.MaxConcurrentProcesses      = 1;
                config.IsRuntimeWaitingForDebugger = true;
            }
                                            );

            // Setup an initial set of jobs with a unique name and the corresponding CLR Type.
            // Note: The Server does not reference the assembly containing the type since the Runner (see above) will activate and execute the job
            jobbrBuilder.AddJobs(repo =>
            {
                repo.Define("ProgressJob", "Demo.MyJobs.ProgressJob")
                .WithTrigger("* * * * *");
            });

            // Expose a Rest-API that is compatible with any browser and the Jobbr.Client
            jobbrBuilder.AddWebApi(config =>
            {
                config.BackendAddress = "http://*****:*****@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\temp\jobbr.mdf;Integrated Security=True;Connect Timeout=30";
            //    c.Schema = "Jobbr";
            //});

            // Uncomment to use RavenDB as storage
            // (start a ravendb server by executing packages\RavenDB.Server.3.5.3\tools\RavenDB.Server.exe)
            //jobbrBuilder.AddRavenDbStorage(config =>
            //{
            //    config.Url = "http://localhost:8080";
            //    config.Database = "Jobbr";
            //});

            // Register your very own component that gets as JobbrComponent and can request specific implementations with constructor injection
            jobbrBuilder.Register <IJobbrComponent>(typeof(MyExtension));

            using (var server = jobbrBuilder.Create())
            {
                server.Start();

                // Trigger a new Job from here. How-ever this does not make sense usually...
                // Better approach would be to use the Client Libraries to access the WebAPI
                // MyExtension.Instance.JobManagementService.AddTrigger(new InstantTrigger() { JobId = 1, IsActive = true });

                Console.ReadLine();

                server.Stop();
            }
        }
コード例 #28
0
        public static void Main(string[] args)
        {
            const string baseAddress     = "http://localhost:1338/";
            const string jobRunDirectory = "C:/temp";

            if (Directory.Exists(jobRunDirectory) == false)
            {
                Directory.CreateDirectory(jobRunDirectory);
            }

            var jobbrBuilder = new JobbrBuilder();

            jobbrBuilder.AddForkedExecution(config =>
            {
                config.JobRunDirectory        = jobRunDirectory;
                config.JobRunnerExecutable    = "../../../Sample.JobRunner/bin/Debug/Sample.JobRunner.exe";
                config.MaxConcurrentProcesses = 2;
            });

            jobbrBuilder.AddJobs(repo =>
            {
                repo.Define(typeof(MinutelyJob).Name, typeof(MinutelyJob).FullName)
                .WithTrigger("* * * * *", parameters: new { SomeProperty = "foobar" }, validFromDateTimeUtc: new DateTime(2000, 1, 1), validToDateTimeUtc: new DateTime(2100, 1, 1), userId: "ozu", userDisplayName: "olibanjoli")
                .WithParameter(new
                {
                    Foo    = "Bar",
                    Nested = new
                    {
                        Priority = "High",
                        Comment  = "Heyho!"
                    }
                })
                .WithTrigger(DateTime.Now.Add(TimeSpan.FromDays(1337)), new { Foo = "bar" }, "ozu", "olibanjoli");

                repo.Define(typeof(MinutelyJob).Name + "-2", typeof(MinutelyJob).FullName)
                .WithTrigger("* * * * *", parameters: new { SomeProperty = "foobar" }, validFromDateTimeUtc: new DateTime(2000, 1, 1), validToDateTimeUtc: new DateTime(2100, 1, 1), userId: "ozu", userDisplayName: "olibanjoli")
                .WithParameter(new
                {
                    Foo    = "Bar",
                    Nested = new
                    {
                        Priority = "High",
                        Comment  = "Heyho!"
                    }
                });

                repo.Define(typeof(HourlyJob).Name, typeof(HourlyJob).FullName)
                .WithTrigger("0 * * * *", parameters: new { Name = "Jack Bauer", Unit = "CTU", Skills = "Headshot" })
                .WithParameter(new
                {
                    Foo    = "Bar",
                    Nested = new
                    {
                        Equipment = "Nuke",
                    }
                });


                repo.Define(typeof(DailyJob).Name, typeof(DailyJob).FullName)
                .WithTrigger("0 0 * * *", parameters: new { Name = "Jack Bauer", Unit = "CTU", Skills = "Headshot" })
                .WithParameter(new
                {
                    Foo    = "Bar",
                    Nested = new
                    {
                        Equipment = "Nuke",
                    }
                });

                repo.Define(typeof(FailingJob).Name, typeof(FailingJob).FullName)
                .WithTrigger("*/2 * * * *", parameters: new { SomeProperty = "foobar" })
                .WithParameter(new
                {
                    Bla = "Blub",
                    Foo = "Bar"
                });
            });

            jobbrBuilder.AddWebApi(config => config.BackendAddress = $"{baseAddress}api");
            jobbrBuilder.AddDashboard(config =>
            {
                config.BackendAddress          = $"{baseAddress}";
                config.SoftDeleteJobRunOnRetry = true;
            });
            //jobbrBuilder.AddRavenDbStorage(config =>
            //{
            //    config.Url = "http://localhost:8080/";
            //    config.Database = "Jobbr";
            //});
            jobbrBuilder.AddMsSqlStorage(config =>
            {
                config.ConnectionString        = "Data Source=localhost\\SQLExpress;Initial Catalog=JobbrDashboard2;Connect Timeout=5;Integrated Security=True";
                config.CreateTablesIfNotExists = true;
            });

            using (var jobbr = jobbrBuilder.Create())
            {
                jobbr.Start(20000);
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("Jobbr is running. Press Enter to quit");
                Console.ResetColor();
                Console.ReadLine();
            }
        }