diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..72170094 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 + +[*.java] +indent_style = space +indent_size = 4 diff --git a/src/main/notice/NOTICE.template b/.license/NOTICE.template similarity index 100% rename from src/main/notice/NOTICE.template rename to .license/NOTICE.template diff --git a/src/main/license-header.txt b/.license/license-header.txt similarity index 100% rename from src/main/license-header.txt rename to .license/license-header.txt diff --git a/src/main/notice/license-mappings.xml b/.license/license-mappings.xml similarity index 100% rename from src/main/notice/license-mappings.xml rename to .license/license-mappings.xml diff --git a/.travis.yml b/.travis.yml index d07125b8..4b991b78 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +dist: trusty sudo: false cache: directories: diff --git a/NOTICE b/NOTICE index 8370ef8d..2e8c9470 100644 --- a/NOTICE +++ b/NOTICE @@ -8,25 +8,106 @@ Licensed under Apache 2 - http://www.apache.org/licenses/LICENSE-2.0.html This software includes third party software subject to the following licenses: + AntLR Parser Generator under BSD License Apache Commons Codec under Apache License, Version 2.0 Apache Commons Compress under Apache License, Version 2.0 Apache Commons IO under Apache License, Version 2.0 Apache Commons Lang under Apache License, Version 2.0 + Apache Log4j API under Apache License, Version 2.0 + Apache Log4j to SLF4J Adapter under Apache License, Version 2.0 + ASM based accessors helper used by json-smart under The Apache Software License, Version 2.0 + ASM Core under BSD + AspectJ weaver under Eclipse Public License - v 1.0 + AssertJ fluent assertions under Apache License, Version 2.0 + Bean Validation API under Apache License 2.0 + Byte Buddy (without dependencies) under Apache License, Version 2.0 + Byte Buddy Java agent under Apache License, Version 2.0 + ClassMate under The Apache Software License, Version 2.0 cron-utils under Apache 2.0 - Db-scheduler under The Apache Software License, Version 2.0 + db-scheduler: Core under The Apache Software License, Version 2.0 + db-scheduler: Examples under The Apache Software License, Version 2.0 + db-scheduler: Examples: Spring Boot under The Apache Software License, Version 2.0 + db-scheduler: Parent under The Apache Software License, Version 2.0 + db-scheduler: Spring Boot Starter under The Apache Software License, Version 2.0 + dom4j under BSD 3-clause New License Guava: Google Core Libraries for Java under The Apache Software License, Version 2.0 Hamcrest Core under New BSD License Hamcrest library under New BSD License + HdrHistogram under Public Domain, per Creative Commons CC0 + Hibernate Commons Annotations under GNU Lesser General Public License v2.1 or later + Hibernate ORM - hibernate-core under GNU Library General Public License v2.1 or later + Hibernate Validator Engine under Apache License 2.0 HikariCP under The Apache Software License, Version 2.0 HyperSQL Database under HSQLDB License, a BSD open source license + Jackson datatype: jdk8 under The Apache Software License, Version 2.0 + Jackson datatype: JSR310 under The Apache Software License, Version 2.0 + Jackson-annotations under The Apache Software License, Version 2.0 + Jackson-core under The Apache Software License, Version 2.0 + jackson-databind under The Apache Software License, Version 2.0 + Jackson-module-parameter-names under The Apache Software License, Version 2.0 + Java Annotation Indexer under Apache License, Version 2.0 java-8-matchers under MIT License + JavaBeans Activation Framework API jar under CDDL/GPLv2+CE + Javassist under MPL 1.1 or LGPL 2.1 or Apache License 2.0 + javax.annotation API under CDDL + GPLv2 with classpath exception + javax.persistence-api under Eclipse Public License v1.0 or Eclipse Distribution License v. 1.0 + javax.transaction API under CDDL + GPLv2 with classpath exception + jaxb-api under CDDL 1.1 or GPL2 w/ CPE + JBoss Logging 3 under Apache License, version 2.0 JCL 1.2 implemented over SLF4J under MIT License + JSON library from Android SDK under Apache License 2.0 + JSON Small and Fast Parser under The Apache Software License, Version 2.0 + JSONassert under The Apache Software License, Version 2.0 + JUL to SLF4J bridge under MIT License JUnit under Eclipse Public License 1.0 + LatencyUtils under Public Domain, per Creative Commons CC0 + Logback Classic Module under Eclipse Public License - v 1.0 or GNU Lesser General Public License + Logback Core Module under Eclipse Public License - v 1.0 or GNU Lesser General Public License Micro JDBC under The Apache Software License, Version 2.0 + micrometer-core under The Apache Software License, Version 2.0 + mockito-core under The MIT License + Objenesis under Apache 2 + org.xmlunit:xmlunit-core under The Apache Software License, Version 2.0 otj-pg-embedded under Apache License, Version 2.0 PostgreSQL JDBC Driver - JDBC 4.2 under The PostgreSQL License + project ':json-path' under The Apache Software License, Version 2.0 SLF4J API Module under MIT License SLF4J Simple Binding under MIT License + SnakeYAML under Apache License, Version 2.0 + Spring AOP under Apache License, Version 2.0 + Spring Aspects under Apache License, Version 2.0 + Spring Beans under Apache License, Version 2.0 + Spring Boot under Apache License, Version 2.0 + Spring Boot Actuator under Apache License, Version 2.0 + Spring Boot Actuator AutoConfigure under Apache License, Version 2.0 + Spring Boot Actuator Starter under Apache License, Version 2.0 + Spring Boot AOP Starter under Apache License, Version 2.0 + Spring Boot AutoConfigure under Apache License, Version 2.0 + Spring Boot Data JPA Starter under Apache License, Version 2.0 + Spring Boot JDBC Starter under Apache License, Version 2.0 + Spring Boot Json Starter under Apache License, Version 2.0 + Spring Boot Logging Starter under Apache License, Version 2.0 + Spring Boot Starter under Apache License, Version 2.0 + Spring Boot Test under Apache License, Version 2.0 + Spring Boot Test Auto-Configure under Apache License, Version 2.0 + Spring Boot Test Starter under Apache License, Version 2.0 + Spring Boot Tomcat Starter under Apache License, Version 2.0 + Spring Boot Web Starter under Apache License, Version 2.0 + Spring Commons Logging Bridge under Apache License, Version 2.0 + Spring Context under Apache License, Version 2.0 + Spring Core under Apache License, Version 2.0 + Spring Data Core under Apache License, Version 2.0 + Spring Data JPA under Apache License, Version 2.0 + Spring Expression Language (SpEL) under Apache License, Version 2.0 + Spring JDBC under Apache License, Version 2.0 + Spring Object/Relational Mapping under Apache License, Version 2.0 + Spring TestContext Framework under Apache License, Version 2.0 + Spring Transaction under Apache License, Version 2.0 + Spring Web under Apache License, Version 2.0 + Spring Web MVC under Apache License, Version 2.0 + tomcat-embed-core under Apache License, Version 2.0 + tomcat-embed-el under Apache License, Version 2.0 + tomcat-embed-websocket under Apache License, Version 2.0 XZ for Java under Public Domain diff --git a/README.md b/README.md index 358430d9..32bf702a 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ final Scheduler scheduler = Scheduler scheduler.start(); ``` -For more examples, continue reading. For details on the inner workings, see [How it works](#how-it-works). +For more examples, continue reading. For details on the inner workings, see [How it works](#how-it-works). If you have a Spring Boot application, have a look at [Spring Boot Usage](#spring-boot-usage). ## Examples @@ -164,6 +164,46 @@ The library contains a number of Schedule-implementations for recurring tasks. S | `.cron(String)` | Spring-style cron-expression. | +## Spring Boot usage + +For Spring Boot applications, there is a starter `db-scheduler-spring-boot-starter` making the scheduler-wiring very simple. (See [full example project](https://github.com/kagkarlsson/db-scheduler/tree/master/examples/spring-boot-example)). + +### Prerequisites + +- An existing Spring Boot application +- A working `DataSource` with schema initialized. (In the example HSQLDB is used and schema is automatically applied.) + +### Getting started + +1. Add the following Maven dependency + ```xml + + com.github.kagkarlsson + db-scheduler-spring-boot-starter + 5.3 + + ``` + **NOTE**: This includes the db-scheduler dependency itself. +2. In your configuration, expose your `Task`'s as Spring beans. If they are recurring, they will automatically be picked up and started. +3. Run the app. + +### Configuration options + +Configuration is mainly done via `application.properties`. Configuration of scheduler-name, serializer and executor-service is done by adding a bean of type `DbSchedulerCustomizer` to your Spring context. + +``` +# application.properties example showing default values + +db-scheduler.enabled=true +db-scheduler.heartbeat-interval=5m +db-scheduler.polling-interval=30s +db-scheduler.polling-limit= +db-scheduler.table-name=scheduled_tasks +db-scheduler.immediate-execution-enabled=false +db-scheduler.scheduler-name= +db-scheduler.threads=10 +``` + ## How it works diff --git a/db-scheduler-boot-starter/NOTICE b/db-scheduler-boot-starter/NOTICE new file mode 100644 index 00000000..c0b0d046 --- /dev/null +++ b/db-scheduler-boot-starter/NOTICE @@ -0,0 +1,71 @@ +Db-scheduler + +Copyright 2015 Gustav Karlsson. All Rights Reserved. + +This product includes software developed by Gustav Karlsson. +Licensed under Apache 2 - http://www.apache.org/licenses/LICENSE-2.0.html + + +This software includes third party software subject to the following licenses: + + Apache Log4j API under Apache License, Version 2.0 + Apache Log4j to SLF4J Adapter under Apache License, Version 2.0 + ASM based accessors helper used by json-smart under The Apache Software License, Version 2.0 + ASM Core under BSD + AssertJ fluent assertions under Apache License, Version 2.0 + Bean Validation API under Apache License 2.0 + Byte Buddy (without dependencies) under Apache License, Version 2.0 + Byte Buddy Java agent under Apache License, Version 2.0 + ClassMate under The Apache Software License, Version 2.0 + cron-utils under Apache 2.0 + db-scheduler: Core under The Apache Software License, Version 2.0 + db-scheduler: Spring Boot Starter under The Apache Software License, Version 2.0 + Guava: Google Core Libraries for Java under The Apache Software License, Version 2.0 + Hamcrest Core under New BSD License + Hamcrest library under New BSD License + Hibernate Validator Engine under Apache License 2.0 + HikariCP under The Apache Software License, Version 2.0 + HyperSQL Database under HSQLDB License, a BSD open source license + Jackson datatype: JSR310 under The Apache Software License, Version 2.0 + Jackson-annotations under The Apache Software License, Version 2.0 + Jackson-core under The Apache Software License, Version 2.0 + jackson-databind under The Apache Software License, Version 2.0 + javax.annotation API under CDDL + GPLv2 with classpath exception + JBoss Logging 3 under Apache License, version 2.0 + JSON library from Android SDK under Apache License 2.0 + JSON Small and Fast Parser under The Apache Software License, Version 2.0 + JSONassert under The Apache Software License, Version 2.0 + JUL to SLF4J bridge under MIT License + JUnit under Eclipse Public License 1.0 + Logback Classic Module under Eclipse Public License - v 1.0 or GNU Lesser General Public License + Logback Core Module under Eclipse Public License - v 1.0 or GNU Lesser General Public License + Micro JDBC under The Apache Software License, Version 2.0 + mockito-core under The MIT License + Objenesis under Apache 2 + org.xmlunit:xmlunit-core under The Apache Software License, Version 2.0 + project ':json-path' under The Apache Software License, Version 2.0 + SLF4J API Module under MIT License + SnakeYAML under Apache License, Version 2.0 + Spring AOP under Apache License, Version 2.0 + Spring Beans under Apache License, Version 2.0 + Spring Boot under Apache License, Version 2.0 + Spring Boot Actuator under Apache License, Version 2.0 + Spring Boot Actuator AutoConfigure under Apache License, Version 2.0 + Spring Boot Auto-Configure Annotation Processor under Apache License, Version 2.0 + Spring Boot AutoConfigure under Apache License, Version 2.0 + Spring Boot Configuration Processor under Apache License, Version 2.0 + Spring Boot JDBC Starter under Apache License, Version 2.0 + Spring Boot Logging Starter under Apache License, Version 2.0 + Spring Boot Starter under Apache License, Version 2.0 + Spring Boot Test under Apache License, Version 2.0 + Spring Boot Test Auto-Configure under Apache License, Version 2.0 + Spring Boot Test Starter under Apache License, Version 2.0 + Spring Commons Logging Bridge under Apache License, Version 2.0 + Spring Context under Apache License, Version 2.0 + Spring Core under Apache License, Version 2.0 + Spring Expression Language (SpEL) under Apache License, Version 2.0 + Spring JDBC under Apache License, Version 2.0 + Spring TestContext Framework under Apache License, Version 2.0 + Spring Transaction under Apache License, Version 2.0 + + diff --git a/db-scheduler-boot-starter/pom.xml b/db-scheduler-boot-starter/pom.xml new file mode 100644 index 00000000..5b71cbd0 --- /dev/null +++ b/db-scheduler-boot-starter/pom.xml @@ -0,0 +1,102 @@ + + + + db-scheduler-parent + com.github.kagkarlsson + 5.3-SNAPSHOT + + 4.0.0 + + db-scheduler-spring-boot-starter + db-scheduler: Spring Boot Starter + A starter for Spring Boot that will configure db-scheduler + + + ${project.parent.basedir}/.license + + + + + + com.github.kagkarlsson + db-scheduler + ${project.version} + + + org.slf4j + slf4j-api + + + + + org.springframework + spring-context + + + org.springframework + spring-jdbc + + + org.springframework.boot + spring-boot-actuator + + + org.springframework.boot + spring-boot + + + org.springframework.boot + spring-boot-autoconfigure + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + + + + + javax.validation + validation-api + provided + + + org.hibernate.validator + hibernate-validator + provided + + + + + junit + junit + + + org.springframework.boot + spring-boot-test + test + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-jdbc + test + + + org.assertj + assertj-core + test + + + org.hsqldb + hsqldb + test + + + diff --git a/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/actuator/DbSchedulerHealthIndicator.java b/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/actuator/DbSchedulerHealthIndicator.java new file mode 100644 index 00000000..4e60e25b --- /dev/null +++ b/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/actuator/DbSchedulerHealthIndicator.java @@ -0,0 +1,34 @@ +package com.github.kagkarlsson.scheduler.boot.actuator; + +import com.github.kagkarlsson.scheduler.Scheduler; +import com.github.kagkarlsson.scheduler.SchedulerState; +import java.util.Objects; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; + +public class DbSchedulerHealthIndicator implements HealthIndicator { + private final SchedulerState state; + + public DbSchedulerHealthIndicator(Scheduler scheduler) { + this.state = Objects.requireNonNull(scheduler).getSchedulerState(); + } + + @Override + public Health health() { + if (state.isStarted() && !state.isShuttingDown()) { + return Health.up() + .withDetail("state", "started") + .build(); + } else if (state.isStarted() && state.isShuttingDown()) { + return Health.outOfService() + .withDetail("state", "shutting_down") + .build(); + } else if (!state.isStarted() && !state.isShuttingDown()) { + return Health.down() + .withDetail("state", "not_started") + .build(); + } else { + return Health.down().build(); + } + } +} diff --git a/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/autoconfigure/DbSchedulerAutoConfiguration.java b/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/autoconfigure/DbSchedulerAutoConfiguration.java new file mode 100644 index 00000000..ac2f54ac --- /dev/null +++ b/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/autoconfigure/DbSchedulerAutoConfiguration.java @@ -0,0 +1,139 @@ +package com.github.kagkarlsson.scheduler.boot.autoconfigure; + +import com.github.kagkarlsson.scheduler.Scheduler; +import com.github.kagkarlsson.scheduler.SchedulerBuilder; +import com.github.kagkarlsson.scheduler.SchedulerName; +import com.github.kagkarlsson.scheduler.boot.actuator.DbSchedulerHealthIndicator; +import com.github.kagkarlsson.scheduler.boot.config.DbSchedulerCustomizer; +import com.github.kagkarlsson.scheduler.boot.config.DbSchedulerProperties; +import com.github.kagkarlsson.scheduler.task.OnStartup; +import com.github.kagkarlsson.scheduler.task.Task; +import java.util.List; +import java.util.Objects; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.actuate.health.HealthIndicatorRegistry; +import org.springframework.boot.autoconfigure.AutoConfigurationPackage; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; + +@Configuration +@EnableConfigurationProperties(DbSchedulerProperties.class) +@AutoConfigurationPackage +@AutoConfigureAfter({DataSourceAutoConfiguration.class, HealthIndicatorAutoConfiguration.class}) +@ConditionalOnBean(DataSource.class) +@ConditionalOnProperty(value = "db-scheduler.enabled", matchIfMissing = true) +public class DbSchedulerAutoConfiguration { + private static final Logger log = LoggerFactory.getLogger(DbSchedulerAutoConfiguration.class); + private static Predicate> shouldBeStarted = task -> task instanceof OnStartup; + + private final DbSchedulerProperties config; + private final DataSource existingDataSource; + private final List> configuredTasks; + + public DbSchedulerAutoConfiguration(DbSchedulerProperties dbSchedulerProperties, + DataSource dataSource, List> configuredTasks) { + this.config = Objects.requireNonNull(dbSchedulerProperties, "Can't configure db-scheduler without required configuration"); + this.existingDataSource = Objects.requireNonNull(dataSource, "An existing javax.sql.DataSource is required"); + this.configuredTasks = Objects.requireNonNull(configuredTasks, "At least one Task must be configured"); + } + + /** + * Provide an empty customizer if not present in the context. + */ + @ConditionalOnMissingBean + @Bean + public DbSchedulerCustomizer noopCustomizer() { + return new DbSchedulerCustomizer() { + }; + } + + @ConditionalOnBean(DataSource.class) + @ConditionalOnMissingBean + @Bean(initMethod = "start", destroyMethod = "stop") + public Scheduler scheduler(DbSchedulerCustomizer customizer) { + log.info("Creating db-scheduler using tasks from Spring context: {}", configuredTasks); + + // Ensure that we are using a transactional aware data source + DataSource transactionalDataSource = configureDataSource(existingDataSource); + + // Instantiate a new builder + final SchedulerBuilder builder = Scheduler.create(transactionalDataSource, nonStartupTasks(configuredTasks)); + + builder.threads(config.getThreads()); + + // Polling + builder.pollingInterval(config.getPollingInterval()); + config.getPollingLimit().ifPresent(builder::pollingLimit); + + builder.heartbeatInterval(config.getHeartbeatInterval()); + + // Use scheduler name implementation from customizer if available, otherwise use + // configured scheduler name (String). If both is absent, use the library default + if (customizer.schedulerName().isPresent()) { + builder.schedulerName(customizer.schedulerName().get()); + } else if (config.getSchedulerName() != null) { + builder.schedulerName(new SchedulerName.Fixed(config.getSchedulerName())); + } + + builder.tableName(config.getTableName()); + + // Use custom serializer if provided + customizer.serializer().ifPresent(builder::serializer); + + if (config.isImmediateExecutionEnabled()) { + builder.enableImmediateExecution(); + } + + // Use custom executor service if provided + customizer.executorService().ifPresent(builder::executorService); + + // Add recurring jobs and jobs that implements OnStartup + builder.startTasks(startupTasks(configuredTasks)); + + return builder.build(); + } + + @ConditionalOnBean({Scheduler.class, HealthIndicatorRegistry.class}) + @Bean + public HealthIndicator dbScheduler(Scheduler scheduler) { + return new DbSchedulerHealthIndicator(scheduler); + } + + private static DataSource configureDataSource(DataSource existingDataSource) { + if (existingDataSource instanceof TransactionAwareDataSourceProxy) { + log.debug("Using an already transaction aware DataSource"); + return existingDataSource; + } + + log.debug("The configured DataSource is not transaction aware: '{}'. Wrapping in TransactionAwareDataSourceProxy.", existingDataSource); + + return new TransactionAwareDataSourceProxy(existingDataSource); + } + + @SuppressWarnings("unchecked") + private static & OnStartup> List startupTasks(List> tasks) { + return tasks.stream() + .filter(shouldBeStarted) + .map(task -> (T) task) + .collect(Collectors.toList()); + } + + private static List> nonStartupTasks(List> tasks) { + return tasks.stream() + .filter(shouldBeStarted.negate()) + .collect(Collectors.toList()); + } +} diff --git a/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/config/DbSchedulerCustomizer.java b/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/config/DbSchedulerCustomizer.java new file mode 100644 index 00000000..e458f8b7 --- /dev/null +++ b/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/config/DbSchedulerCustomizer.java @@ -0,0 +1,33 @@ +package com.github.kagkarlsson.scheduler.boot.config; + +import com.github.kagkarlsson.scheduler.SchedulerName; +import com.github.kagkarlsson.scheduler.Serializer; +import java.util.Optional; +import java.util.concurrent.ExecutorService; + +/** + * Provides functionality for customizing various aspects of the db-scheduler configuration that + * is not easily done with properties. + */ +public interface DbSchedulerCustomizer { + /** + * Provide a custom {@link SchedulerName} implementation. + */ + default Optional schedulerName() { + return Optional.empty(); + } + + /** + * A custom serializer for task data. + */ + default Optional serializer() { + return Optional.empty(); + } + + /** + * Provide an existing {@link ExecutorService} instance. + */ + default Optional executorService() { + return Optional.empty(); + } +} diff --git a/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/config/DbSchedulerProperties.java b/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/config/DbSchedulerProperties.java new file mode 100644 index 00000000..5f3bbf0e --- /dev/null +++ b/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/config/DbSchedulerProperties.java @@ -0,0 +1,134 @@ +package com.github.kagkarlsson.scheduler.boot.config; + +import static java.time.temporal.ChronoUnit.MINUTES; +import static java.time.temporal.ChronoUnit.SECONDS; + +import com.github.kagkarlsson.scheduler.JdbcTaskRepository; +import java.time.Duration; +import java.util.Optional; +import javax.validation.constraints.NotNull; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.convert.DurationUnit; +import org.springframework.validation.annotation.Validated; + +@Validated +@ConfigurationProperties("db-scheduler") +public class DbSchedulerProperties { + /** + * Whether to enable auto configuration of the db-scheduler. + */ + private boolean enabled = true; + + /*** + *

Number of threads. + */ + private int threads = 10; + + /** + * How often to update the heartbeat timestamp for running executions. + */ + @DurationUnit(MINUTES) + @NotNull + private Duration heartbeatInterval = Duration.ofMinutes(5); + + /** + *

Name of this scheduler-instance. The name is stored in the database when an execution is + * picked by a scheduler. + * + *

If the name is {@code null} or not configured, the hostname of the running machine will be + * used. + */ + private String schedulerName; + + /** + *

Name of the table used to track task-executions. Must match the database. Change name in the + * table definitions accordingly when creating or modifying the table. + */ + @NotNull + private String tableName = JdbcTaskRepository.DEFAULT_TABLE_NAME; + + /** + *

If this is enabled, the scheduler will attempt to directly execute tasks that are scheduled + * to {@code now()}, or a time in the past. For this to work, the call to {@code schedule(..)} + * must not occur from within a transaction, because the record will not yet be visible to the + * scheduler (if this is a requirement, see the method + * {@code scheduler.triggerCheckForDueExecutions())} + */ + private boolean immediateExecutionEnabled = false; + + /** + *

How often the scheduler checks the database for due executions. + */ + @DurationUnit(SECONDS) + @NotNull + private Duration pollingInterval = Duration.ofSeconds(30); + + /** + *

Maximum number of executions to fetch on a check for due executions. + */ + private Optional pollingLimit = Optional.empty(); + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(final boolean enabled) { + this.enabled = enabled; + } + + public int getThreads() { + return threads; + } + + public void setThreads(final int threads) { + this.threads = threads; + } + + public Duration getHeartbeatInterval() { + return heartbeatInterval; + } + + public void setHeartbeatInterval(final Duration heartbeatInterval) { + this.heartbeatInterval = heartbeatInterval; + } + + public String getSchedulerName() { + return schedulerName; + } + + public void setSchedulerName(String schedulerName) { + this.schedulerName = schedulerName; + } + + public String getTableName() { + return tableName; + } + + public void setTableName(final String tableName) { + this.tableName = tableName; + } + + public boolean isImmediateExecutionEnabled() { + return immediateExecutionEnabled; + } + + public void setImmediateExecutionEnabled(boolean immediateExecutionEnabled) { + this.immediateExecutionEnabled = immediateExecutionEnabled; + } + + public Duration getPollingInterval() { + return pollingInterval; + } + + public void setPollingInterval(final Duration pollingInterval) { + this.pollingInterval = pollingInterval; + } + + public Optional getPollingLimit() { + return pollingLimit; + } + + public void setPollingLimit(final Optional pollingLimit) { + this.pollingLimit = pollingLimit; + } +} diff --git a/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/package-info.java b/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/package-info.java new file mode 100644 index 00000000..706ccb9c --- /dev/null +++ b/db-scheduler-boot-starter/src/main/java/com/github/kagkarlsson/scheduler/boot/package-info.java @@ -0,0 +1,4 @@ +/** + * Spring Boot related autoconfiguration and glue code. + */ +package com.github.kagkarlsson.scheduler.boot; diff --git a/db-scheduler-boot-starter/src/main/resources/META-INF/spring.factories b/db-scheduler-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..5d15a2c6 --- /dev/null +++ b/db-scheduler-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.github.kagkarlsson.scheduler.boot.autoconfigure.DbSchedulerAutoConfiguration diff --git a/db-scheduler-boot-starter/src/test/java/com/github/kagkarlsson/scheduler/boot/autoconfigure/DbSchedulerAutoConfigurationTest.java b/db-scheduler-boot-starter/src/test/java/com/github/kagkarlsson/scheduler/boot/autoconfigure/DbSchedulerAutoConfigurationTest.java new file mode 100644 index 00000000..397f4ffe --- /dev/null +++ b/db-scheduler-boot-starter/src/test/java/com/github/kagkarlsson/scheduler/boot/autoconfigure/DbSchedulerAutoConfigurationTest.java @@ -0,0 +1,130 @@ +package com.github.kagkarlsson.scheduler.boot.autoconfigure; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import com.github.kagkarlsson.scheduler.Scheduler; +import com.github.kagkarlsson.scheduler.boot.actuator.DbSchedulerHealthIndicator; +import com.github.kagkarlsson.scheduler.task.Task; +import com.github.kagkarlsson.scheduler.task.helper.Tasks; +import com.google.common.collect.ImmutableList; +import java.util.Objects; +import javax.sql.DataSource; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@RunWith(JUnit4.class) +public class DbSchedulerAutoConfigurationTest { + private static final Logger log = LoggerFactory.getLogger(DbSchedulerAutoConfigurationTest.class); + private final ApplicationContextRunner ctxRunner; + + public DbSchedulerAutoConfigurationTest() { + ctxRunner = new ApplicationContextRunner() + .withPropertyValues( + "spring.application.name=db-scheduler-boot-starter-test", + "spring.profiles.active=integration-test" + ).withConfiguration(AutoConfigurations.of( + DataSourceAutoConfiguration.class, DbSchedulerAutoConfiguration.class + )); + } + + @Test + public void it_should_initialize_an_empty_scheduler() { + ctxRunner.run((AssertableApplicationContext ctx) -> { + assertThat(ctx).hasSingleBean(DataSource.class); + assertThat(ctx).hasSingleBean(Scheduler.class); + + ctx.getBean(Scheduler.class).getScheduledExecutions(execution -> { + fail("No scheduled executions should be present", execution); + }); + }); + } + + @Test + public void it_should_initialize_a_scheduler_with_a_single_task() { + ctxRunner + .withUserConfiguration(SingleTaskConfiguration.class) + .run((AssertableApplicationContext ctx) -> { + assertThat(ctx).hasSingleBean(Scheduler.class); + assertThat(ctx).hasSingleBean(Task.class); + assertThat(ctx).getBean("singleStringTask", Task.class).isNotNull(); + }); + } + + @Test + public void it_should_initialize_a_scheduler_with_a_multiple_tasks() { + ctxRunner + .withUserConfiguration(MultipleTasksConfiguration.class) + .run((AssertableApplicationContext ctx) -> { + assertThat(ctx).hasSingleBean(Scheduler.class); + + ImmutableList.of("firstTask", "secondTask", "thirdTask").forEach(beanName -> { + assertThat(ctx).getBean(beanName, Task.class).isNotNull(); + }); + }); + } + + @Test + public void it_should_autoconfigure_a_health_check() { + ctxRunner + .withConfiguration(AutoConfigurations.of(HealthIndicatorAutoConfiguration.class)) + .run((AssertableApplicationContext ctx) -> { + assertThat(ctx).hasSingleBean(DbSchedulerHealthIndicator.class); + }); + } + + @Test + public void it_should_skip_autoconfiguration_if_explicitly_disabled() { + ctxRunner + .withPropertyValues("db-scheduler.enabled=false") + .run((AssertableApplicationContext ctx) -> { + assertThat(ctx).doesNotHaveBean(Scheduler.class); + }); + } + + @Configuration + static class SingleTaskConfiguration { + @Bean + Task singleStringTask() { + return namedStringTask("single-string-task"); + } + } + + @Configuration + static class MultipleTasksConfiguration { + @Bean + Task firstTask() { + return namedStringTask("first-task"); + } + + @Bean + Task secondTask() { + return namedStringTask("second-task"); + } + + @Bean + Task thirdTask() { + return namedStringTask("third-task"); + } + } + + private static Task namedStringTask(String name) { + Objects.requireNonNull(name); + + return Tasks + .oneTime(name, String.class) + .execute((instance, context) -> { + log.info("Executed task: {}, ctx: {}", instance, context); + }); + } +} diff --git a/db-scheduler-boot-starter/src/test/resources/schema.sql b/db-scheduler-boot-starter/src/test/resources/schema.sql new file mode 100644 index 00000000..6242da80 --- /dev/null +++ b/db-scheduler-boot-starter/src/test/resources/schema.sql @@ -0,0 +1,14 @@ +create table if not exists scheduled_tasks ( + task_name varchar(100), + task_instance varchar(100), + task_data blob, + execution_time TIMESTAMP WITH TIME ZONE, + picked BIT, + picked_by varchar(50), + last_success TIMESTAMP WITH TIME ZONE, + last_failure TIMESTAMP WITH TIME ZONE, + consecutive_failures INT, + last_heartbeat TIMESTAMP WITH TIME ZONE, + version BIGINT, + PRIMARY KEY (task_name, task_instance) +); diff --git a/db-scheduler/NOTICE b/db-scheduler/NOTICE new file mode 100644 index 00000000..7c8e7295 --- /dev/null +++ b/db-scheduler/NOTICE @@ -0,0 +1,32 @@ +Db-scheduler + +Copyright 2015 Gustav Karlsson. All Rights Reserved. + +This product includes software developed by Gustav Karlsson. +Licensed under Apache 2 - http://www.apache.org/licenses/LICENSE-2.0.html + + +This software includes third party software subject to the following licenses: + + Apache Commons Codec under Apache License, Version 2.0 + Apache Commons Compress under Apache License, Version 2.0 + Apache Commons IO under Apache License, Version 2.0 + Apache Commons Lang under Apache License, Version 2.0 + cron-utils under Apache 2.0 + db-scheduler: Core under The Apache Software License, Version 2.0 + Guava: Google Core Libraries for Java under The Apache Software License, Version 2.0 + Hamcrest Core under New BSD License + Hamcrest library under New BSD License + HikariCP under The Apache Software License, Version 2.0 + HyperSQL Database under HSQLDB License, a BSD open source license + java-8-matchers under MIT License + JCL 1.2 implemented over SLF4J under MIT License + JUnit under Eclipse Public License 1.0 + Micro JDBC under The Apache Software License, Version 2.0 + otj-pg-embedded under Apache License, Version 2.0 + PostgreSQL JDBC Driver - JDBC 4.2 under The PostgreSQL License + SLF4J API Module under MIT License + SLF4J Simple Binding under MIT License + XZ for Java under Public Domain + + diff --git a/db-scheduler/pom.xml b/db-scheduler/pom.xml new file mode 100644 index 00000000..4cce29f8 --- /dev/null +++ b/db-scheduler/pom.xml @@ -0,0 +1,155 @@ + + + + db-scheduler-parent + com.github.kagkarlsson + 5.3-SNAPSHOT + + 4.0.0 + + db-scheduler + db-scheduler: Core + + + ${project.parent.basedir}/.license + + 8.0.0 + 1.3 + 3.1.0 + 2.3.3 + 1.6 + 4.12 + 0.1 + 0.11.4 + 9.4.1207 + 1.7.7 + + + + + com.github.kagkarlsson + micro-jdbc + ${micro-jdbc.version} + + + org.slf4j + slf4j-api + ${slf4j.version} + + + com.cronutils + cron-utils + ${cron-utils.version} + + + + + org.slf4j + slf4j-simple + ${slf4j.version} + test + + + junit + junit + ${junit.version} + test + + + org.hamcrest + hamcrest-core + ${hamcrest.version} + test + + + org.hamcrest + hamcrest-library + ${hamcrest.version} + test + + + co.unruly + java-8-matchers + ${java8-matchers.version} + test + + + + org.hsqldb + hsqldb + ${hsqldb.version} + test + + + org.postgresql + postgresql + ${postgresql.version} + test + + + + com.opentable.components + otj-pg-embedded + ${otj-pg-embedded.version} + test + + + com.zaxxer + HikariCP + ${hikaricp.version} + test + + + + + + + + + maven-dependency-plugin + 2.10 + + + + analyze-only + + + true + true + + + + + + com.mycila + license-maven-plugin + + + maven-enforcer-plugin + + + maven-shade-plugin + + + + diff --git a/src/main/java/com/github/kagkarlsson/scheduler/ClientEvent.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/ClientEvent.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/ClientEvent.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/ClientEvent.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/Clock.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/Clock.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/Clock.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/Clock.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/CurrentlyExecuting.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/CurrentlyExecuting.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/CurrentlyExecuting.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/CurrentlyExecuting.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/DueExecutionsBatch.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/DueExecutionsBatch.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/DueExecutionsBatch.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/DueExecutionsBatch.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/ExecutorUtils.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/ExecutorUtils.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/ExecutorUtils.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/ExecutorUtils.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/JdbcTaskRepository.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/JdbcTaskRepository.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/JdbcTaskRepository.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/JdbcTaskRepository.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/RunUntilShutdown.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/RunUntilShutdown.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/RunUntilShutdown.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/RunUntilShutdown.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/ScheduledExecution.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/ScheduledExecution.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/ScheduledExecution.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/ScheduledExecution.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/Scheduler.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/Scheduler.java similarity index 99% rename from src/main/java/com/github/kagkarlsson/scheduler/Scheduler.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/Scheduler.java index 641d8395..45b802f7 100644 --- a/src/main/java/com/github/kagkarlsson/scheduler/Scheduler.java +++ b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/Scheduler.java @@ -80,7 +80,7 @@ protected Scheduler(Clock clock, TaskRepository taskRepository, TaskResolver tas } public void start() { - LOG.info("Starting scheduler"); + LOG.info("Starting scheduler."); executeOnStartup(); @@ -130,6 +130,10 @@ public void stop() { } } + public SchedulerState getSchedulerState() { + return schedulerState; + } + @Override public void schedule(TaskInstance taskInstance, Instant executionTime) { this.delegate.schedule(taskInstance, executionTime); diff --git a/src/main/java/com/github/kagkarlsson/scheduler/SchedulerBuilder.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/SchedulerBuilder.java similarity index 93% rename from src/main/java/com/github/kagkarlsson/scheduler/SchedulerBuilder.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/SchedulerBuilder.java index c13a64a7..d201da09 100644 --- a/src/main/java/com/github/kagkarlsson/scheduler/SchedulerBuilder.java +++ b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/SchedulerBuilder.java @@ -15,22 +15,21 @@ */ package com.github.kagkarlsson.scheduler; +import static com.github.kagkarlsson.scheduler.ExecutorUtils.defaultThreadFactoryWithPrefix; +import static com.github.kagkarlsson.scheduler.Scheduler.THREAD_PREFIX; + import com.github.kagkarlsson.scheduler.stats.StatsRegistry; import com.github.kagkarlsson.scheduler.task.OnStartup; import com.github.kagkarlsson.scheduler.task.Task; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.sql.DataSource; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; - -import static com.github.kagkarlsson.scheduler.ExecutorUtils.defaultThreadFactoryWithPrefix; -import static com.github.kagkarlsson.scheduler.Scheduler.THREAD_PREFIX; +import javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class SchedulerBuilder { private static final Logger LOG = LoggerFactory.getLogger(SchedulerBuilder.class); @@ -144,6 +143,13 @@ public Scheduler build() { candidateExecutorService = Executors.newFixedThreadPool(executorThreads, defaultThreadFactoryWithPrefix(THREAD_PREFIX + "-")); } + LOG.info("Creating scheduler with configuration: threads={}, pollInterval={}s, heartbeat={}s enable-immediate-execution={}, table-name={}, name={}", + waiter.getWaitDuration().getSeconds(), + executorThreads, + heartbeatInterval.getSeconds(), + enableImmediateExecution, + tableName, + schedulerName.getName()); return new Scheduler(clock, taskRepository, taskResolver, executorThreads, candidateExecutorService, schedulerName, waiter, heartbeatInterval, enableImmediateExecution, statsRegistry, pollingLimit, startTasks); } diff --git a/src/main/java/com/github/kagkarlsson/scheduler/SchedulerClient.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/SchedulerClient.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/SchedulerClient.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/SchedulerClient.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/SchedulerClientEventListener.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/SchedulerClientEventListener.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/SchedulerClientEventListener.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/SchedulerClientEventListener.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/SchedulerName.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/SchedulerName.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/SchedulerName.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/SchedulerName.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/SchedulerState.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/SchedulerState.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/SchedulerState.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/SchedulerState.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/Serializer.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/Serializer.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/Serializer.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/Serializer.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/StringUtils.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/StringUtils.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/StringUtils.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/StringUtils.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/SystemClock.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/SystemClock.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/SystemClock.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/SystemClock.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/TaskRepository.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/TaskRepository.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/TaskRepository.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/TaskRepository.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/TaskResolver.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/TaskResolver.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/TaskResolver.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/TaskResolver.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/TriggerCheckForDueExecutions.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/TriggerCheckForDueExecutions.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/TriggerCheckForDueExecutions.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/TriggerCheckForDueExecutions.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/Waiter.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/Waiter.java similarity index 96% rename from src/main/java/com/github/kagkarlsson/scheduler/Waiter.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/Waiter.java index c3decd7e..360d17e5 100644 --- a/src/main/java/com/github/kagkarlsson/scheduler/Waiter.java +++ b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/Waiter.java @@ -77,4 +77,8 @@ public boolean wake() { } } + public Duration getWaitDuration() { + return duration; + } + } diff --git a/src/main/java/com/github/kagkarlsson/scheduler/stats/StatsRegistry.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/stats/StatsRegistry.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/stats/StatsRegistry.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/stats/StatsRegistry.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/CompletionHandler.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/CompletionHandler.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/CompletionHandler.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/CompletionHandler.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/DeadExecutionHandler.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/DeadExecutionHandler.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/DeadExecutionHandler.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/DeadExecutionHandler.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/Execution.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/Execution.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/Execution.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/Execution.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionComplete.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionComplete.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionComplete.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionComplete.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionContext.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionContext.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionContext.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionContext.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionFailed.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionFailed.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionFailed.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionFailed.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionHandler.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionHandler.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionHandler.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionHandler.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionOperations.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionOperations.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionOperations.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/ExecutionOperations.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/FailureHandler.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/FailureHandler.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/FailureHandler.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/FailureHandler.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/OnStartup.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/OnStartup.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/OnStartup.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/OnStartup.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/Task.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/Task.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/Task.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/Task.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/TaskInstance.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/TaskInstance.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/TaskInstance.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/TaskInstance.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/TaskInstanceId.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/TaskInstanceId.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/TaskInstanceId.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/TaskInstanceId.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/VoidExecutionHandler.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/VoidExecutionHandler.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/VoidExecutionHandler.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/VoidExecutionHandler.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/helper/ComposableTask.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/helper/ComposableTask.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/helper/ComposableTask.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/helper/ComposableTask.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/helper/CustomTask.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/helper/CustomTask.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/helper/CustomTask.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/helper/CustomTask.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/helper/OneTimeTask.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/helper/OneTimeTask.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/helper/OneTimeTask.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/helper/OneTimeTask.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/helper/RecurringTask.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/helper/RecurringTask.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/helper/RecurringTask.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/helper/RecurringTask.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/helper/ScheduleOnStartup.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/helper/ScheduleOnStartup.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/helper/ScheduleOnStartup.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/helper/ScheduleOnStartup.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/helper/Tasks.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/helper/Tasks.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/helper/Tasks.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/helper/Tasks.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/CronSchedule.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/CronSchedule.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/schedule/CronSchedule.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/CronSchedule.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/Daily.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/Daily.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/schedule/Daily.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/Daily.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/FixedDelay.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/FixedDelay.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/schedule/FixedDelay.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/FixedDelay.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/Schedule.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/Schedule.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/schedule/Schedule.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/Schedule.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/Schedules.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/Schedules.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/task/schedule/Schedules.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/task/schedule/Schedules.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/testhelper/ManualScheduler.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/testhelper/ManualScheduler.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/testhelper/ManualScheduler.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/testhelper/ManualScheduler.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/testhelper/SettableClock.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/testhelper/SettableClock.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/testhelper/SettableClock.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/testhelper/SettableClock.java diff --git a/src/main/java/com/github/kagkarlsson/scheduler/testhelper/TestHelper.java b/db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/testhelper/TestHelper.java similarity index 100% rename from src/main/java/com/github/kagkarlsson/scheduler/testhelper/TestHelper.java rename to db-scheduler/src/main/java/com/github/kagkarlsson/scheduler/testhelper/TestHelper.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/ClusterTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/ClusterTest.java similarity index 93% rename from src/test/java/com/github/kagkarlsson/scheduler/ClusterTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/ClusterTest.java index 3ffd1009..a94f7dc8 100644 --- a/src/test/java/com/github/kagkarlsson/scheduler/ClusterTest.java +++ b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/ClusterTest.java @@ -1,12 +1,16 @@ package com.github.kagkarlsson.scheduler; -import com.github.kagkarlsson.scheduler.task.*; +import static java.util.stream.Collectors.toList; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; + +import com.github.kagkarlsson.scheduler.task.CompletionHandler; +import com.github.kagkarlsson.scheduler.task.ExecutionComplete; +import com.github.kagkarlsson.scheduler.task.ExecutionOperations; +import com.github.kagkarlsson.scheduler.task.Task; import com.github.kagkarlsson.scheduler.task.helper.ComposableTask; import com.google.common.collect.Lists; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.Timeout; - import java.time.Duration; import java.time.Instant; import java.util.ArrayList; @@ -17,11 +21,9 @@ import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.stream.IntStream; - -import static java.util.stream.Collectors.toList; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; public class ClusterTest { diff --git a/src/test/java/com/github/kagkarlsson/scheduler/CustomTableNameTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/CustomTableNameTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/CustomTableNameTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/CustomTableNameTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/DbUtils.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/DbUtils.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/DbUtils.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/DbUtils.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/DeadExecutionsTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/DeadExecutionsTest.java similarity index 88% rename from src/test/java/com/github/kagkarlsson/scheduler/DeadExecutionsTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/DeadExecutionsTest.java index 733bdd25..0f332d38 100644 --- a/src/test/java/com/github/kagkarlsson/scheduler/DeadExecutionsTest.java +++ b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/DeadExecutionsTest.java @@ -1,25 +1,33 @@ package com.github.kagkarlsson.scheduler; +import static com.github.kagkarlsson.scheduler.JdbcTaskRepository.DEFAULT_TABLE_NAME; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertTrue; + import com.github.kagkarlsson.scheduler.stats.StatsRegistry; -import com.github.kagkarlsson.scheduler.task.*; +import com.github.kagkarlsson.scheduler.task.CompletionHandler; +import com.github.kagkarlsson.scheduler.task.DeadExecutionHandler; +import com.github.kagkarlsson.scheduler.task.Execution; +import com.github.kagkarlsson.scheduler.task.ExecutionContext; +import com.github.kagkarlsson.scheduler.task.ExecutionOperations; +import com.github.kagkarlsson.scheduler.task.Task; +import com.github.kagkarlsson.scheduler.task.TaskInstance; +import com.github.kagkarlsson.scheduler.task.VoidExecutionHandler; import com.github.kagkarlsson.scheduler.task.helper.OneTimeTask; import com.github.kagkarlsson.scheduler.testhelper.SettableClock; import com.google.common.util.concurrent.MoreExecutors; -import org.hamcrest.Matchers; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - import java.time.Duration; import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.Optional; - -import static com.github.kagkarlsson.scheduler.JdbcTaskRepository.DEFAULT_TABLE_NAME; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertTrue; +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; public class DeadExecutionsTest { diff --git a/src/test/java/com/github/kagkarlsson/scheduler/DueExecutionsBatchTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/DueExecutionsBatchTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/DueExecutionsBatchTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/DueExecutionsBatchTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/EmbeddedPostgresqlRule.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/EmbeddedPostgresqlRule.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/EmbeddedPostgresqlRule.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/EmbeddedPostgresqlRule.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/ExecutionTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/ExecutionTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/ExecutionTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/ExecutionTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/HsqlTestDatabaseRule.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/HsqlTestDatabaseRule.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/HsqlTestDatabaseRule.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/HsqlTestDatabaseRule.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/JdbcTaskRepositoryTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/JdbcTaskRepositoryTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/JdbcTaskRepositoryTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/JdbcTaskRepositoryTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/RunUntilShutdownTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/RunUntilShutdownTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/RunUntilShutdownTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/RunUntilShutdownTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/ScheduledExecutionTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/ScheduledExecutionTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/ScheduledExecutionTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/ScheduledExecutionTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/SchedulerClientTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/SchedulerClientTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/SchedulerClientTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/SchedulerClientTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/SchedulerTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/SchedulerTest.java similarity index 96% rename from src/test/java/com/github/kagkarlsson/scheduler/SchedulerTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/SchedulerTest.java index dfb18d63..6dfe2c18 100644 --- a/src/test/java/com/github/kagkarlsson/scheduler/SchedulerTest.java +++ b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/SchedulerTest.java @@ -1,27 +1,28 @@ package com.github.kagkarlsson.scheduler; +import static com.github.kagkarlsson.scheduler.JdbcTaskRepository.DEFAULT_TABLE_NAME; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + import com.github.kagkarlsson.scheduler.stats.StatsRegistry; -import com.github.kagkarlsson.scheduler.task.*; +import com.github.kagkarlsson.scheduler.task.ExecutionComplete; +import com.github.kagkarlsson.scheduler.task.Task; +import com.github.kagkarlsson.scheduler.task.TaskInstance; import com.github.kagkarlsson.scheduler.task.helper.ComposableTask; import com.github.kagkarlsson.scheduler.task.helper.OneTimeTask; import com.github.kagkarlsson.scheduler.task.helper.RecurringTask; import com.github.kagkarlsson.scheduler.task.schedule.FixedDelay; import com.github.kagkarlsson.scheduler.testhelper.SettableClock; import com.google.common.util.concurrent.MoreExecutors; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - import java.time.Duration; import java.time.Instant; import java.util.ArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; - -import static com.github.kagkarlsson.scheduler.JdbcTaskRepository.DEFAULT_TABLE_NAME; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; public class SchedulerTest { @@ -37,7 +38,7 @@ public void setUp() { handler = new TestTasks.CountingHandler<>(); } - private Scheduler schedulerFor(Task ... tasks) { + private Scheduler schedulerFor(Task... tasks) { return schedulerFor(MoreExecutors.newDirectExecutorService(), tasks); } diff --git a/src/test/java/com/github/kagkarlsson/scheduler/StopSchedulerRule.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/StopSchedulerRule.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/StopSchedulerRule.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/StopSchedulerRule.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/StringUtilsTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/StringUtilsTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/StringUtilsTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/StringUtilsTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/TestTasks.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/TestTasks.java similarity index 92% rename from src/test/java/com/github/kagkarlsson/scheduler/TestTasks.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/TestTasks.java index 467c4999..d4be90dd 100644 --- a/src/test/java/com/github/kagkarlsson/scheduler/TestTasks.java +++ b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/TestTasks.java @@ -1,16 +1,21 @@ package com.github.kagkarlsson.scheduler; import com.github.kagkarlsson.scheduler.stats.StatsRegistry; -import com.github.kagkarlsson.scheduler.task.*; +import com.github.kagkarlsson.scheduler.task.CompletionHandler; +import com.github.kagkarlsson.scheduler.task.ExecutionComplete; +import com.github.kagkarlsson.scheduler.task.ExecutionContext; +import com.github.kagkarlsson.scheduler.task.ExecutionOperations; +import com.github.kagkarlsson.scheduler.task.FailureHandler; +import com.github.kagkarlsson.scheduler.task.TaskInstance; +import com.github.kagkarlsson.scheduler.task.VoidExecutionHandler; import com.github.kagkarlsson.scheduler.task.helper.OneTimeTask; import com.github.kagkarlsson.scheduler.task.helper.RecurringTask; import com.github.kagkarlsson.scheduler.task.schedule.FixedDelay; -import org.slf4j.LoggerFactory; - import java.time.Duration; import java.util.Optional; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; +import org.slf4j.LoggerFactory; public class TestTasks { diff --git a/src/test/java/com/github/kagkarlsson/scheduler/WaiterTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/WaiterTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/WaiterTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/WaiterTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/compatibility/CompatibilityTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/compatibility/CompatibilityTest.java similarity index 90% rename from src/test/java/com/github/kagkarlsson/scheduler/compatibility/CompatibilityTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/compatibility/CompatibilityTest.java index 7cdccaf3..3654bf58 100644 --- a/src/test/java/com/github/kagkarlsson/scheduler/compatibility/CompatibilityTest.java +++ b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/compatibility/CompatibilityTest.java @@ -1,32 +1,41 @@ package com.github.kagkarlsson.scheduler.compatibility; -import com.github.kagkarlsson.scheduler.*; +import static com.github.kagkarlsson.scheduler.JdbcTaskRepository.DEFAULT_TABLE_NAME; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; + +import com.github.kagkarlsson.scheduler.DbUtils; +import com.github.kagkarlsson.scheduler.JdbcTaskRepository; +import com.github.kagkarlsson.scheduler.Scheduler; +import com.github.kagkarlsson.scheduler.SchedulerName; +import com.github.kagkarlsson.scheduler.StopSchedulerRule; +import com.github.kagkarlsson.scheduler.TaskResolver; +import com.github.kagkarlsson.scheduler.TestTasks; import com.github.kagkarlsson.scheduler.TestTasks.DoNothingHandler; -import com.github.kagkarlsson.scheduler.task.*; +import com.github.kagkarlsson.scheduler.task.Execution; +import com.github.kagkarlsson.scheduler.task.TaskInstance; import com.github.kagkarlsson.scheduler.task.helper.OneTimeTask; import com.github.kagkarlsson.scheduler.task.helper.RecurringTask; import com.github.kagkarlsson.scheduler.task.schedule.FixedDelay; import com.google.common.collect.Lists; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.Timeout; -import org.slf4j.LoggerFactory; - -import javax.sql.DataSource; import java.time.Duration; import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.TimeUnit; - -import static com.github.kagkarlsson.scheduler.JdbcTaskRepository.DEFAULT_TABLE_NAME; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; +import javax.sql.DataSource; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.slf4j.LoggerFactory; @SuppressWarnings("ConstantConditions") diff --git a/src/test/java/com/github/kagkarlsson/scheduler/compatibility/HsqlCompatibilityTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/compatibility/HsqlCompatibilityTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/compatibility/HsqlCompatibilityTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/compatibility/HsqlCompatibilityTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/compatibility/MssqlCompatibilityTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/compatibility/MssqlCompatibilityTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/compatibility/MssqlCompatibilityTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/compatibility/MssqlCompatibilityTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/compatibility/MysqlCompatibilityTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/compatibility/MysqlCompatibilityTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/compatibility/MysqlCompatibilityTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/compatibility/MysqlCompatibilityTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/compatibility/OracleCompatibilityTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/compatibility/OracleCompatibilityTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/compatibility/OracleCompatibilityTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/compatibility/OracleCompatibilityTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/compatibility/PostgresqlCompatibilityTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/compatibility/PostgresqlCompatibilityTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/compatibility/PostgresqlCompatibilityTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/compatibility/PostgresqlCompatibilityTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/example/CheckForNewBatchDirectlyMain.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/example/CheckForNewBatchDirectlyMain.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/example/CheckForNewBatchDirectlyMain.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/example/CheckForNewBatchDirectlyMain.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/example/CronMain.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/example/CronMain.java similarity index 93% rename from src/test/java/com/github/kagkarlsson/scheduler/example/CronMain.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/example/CronMain.java index 6cbb9019..96ffd239 100644 --- a/src/test/java/com/github/kagkarlsson/scheduler/example/CronMain.java +++ b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/example/CronMain.java @@ -2,7 +2,6 @@ import com.github.kagkarlsson.scheduler.HsqlTestDatabaseRule; import com.github.kagkarlsson.scheduler.Scheduler; -import com.github.kagkarlsson.scheduler.task.*; import com.github.kagkarlsson.scheduler.task.helper.CustomTask; import com.github.kagkarlsson.scheduler.task.helper.OneTimeTask; import com.github.kagkarlsson.scheduler.task.helper.RecurringTask; @@ -15,8 +14,6 @@ import javax.sql.DataSource; import java.time.Duration; import java.time.Instant; -import java.time.temporal.ChronoField; -import java.time.temporal.TemporalField; public class CronMain { private static final Logger LOG = LoggerFactory.getLogger(CronMain.class); diff --git a/src/test/java/com/github/kagkarlsson/scheduler/example/EnableImmediateExecutionMain.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/example/EnableImmediateExecutionMain.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/example/EnableImmediateExecutionMain.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/example/EnableImmediateExecutionMain.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/example/MaxRetriesMain.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/example/MaxRetriesMain.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/example/MaxRetriesMain.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/example/MaxRetriesMain.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/example/SchedulerMain.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/example/SchedulerMain.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/example/SchedulerMain.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/example/SchedulerMain.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/example/TasksMain.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/example/TasksMain.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/example/TasksMain.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/example/TasksMain.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/functional/DeadExecutionTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/functional/DeadExecutionTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/functional/DeadExecutionTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/functional/DeadExecutionTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/functional/ExecutorPoolTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/functional/ExecutorPoolTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/functional/ExecutorPoolTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/functional/ExecutorPoolTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/functional/ImmediateExecutionTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/functional/ImmediateExecutionTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/functional/ImmediateExecutionTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/functional/ImmediateExecutionTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/functional/RecurringTaskTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/functional/RecurringTaskTest.java similarity index 96% rename from src/test/java/com/github/kagkarlsson/scheduler/functional/RecurringTaskTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/functional/RecurringTaskTest.java index 6e012c36..c7a85a46 100644 --- a/src/test/java/com/github/kagkarlsson/scheduler/functional/RecurringTaskTest.java +++ b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/functional/RecurringTaskTest.java @@ -8,16 +8,13 @@ import com.github.kagkarlsson.scheduler.testhelper.ManualScheduler; import com.github.kagkarlsson.scheduler.testhelper.SettableClock; import com.github.kagkarlsson.scheduler.testhelper.TestHelper; -import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.junit.rules.Timeout; import java.time.*; import java.util.Arrays; import java.util.Optional; -import java.util.concurrent.TimeUnit; import static co.unruly.matchers.OptionalMatchers.contains; import static org.junit.Assert.assertThat; diff --git a/src/test/java/com/github/kagkarlsson/scheduler/helper/ExecutionCompletedCondition.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/helper/ExecutionCompletedCondition.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/helper/ExecutionCompletedCondition.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/helper/ExecutionCompletedCondition.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/helper/RanExecuteDueCondition.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/helper/RanExecuteDueCondition.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/helper/RanExecuteDueCondition.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/helper/RanExecuteDueCondition.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/helper/TestableRegistry.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/helper/TestableRegistry.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/helper/TestableRegistry.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/helper/TestableRegistry.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/task/CronTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/task/CronTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/task/CronTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/task/CronTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/task/DailyTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/task/DailyTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/task/DailyTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/task/DailyTest.java diff --git a/src/test/java/com/github/kagkarlsson/scheduler/task/SchedulesTest.java b/db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/task/SchedulesTest.java similarity index 100% rename from src/test/java/com/github/kagkarlsson/scheduler/task/SchedulesTest.java rename to db-scheduler/src/test/java/com/github/kagkarlsson/scheduler/task/SchedulesTest.java diff --git a/src/test/resources/com/github/kagkarlsson/scheduler/postgresql_custom_tablename.sql b/db-scheduler/src/test/resources/com/github/kagkarlsson/scheduler/postgresql_custom_tablename.sql similarity index 100% rename from src/test/resources/com/github/kagkarlsson/scheduler/postgresql_custom_tablename.sql rename to db-scheduler/src/test/resources/com/github/kagkarlsson/scheduler/postgresql_custom_tablename.sql diff --git a/src/test/resources/hsql_tables.sql b/db-scheduler/src/test/resources/hsql_tables.sql similarity index 100% rename from src/test/resources/hsql_tables.sql rename to db-scheduler/src/test/resources/hsql_tables.sql diff --git a/src/test/resources/mssql_tables.sql b/db-scheduler/src/test/resources/mssql_tables.sql similarity index 100% rename from src/test/resources/mssql_tables.sql rename to db-scheduler/src/test/resources/mssql_tables.sql diff --git a/src/test/resources/mysql_tables.sql b/db-scheduler/src/test/resources/mysql_tables.sql similarity index 100% rename from src/test/resources/mysql_tables.sql rename to db-scheduler/src/test/resources/mysql_tables.sql diff --git a/src/test/resources/oracle_tables.sql b/db-scheduler/src/test/resources/oracle_tables.sql similarity index 100% rename from src/test/resources/oracle_tables.sql rename to db-scheduler/src/test/resources/oracle_tables.sql diff --git a/src/test/resources/postgresql_tables.sql b/db-scheduler/src/test/resources/postgresql_tables.sql similarity index 100% rename from src/test/resources/postgresql_tables.sql rename to db-scheduler/src/test/resources/postgresql_tables.sql diff --git a/src/test/resources/simplelogger.properties b/db-scheduler/src/test/resources/simplelogger.properties similarity index 100% rename from src/test/resources/simplelogger.properties rename to db-scheduler/src/test/resources/simplelogger.properties diff --git a/examples/NOTICE b/examples/NOTICE new file mode 100644 index 00000000..a06059c9 --- /dev/null +++ b/examples/NOTICE @@ -0,0 +1,102 @@ +Db-scheduler + +Copyright 2015 Gustav Karlsson. All Rights Reserved. + +This product includes software developed by Gustav Karlsson. +Licensed under Apache 2 - http://www.apache.org/licenses/LICENSE-2.0.html + + +This software includes third party software subject to the following licenses: + + AntLR Parser Generator under BSD License + Apache Log4j API under Apache License, Version 2.0 + Apache Log4j to SLF4J Adapter under Apache License, Version 2.0 + ASM based accessors helper used by json-smart under The Apache Software License, Version 2.0 + ASM Core under BSD + AspectJ weaver under Eclipse Public License - v 1.0 + AssertJ fluent assertions under Apache License, Version 2.0 + Bean Validation API under Apache License 2.0 + Byte Buddy (without dependencies) under Apache License, Version 2.0 + Byte Buddy Java agent under Apache License, Version 2.0 + ClassMate under The Apache Software License, Version 2.0 + cron-utils under Apache 2.0 + db-scheduler: Core under The Apache Software License, Version 2.0 + db-scheduler: Examples under The Apache Software License, Version 2.0 + db-scheduler: Examples: Spring Boot under The Apache Software License, Version 2.0 + db-scheduler: Spring Boot Starter under The Apache Software License, Version 2.0 + dom4j under BSD 3-clause New License + Guava: Google Core Libraries for Java under The Apache Software License, Version 2.0 + Hamcrest Core under New BSD License + Hamcrest library under New BSD License + HdrHistogram under Public Domain, per Creative Commons CC0 + Hibernate Commons Annotations under GNU Lesser General Public License v2.1 or later + Hibernate ORM - hibernate-core under GNU Library General Public License v2.1 or later + Hibernate Validator Engine under Apache License 2.0 + HikariCP under The Apache Software License, Version 2.0 + HyperSQL Database under HSQLDB License, a BSD open source license + Jackson datatype: jdk8 under The Apache Software License, Version 2.0 + Jackson datatype: JSR310 under The Apache Software License, Version 2.0 + Jackson-annotations under The Apache Software License, Version 2.0 + Jackson-core under The Apache Software License, Version 2.0 + jackson-databind under The Apache Software License, Version 2.0 + Jackson-module-parameter-names under The Apache Software License, Version 2.0 + Java Annotation Indexer under Apache License, Version 2.0 + JavaBeans Activation Framework API jar under CDDL/GPLv2+CE + Javassist under MPL 1.1 or LGPL 2.1 or Apache License 2.0 + javax.annotation API under CDDL + GPLv2 with classpath exception + javax.persistence-api under Eclipse Public License v1.0 or Eclipse Distribution License v. 1.0 + javax.transaction API under CDDL + GPLv2 with classpath exception + jaxb-api under CDDL 1.1 or GPL2 w/ CPE + JBoss Logging 3 under Apache License, version 2.0 + JSON library from Android SDK under Apache License 2.0 + JSON Small and Fast Parser under The Apache Software License, Version 2.0 + JSONassert under The Apache Software License, Version 2.0 + JUL to SLF4J bridge under MIT License + JUnit under Eclipse Public License 1.0 + LatencyUtils under Public Domain, per Creative Commons CC0 + Logback Classic Module under Eclipse Public License - v 1.0 or GNU Lesser General Public License + Logback Core Module under Eclipse Public License - v 1.0 or GNU Lesser General Public License + Micro JDBC under The Apache Software License, Version 2.0 + micrometer-core under The Apache Software License, Version 2.0 + mockito-core under The MIT License + Objenesis under Apache 2 + org.xmlunit:xmlunit-core under The Apache Software License, Version 2.0 + project ':json-path' under The Apache Software License, Version 2.0 + SLF4J API Module under MIT License + SnakeYAML under Apache License, Version 2.0 + Spring AOP under Apache License, Version 2.0 + Spring Aspects under Apache License, Version 2.0 + Spring Beans under Apache License, Version 2.0 + Spring Boot under Apache License, Version 2.0 + Spring Boot Actuator under Apache License, Version 2.0 + Spring Boot Actuator AutoConfigure under Apache License, Version 2.0 + Spring Boot Actuator Starter under Apache License, Version 2.0 + Spring Boot AOP Starter under Apache License, Version 2.0 + Spring Boot AutoConfigure under Apache License, Version 2.0 + Spring Boot Data JPA Starter under Apache License, Version 2.0 + Spring Boot JDBC Starter under Apache License, Version 2.0 + Spring Boot Json Starter under Apache License, Version 2.0 + Spring Boot Logging Starter under Apache License, Version 2.0 + Spring Boot Starter under Apache License, Version 2.0 + Spring Boot Test under Apache License, Version 2.0 + Spring Boot Test Auto-Configure under Apache License, Version 2.0 + Spring Boot Test Starter under Apache License, Version 2.0 + Spring Boot Tomcat Starter under Apache License, Version 2.0 + Spring Boot Web Starter under Apache License, Version 2.0 + Spring Commons Logging Bridge under Apache License, Version 2.0 + Spring Context under Apache License, Version 2.0 + Spring Core under Apache License, Version 2.0 + Spring Data Core under Apache License, Version 2.0 + Spring Data JPA under Apache License, Version 2.0 + Spring Expression Language (SpEL) under Apache License, Version 2.0 + Spring JDBC under Apache License, Version 2.0 + Spring Object/Relational Mapping under Apache License, Version 2.0 + Spring TestContext Framework under Apache License, Version 2.0 + Spring Transaction under Apache License, Version 2.0 + Spring Web under Apache License, Version 2.0 + Spring Web MVC under Apache License, Version 2.0 + tomcat-embed-core under Apache License, Version 2.0 + tomcat-embed-el under Apache License, Version 2.0 + tomcat-embed-websocket under Apache License, Version 2.0 + + diff --git a/examples/pom.xml b/examples/pom.xml new file mode 100644 index 00000000..dbf35451 --- /dev/null +++ b/examples/pom.xml @@ -0,0 +1,26 @@ + + + + db-scheduler-parent + com.github.kagkarlsson + 5.3-SNAPSHOT + + + 4.0.0 + pom + + examples + db-scheduler: Examples + Examples for how to use db-scheduler + + + ${project.parent.basedir}/.license + + + + spring-boot-example + + + diff --git a/examples/spring-boot-example/NOTICE b/examples/spring-boot-example/NOTICE new file mode 100644 index 00000000..c90914de --- /dev/null +++ b/examples/spring-boot-example/NOTICE @@ -0,0 +1,101 @@ +Db-scheduler + +Copyright 2015 Gustav Karlsson. All Rights Reserved. + +This product includes software developed by Gustav Karlsson. +Licensed under Apache 2 - http://www.apache.org/licenses/LICENSE-2.0.html + + +This software includes third party software subject to the following licenses: + + AntLR Parser Generator under BSD License + Apache Log4j API under Apache License, Version 2.0 + Apache Log4j to SLF4J Adapter under Apache License, Version 2.0 + ASM based accessors helper used by json-smart under The Apache Software License, Version 2.0 + ASM Core under BSD + AspectJ weaver under Eclipse Public License - v 1.0 + AssertJ fluent assertions under Apache License, Version 2.0 + Bean Validation API under Apache License 2.0 + Byte Buddy (without dependencies) under Apache License, Version 2.0 + Byte Buddy Java agent under Apache License, Version 2.0 + ClassMate under The Apache Software License, Version 2.0 + cron-utils under Apache 2.0 + db-scheduler: Core under The Apache Software License, Version 2.0 + db-scheduler: Examples: Spring Boot under The Apache Software License, Version 2.0 + db-scheduler: Spring Boot Starter under The Apache Software License, Version 2.0 + dom4j under BSD 3-clause New License + Guava: Google Core Libraries for Java under The Apache Software License, Version 2.0 + Hamcrest Core under New BSD License + Hamcrest library under New BSD License + HdrHistogram under Public Domain, per Creative Commons CC0 + Hibernate Commons Annotations under GNU Lesser General Public License v2.1 or later + Hibernate ORM - hibernate-core under GNU Library General Public License v2.1 or later + Hibernate Validator Engine under Apache License 2.0 + HikariCP under The Apache Software License, Version 2.0 + HyperSQL Database under HSQLDB License, a BSD open source license + Jackson datatype: jdk8 under The Apache Software License, Version 2.0 + Jackson datatype: JSR310 under The Apache Software License, Version 2.0 + Jackson-annotations under The Apache Software License, Version 2.0 + Jackson-core under The Apache Software License, Version 2.0 + jackson-databind under The Apache Software License, Version 2.0 + Jackson-module-parameter-names under The Apache Software License, Version 2.0 + Java Annotation Indexer under Apache License, Version 2.0 + JavaBeans Activation Framework API jar under CDDL/GPLv2+CE + Javassist under MPL 1.1 or LGPL 2.1 or Apache License 2.0 + javax.annotation API under CDDL + GPLv2 with classpath exception + javax.persistence-api under Eclipse Public License v1.0 or Eclipse Distribution License v. 1.0 + javax.transaction API under CDDL + GPLv2 with classpath exception + jaxb-api under CDDL 1.1 or GPL2 w/ CPE + JBoss Logging 3 under Apache License, version 2.0 + JSON library from Android SDK under Apache License 2.0 + JSON Small and Fast Parser under The Apache Software License, Version 2.0 + JSONassert under The Apache Software License, Version 2.0 + JUL to SLF4J bridge under MIT License + JUnit under Eclipse Public License 1.0 + LatencyUtils under Public Domain, per Creative Commons CC0 + Logback Classic Module under Eclipse Public License - v 1.0 or GNU Lesser General Public License + Logback Core Module under Eclipse Public License - v 1.0 or GNU Lesser General Public License + Micro JDBC under The Apache Software License, Version 2.0 + micrometer-core under The Apache Software License, Version 2.0 + mockito-core under The MIT License + Objenesis under Apache 2 + org.xmlunit:xmlunit-core under The Apache Software License, Version 2.0 + project ':json-path' under The Apache Software License, Version 2.0 + SLF4J API Module under MIT License + SnakeYAML under Apache License, Version 2.0 + Spring AOP under Apache License, Version 2.0 + Spring Aspects under Apache License, Version 2.0 + Spring Beans under Apache License, Version 2.0 + Spring Boot under Apache License, Version 2.0 + Spring Boot Actuator under Apache License, Version 2.0 + Spring Boot Actuator AutoConfigure under Apache License, Version 2.0 + Spring Boot Actuator Starter under Apache License, Version 2.0 + Spring Boot AOP Starter under Apache License, Version 2.0 + Spring Boot AutoConfigure under Apache License, Version 2.0 + Spring Boot Data JPA Starter under Apache License, Version 2.0 + Spring Boot JDBC Starter under Apache License, Version 2.0 + Spring Boot Json Starter under Apache License, Version 2.0 + Spring Boot Logging Starter under Apache License, Version 2.0 + Spring Boot Starter under Apache License, Version 2.0 + Spring Boot Test under Apache License, Version 2.0 + Spring Boot Test Auto-Configure under Apache License, Version 2.0 + Spring Boot Test Starter under Apache License, Version 2.0 + Spring Boot Tomcat Starter under Apache License, Version 2.0 + Spring Boot Web Starter under Apache License, Version 2.0 + Spring Commons Logging Bridge under Apache License, Version 2.0 + Spring Context under Apache License, Version 2.0 + Spring Core under Apache License, Version 2.0 + Spring Data Core under Apache License, Version 2.0 + Spring Data JPA under Apache License, Version 2.0 + Spring Expression Language (SpEL) under Apache License, Version 2.0 + Spring JDBC under Apache License, Version 2.0 + Spring Object/Relational Mapping under Apache License, Version 2.0 + Spring TestContext Framework under Apache License, Version 2.0 + Spring Transaction under Apache License, Version 2.0 + Spring Web under Apache License, Version 2.0 + Spring Web MVC under Apache License, Version 2.0 + tomcat-embed-core under Apache License, Version 2.0 + tomcat-embed-el under Apache License, Version 2.0 + tomcat-embed-websocket under Apache License, Version 2.0 + + diff --git a/examples/spring-boot-example/README.md b/examples/spring-boot-example/README.md new file mode 100644 index 00000000..9bf8fb66 --- /dev/null +++ b/examples/spring-boot-example/README.md @@ -0,0 +1,39 @@ +# Spring Boot Example + +This Maven module provides a working example of the [db-scheduler](https://github.com/kagkarlsson/db-scheduler) running in a Spring Boot application using the provided Spring Boot starter. + +## Prerequisites + +- An existing Spring Boot application +- A working `DataSource` with schema initialized. (In the example HSQLDB is used and schema is automatically applied.) + +## How to use + +1. Add the following Maven dependency + ```xml + + com.github.kagkarlsson + db-scheduler-spring-boot-starter + 5.3 + + ``` + *NOTE*: This includes the db-scheduler dependency itself. +2. In your configuration, expose your `Task`'s as Spring beans. If they are recurring, they will automatically be picked up and started. +3. (Optional) Define a bean of type `DbSchedulerCustomizer` if you want to supply a custom naming strategy, serializer or `ExecutorService`. + +## Configuration options + +The Spring Boot integration exposes some configuration properties. For more configurability, consider defining a bean of type `DbSchedulerCustomzier`. + +``` +# Listing with default values + +db-scheduler.enabled=true +db-scheduler.heartbeat-interval=5m +db-scheduler.polling-interval=30s +db-scheduler.polling-limit= +db-scheduler.table-name=scheduled_tasks +db-scheduler.immediate-execution-enabled=false +db-scheduler.scheduler-name= +db-scheduler.threads=10 +``` diff --git a/examples/spring-boot-example/pom.xml b/examples/spring-boot-example/pom.xml new file mode 100644 index 00000000..1e4a61f7 --- /dev/null +++ b/examples/spring-boot-example/pom.xml @@ -0,0 +1,68 @@ + + + + examples + com.github.kagkarlsson + 5.3-SNAPSHOT + + 4.0.0 + + spring-boot-example + db-scheduler: Examples: Spring Boot + Examples on how to use db-scheduler with Spring Boot + + + ${project.parent.parent.basedir}/.license + + + + + + com.github.kagkarlsson + db-scheduler-spring-boot-starter + ${project.parent.version} + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-actuator + + + + + org.hsqldb + hsqldb + runtime + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + maven-dependency-plugin + + true + + + + + diff --git a/examples/spring-boot-example/src/main/java/com/github/kagkarlsson/examples/boot/App.java b/examples/spring-boot-example/src/main/java/com/github/kagkarlsson/examples/boot/App.java new file mode 100644 index 00000000..65ecd39a --- /dev/null +++ b/examples/spring-boot-example/src/main/java/com/github/kagkarlsson/examples/boot/App.java @@ -0,0 +1,33 @@ +package com.github.kagkarlsson.examples.boot; + +import com.github.kagkarlsson.scheduler.Scheduler; +import com.github.kagkarlsson.scheduler.task.Task; +import java.time.Instant; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class App { + private static final Logger log = LoggerFactory.getLogger(App.class); + + public static void main(String... args) { + SpringApplication.run(App.class, args); + } + + /** + * Example hack: use a {@link CommandLineRunner} to trigger scheduling of a one-time task. + */ + @Bean + CommandLineRunner executeOnStartup(Scheduler scheduler, Task sampleOneTimeTask) { + log.info("Scheduling one time task to now!"); + + return ignored -> scheduler.schedule( + sampleOneTimeTask.instance("command-line-runner"), + Instant.now() + ); + } +} diff --git a/examples/spring-boot-example/src/main/java/com/github/kagkarlsson/examples/boot/CounterController.java b/examples/spring-boot-example/src/main/java/com/github/kagkarlsson/examples/boot/CounterController.java new file mode 100644 index 00000000..a885d201 --- /dev/null +++ b/examples/spring-boot-example/src/main/java/com/github/kagkarlsson/examples/boot/CounterController.java @@ -0,0 +1,25 @@ +package com.github.kagkarlsson.examples.boot; + +import java.util.HashMap; +import java.util.Map; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/counter") +public class CounterController { + private final CounterService counter; + + public CounterController(CounterService counter) { + this.counter = counter; + } + + @GetMapping + public Map displayCounter() { + Map data = new HashMap<>(); + data.put("recurring_executions", counter.read()); + + return data; + } +} diff --git a/examples/spring-boot-example/src/main/java/com/github/kagkarlsson/examples/boot/CounterService.java b/examples/spring-boot-example/src/main/java/com/github/kagkarlsson/examples/boot/CounterService.java new file mode 100644 index 00000000..a5104b05 --- /dev/null +++ b/examples/spring-boot-example/src/main/java/com/github/kagkarlsson/examples/boot/CounterService.java @@ -0,0 +1,17 @@ +package com.github.kagkarlsson.examples.boot; + +import java.util.concurrent.atomic.AtomicLong; +import org.springframework.stereotype.Service; + +@Service +public class CounterService { + private final AtomicLong count = new AtomicLong(0L); + + public void increase() { + count.incrementAndGet(); + } + + public long read() { + return count.get(); + } +} diff --git a/examples/spring-boot-example/src/main/java/com/github/kagkarlsson/examples/boot/config/TaskConfiguration.java b/examples/spring-boot-example/src/main/java/com/github/kagkarlsson/examples/boot/config/TaskConfiguration.java new file mode 100644 index 00000000..05c8d31f --- /dev/null +++ b/examples/spring-boot-example/src/main/java/com/github/kagkarlsson/examples/boot/config/TaskConfiguration.java @@ -0,0 +1,61 @@ +package com.github.kagkarlsson.examples.boot.config; + +import static com.github.kagkarlsson.scheduler.task.schedule.Schedules.fixedDelay; + +import com.github.kagkarlsson.examples.boot.CounterService; +import com.github.kagkarlsson.scheduler.SchedulerName; +import com.github.kagkarlsson.scheduler.Serializer; +import com.github.kagkarlsson.scheduler.boot.config.DbSchedulerCustomizer; +import com.github.kagkarlsson.scheduler.task.Task; +import com.github.kagkarlsson.scheduler.task.helper.Tasks; +import java.time.Duration; +import java.util.Optional; +import java.util.concurrent.ExecutorService; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class TaskConfiguration { + private static final Logger log = LoggerFactory.getLogger(TaskConfiguration.class); + + /** + * Define a recurring task with a dependency, which will automatically be picked up by the + * Spring Boot autoconfiguration. + */ + @Bean + Task recurringSampleTask(CounterService counter) { + return Tasks + .recurring("recurring-sample-task", fixedDelay(Duration.ofMinutes(1))) + .execute((instance, ctx) -> { + log.info("Running recurring-simple-task. Instance: {}, ctx: {}", instance, ctx); + counter.increase(); + }); + } + + /** + * Define a one-time task which have to be manually scheduled. + */ + @Bean + Task sampleOneTimeTask() { + return Tasks.oneTime("sample-one-time-task") + .execute((instance, ctx) -> { + log.info("I am a one-time task!"); + }); + } + + /** + * Bean defined when a configuration-property in DbSchedulerCustomizer needs to be overridden. + */ + @Bean + DbSchedulerCustomizer customizer() { + return new DbSchedulerCustomizer() { + @Override + public Optional schedulerName() { + return Optional.of(new SchedulerName.Fixed("spring-boot-scheduler-1")); + } + }; + } +} diff --git a/examples/spring-boot-example/src/main/resources/application.properties b/examples/spring-boot-example/src/main/resources/application.properties new file mode 100644 index 00000000..287259dc --- /dev/null +++ b/examples/spring-boot-example/src/main/resources/application.properties @@ -0,0 +1,11 @@ +spring.application.name=spring-boot-example + +# Sane defaults +spring.jpa.open-in-view=false + +# Enable debug output for db-scheduler, just to visualize what's going on +logging.level.com.github.kagkarlsson.scheduler=DEBUG + +# Db-scheduler configuration +db-scheduler.threads=5 +db-scheduler.polling-interval=5s diff --git a/examples/spring-boot-example/src/main/resources/schema.sql b/examples/spring-boot-example/src/main/resources/schema.sql new file mode 100644 index 00000000..fd5de87c --- /dev/null +++ b/examples/spring-boot-example/src/main/resources/schema.sql @@ -0,0 +1,16 @@ +-- Table definition for HSQLDB. +-- Will get executed automatically by Spring Boot if the database is of type embedded. +create table if not exists scheduled_tasks ( + task_name varchar(100), + task_instance varchar(100), + task_data blob, + execution_time TIMESTAMP WITH TIME ZONE, + picked BIT, + picked_by varchar(50), + last_success TIMESTAMP WITH TIME ZONE, + last_failure TIMESTAMP WITH TIME ZONE, + consecutive_failures INT, + last_heartbeat TIMESTAMP WITH TIME ZONE, + version BIGINT, + PRIMARY KEY (task_name, task_instance) +); diff --git a/examples/spring-boot-example/src/test/java/com/github/kagkarlsson/examples/boot/SmokeTest.java b/examples/spring-boot-example/src/test/java/com/github/kagkarlsson/examples/boot/SmokeTest.java new file mode 100644 index 00000000..4a9e3521 --- /dev/null +++ b/examples/spring-boot-example/src/test/java/com/github/kagkarlsson/examples/boot/SmokeTest.java @@ -0,0 +1,56 @@ +package com.github.kagkarlsson.examples.boot; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.github.kagkarlsson.scheduler.Scheduler; +import com.github.kagkarlsson.scheduler.boot.actuator.DbSchedulerHealthIndicator; +import com.github.kagkarlsson.scheduler.task.Task; +import com.github.kagkarlsson.scheduler.task.helper.OneTimeTask; +import com.github.kagkarlsson.scheduler.task.helper.RecurringTask; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.context.ConfigurableWebApplicationContext; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class SmokeTest { + @Autowired + ConfigurableWebApplicationContext applicationContext; + AssertableWebApplicationContext ctx; + + @Autowired + DbSchedulerHealthIndicator healthIndicator; + + @Before + public void setup() { + this.ctx = AssertableWebApplicationContext.get(() -> applicationContext); + } + + @Test + public void it_should_load_context() { + assertThat(ctx).hasNotFailed(); + } + + @Test + public void it_should_have_a_scheduler_bean() { + assertThat(ctx).hasSingleBean(Scheduler.class); + } + + @Test + public void it_should_have_two_tasks_exposed_as_beans() { + assertThat(ctx.getBeansOfType(Task.class).values()).hasSize(2); + assertThat(ctx.getBeansOfType(OneTimeTask.class).values()).hasSize(1); + assertThat(ctx.getBeansOfType(RecurringTask.class).values()).hasSize(1); + } + + @Test + public void it_should_be_healthy_after_startup() { + assertThat(healthIndicator.health().getStatus()).isEqualTo(Status.UP); + } +} diff --git a/pom.xml b/pom.xml index 0356f52b..535bf838 100644 --- a/pom.xml +++ b/pom.xml @@ -3,11 +3,11 @@ 4.0.0 com.github.kagkarlsson - db-scheduler + db-scheduler-parent 5.3-SNAPSHOT - jar + pom - Db-scheduler + db-scheduler: Parent Simple persistent scheduler for scheduled tasks, recurring or ad-hoc. https://github.com/kagkarlsson/db-scheduler @@ -28,116 +28,46 @@ UTF-8 1.8 - 1.8 - 1.8 + ${jdk.version} + ${jdk.version} false true - 1.7.7 - 1.3 + ${project.basedir}/.license + + + 1.6 + 2.1.6.RELEASE - - - com.github.kagkarlsson - micro-jdbc - 0.1 - - - org.slf4j - slf4j-api - ${slf4j.version} - - - com.cronutils - cron-utils - 8.0.0 - + + db-scheduler + db-scheduler-boot-starter + examples + - - - org.slf4j - slf4j-simple - ${slf4j.version} - test - - - junit - junit - 4.12 - test - - - org.hamcrest - hamcrest-core - ${hamcrest.version} - test - - - org.hamcrest - hamcrest-library - ${hamcrest.version} - test - - - co.unruly - java-8-matchers - 1.6 - test - + com.google.guava guava 19.0 test - - org.hsqldb - hsqldb - 2.3.3 - test - - - org.postgresql - postgresql - 9.4.1207 - test - - - - com.opentable.components - otj-pg-embedded - 0.11.4 - test - - - com.zaxxer - HikariCP - 3.1.0 - test - - - + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + @@ -153,9 +83,9 @@ maven-notice-plugin 1.0.6.1 - ${project.basedir}/src/main/notice/NOTICE.template + ${license.dir}/NOTICE.template - ${project.basedir}/src/main/notice/license-mappings.xml + ${license.dir}/license-mappings.xml ${skipChecks} @@ -166,6 +96,7 @@ check verify + false @@ -175,7 +106,7 @@ license-maven-plugin 2.11 -

src/main/license-header.txt
+
${license.dir}/license-header.txt
true pom.xml @@ -183,8 +114,7 @@ NOTICE todo.txt .java-version - src/main/notice/NOTICE.template - src/main/notice/license-mappings.xml + .license/** src/test/** ${failOnMissingHeader} @@ -250,6 +180,85 @@ org.apache.commons:commons-compress org.tukaani:xz co.unruly:java-8-matchers + + org.springframework.boot:spring-boot-autoconfigure + org.springframework.boot:spring-boot-actuator-autoconfigure + org.springframework.boot:spring-boot-actuator + com.fasterxml.jackson.core:jackson-core + com.fasterxml.jackson.core:jackson-annotations + com.fasterxml.jackson.core:jackson-databind + com.fasterxml.jackson.datatype:jackson-datatype-jsr310 + org.slf4j:jul-to-slf4j + org.springframework:spring-jcl + com.github.kagkarlsson:db-scheduler + org.apache.logging.log4j:log4j-api + org.springframework.boot:spring-boot + ch.qos.logback:logback-core + org.springframework.boot:spring-boot-starter + org.springframework:spring-core + org.springframework:spring-expression + ch.qos.logback:logback-classic + javax.annotation:javax.annotation-api + org.springframework:spring-aop + org.springframework:spring-beans + org.apache.logging.log4j:log4j-to-slf4j + org.yaml:snakeyaml + org.springframework.boot:spring-boot-starter-logging + org.springframework:spring-context + org.springframework.boot:spring-boot-autoconfigure-processor + org.springframework.boot:spring-boot-configuration-processor + javax.validation:validation-api + net.minidev:json-smart + org.skyscreamer:jsonassert + org.springframework.boot:spring-boot-test-autoconfigure + net.minidev:accessors-smart + org.ow2.asm:asm + org.jboss.logging:jboss-logging + org.springframework.boot:spring-boot-starter-jdbc + org.xmlunit:xmlunit-core + org.springframework:spring-jdbc + org.hibernate.validator:hibernate-validator + org.assertj:assertj-core + com.fasterxml:classmate + org.springframework.boot:spring-boot-test + net.bytebuddy:byte-buddy + com.jayway.jsonpath:json-path + org.springframework:spring-tx + org.springframework:spring-test + com.vaadin.external.google:android-json + org.springframework.boot:spring-boot-starter-test + net.bytebuddy:byte-buddy-agent + + org.jboss:jandex + javax.xml.bind:jaxb-api + org.springframework.boot:spring-boot-starter-web + org.springframework.data:spring-data-commons + org.apache.tomcat.embed:tomcat-embed-el + org.hibernate:hibernate-core + org.hibernate.common:hibernate-commons-annotations + com.fasterxml.jackson.datatype:jackson-datatype-jdk8 + org.springframework.data:spring-data-jpa + org.springframework.boot:spring-boot-starter-aop + javax.transaction:javax.transaction-api + javax.activation:javax.activation-api + org.springframework:spring-aspects + org.springframework:spring-orm + org.springframework.boot:spring-boot-starter-tomcat + org.springframework:spring-web + org.aspectj:aspectjweaver + org.hdrhistogram:HdrHistogram + org.apache.tomcat.embed:tomcat-embed-core + org.springframework.boot:spring-boot-starter-actuator + com.github.kagkarlsson:db-scheduler-spring-boot-starter + com.fasterxml.jackson.module:jackson-module-parameter-names + org.springframework.boot:spring-boot-starter-data-jpa + org.apache.tomcat.embed:tomcat-embed-websocket + org.latencyutils:LatencyUtils + org.springframework.boot:spring-boot-starter-json + org.springframework:spring-webmvc + io.micrometer:micrometer-core + javax.persistence:javax.persistence-api + org.dom4j:dom4j true @@ -330,7 +339,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 + ${gpg-maven-plugin.version} sign-artifacts @@ -372,10 +381,6 @@ - - com.mycila - license-maven-plugin - org.jasig.maven maven-notice-plugin @@ -383,9 +388,6 @@ maven-enforcer-plugin - - maven-shade-plugin - @@ -416,6 +418,7 @@ org.apache.maven.plugins maven-gpg-plugin + ${gpg-maven-plugin.version}