Skip to content

Commit

Permalink
Merge pull request #852 from jobrunr/bugfix/GH-847
Browse files Browse the repository at this point in the history
Fix #847
  • Loading branch information
rdehuyss committed Oct 16, 2023
2 parents 9458147 + d25ec7d commit cab0d63
Show file tree
Hide file tree
Showing 14 changed files with 462 additions and 356 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.jobrunr.micronaut.autoconfigure;

import io.micronaut.context.event.ShutdownEvent;
import io.micronaut.context.event.StartupEvent;
import io.micronaut.runtime.event.annotation.EventListener;
import io.micronaut.runtime.server.event.ServerShutdownEvent;
import io.micronaut.runtime.server.event.ServerStartupEvent;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import org.jobrunr.dashboard.JobRunrDashboardWebServer;
Expand All @@ -27,7 +27,7 @@ public class JobRunrStarter {
private Optional<JobRunrDashboardWebServer> dashboardWebServer;

@EventListener
void startup(ServerStartupEvent event) {
void startup(StartupEvent event) {
if (configuration.getBackgroundJobServer().isEnabled()) {
backgroundJobServer.get().start();
}
Expand All @@ -37,7 +37,7 @@ void startup(ServerStartupEvent event) {
}

@EventListener
void shutdown(ServerShutdownEvent event) {
void shutdown(ShutdownEvent event) {
if (configuration.getBackgroundJobServer().isEnabled()) {
backgroundJobServer.get().stop();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ public class JobRunrElasticSearchStorageProviderFactory {
public StorageProvider elasticSearchStorageProvider(ElasticsearchClient elasticsearchClient, JobMapper jobMapper) {
String tablePrefix = configuration.getDatabase().getTablePrefix().orElse(null);
StorageProviderUtils.DatabaseOptions databaseOptions = configuration.getDatabase().isSkipCreate() ? StorageProviderUtils.DatabaseOptions.SKIP_CREATE : StorageProviderUtils.DatabaseOptions.CREATE;
ElasticSearchStorageProvider elasticSearchStorageProvider = new ElasticSearchStorageProvider(elasticsearchClient);
new ElasticSearchStorageProvider(elasticsearchClient, tablePrefix, databaseOptions);
ElasticSearchStorageProvider elasticSearchStorageProvider = new ElasticSearchStorageProvider(elasticsearchClient, tablePrefix, databaseOptions);
elasticSearchStorageProvider.setJobMapper(jobMapper);
return elasticSearchStorageProvider;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,25 @@
import io.micronaut.context.annotation.Property;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.jobrunr.storage.StorageProvider;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

import static org.jobrunr.micronaut.MicronautAssertions.assertThat;

@MicronautTest(rebuildContext = true)
@TestMethodOrder(MethodOrderer.MethodName.class)
class JobRunrHealthIndicatorRegistrationTest {

@Inject
ApplicationContext context;

@Test
void aFirstTestThatReloadsTheContextToMakeFlakyTestWork() {
assertThat(context).hasSingleBean(StorageProvider.class);
}

@Test
@Property(name = "jobrunr.background-job-server.enabled", value = "true")
void jobRunrHealthIndicatorEnabledAutoConfiguration() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,25 @@
package org.jobrunr.micronaut.autoconfigure.storage;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.cluster.ElasticsearchClusterClient;
import co.elastic.clients.elasticsearch.core.GetResponse;
import co.elastic.clients.elasticsearch.indices.ElasticsearchIndicesClient;
import co.elastic.clients.elasticsearch.indices.ExistsRequest;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import io.micronaut.context.ApplicationContext;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import org.jobrunr.storage.InMemoryStorageProvider;
import org.jobrunr.storage.StorageProvider;
import org.jobrunr.storage.nosql.elasticsearch.ElasticSearchStorageProvider;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.function.Function;

import static org.jobrunr.micronaut.MicronautAssertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@MicronautTest(rebuildContext = true)
@MicronautTest
class JobRunrElasticSearchStorageProviderFactoryTest {

@Inject
ApplicationContext context;

@BeforeEach
void setupElasticSearchClient() throws IOException {
context.registerSingleton(elasticsearchClient());
}

@Test
void elasticSearchStorageProviderAutoConfigurationTest() {
assertThat(context).hasSingleBean(StorageProvider.class);
Expand All @@ -43,25 +29,8 @@ void elasticSearchStorageProviderAutoConfigurationTest() {
assertThat(context).doesNotHaveBean(InMemoryStorageProvider.class);
}

public static ElasticsearchClient elasticsearchClient() throws IOException {
final ElasticsearchClient client = mock(ElasticsearchClient.class);

final GetResponse<?> getResponse = mock(GetResponse.class);
when(getResponse.found()).thenReturn(true);
when(client.get(any(Function.class), any())).thenAnswer(args -> getResponse);

final BooleanResponse exists = new BooleanResponse(true);
when(client.exists(any(Function.class))).thenReturn(exists);

final ElasticsearchIndicesClient indices = mock(ElasticsearchIndicesClient.class);
when(client.indices()).thenReturn(indices);

when(indices.exists(any(Function.class))).thenReturn(exists);
when(indices.exists(any(ExistsRequest.class))).thenReturn(exists);

final ElasticsearchClusterClient cluster = mock(ElasticsearchClusterClient.class);
when(client.cluster()).thenReturn(cluster);

return client;
@Singleton
public ElasticsearchClient elasticsearchClient() throws IOException {
return Mocks.elasticsearchClient();
}
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,23 @@
package org.jobrunr.micronaut.autoconfigure.storage;

import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import io.micronaut.context.ApplicationContext;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import org.jobrunr.storage.InMemoryStorageProvider;
import org.jobrunr.storage.StorageProvider;
import org.jobrunr.storage.nosql.redis.LettuceRedisStorageProvider;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.jobrunr.micronaut.MicronautAssertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@MicronautTest(rebuildContext = true)
@MicronautTest
class JobRunrLettuceRedisStorageProviderFactoryTest {

@Inject
ApplicationContext context;

@BeforeEach
void setupRedisClient() {
context.registerSingleton(redisClient());
}

@Test
void lettuceRedisStorageProviderAutoConfigurationTest() {
assertThat(context).hasSingleBean(StorageProvider.class);
Expand All @@ -36,11 +27,8 @@ void lettuceRedisStorageProviderAutoConfigurationTest() {
assertThat(context).doesNotHaveBean(InMemoryStorageProvider.class);
}

@Singleton
public RedisClient redisClient() {
RedisClient redisClient = mock(RedisClient.class);
StatefulRedisConnection connection = mock(StatefulRedisConnection.class);
when(connection.sync()).thenReturn(mock(RedisCommands.class));
when(redisClient.connect()).thenReturn(connection);
return redisClient;
return Mocks.redisClient();
}
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,23 @@
package org.jobrunr.micronaut.autoconfigure.storage;

import com.mongodb.client.*;
import com.mongodb.client.result.InsertOneResult;
import com.mongodb.client.MongoClient;
import io.micronaut.context.ApplicationContext;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.bson.Document;
import org.bson.conversions.Bson;
import jakarta.inject.Singleton;
import org.jobrunr.storage.InMemoryStorageProvider;
import org.jobrunr.storage.StorageProvider;
import org.jobrunr.storage.StorageProviderUtils;
import org.jobrunr.storage.nosql.mongo.MongoDBStorageProvider;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Spliterator;

import static org.jobrunr.micronaut.MicronautAssertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@MicronautTest(rebuildContext = true)
@MicronautTest
class JobRunrMongoDBStorageProviderFactoryTest {

@Inject
ApplicationContext context;

@BeforeEach
void setupMongoClient() {
context.registerSingleton(mongoClient());
}

@Test
void mongoDBStorageProviderAutoConfigurationTest() {
assertThat(context).hasSingleBean(StorageProvider.class);
Expand All @@ -41,30 +27,8 @@ void mongoDBStorageProviderAutoConfigurationTest() {
assertThat(context).doesNotHaveBean(InMemoryStorageProvider.class);
}

@Singleton
public MongoClient mongoClient() {
MongoClient mongoClientMock = mock(MongoClient.class);
MongoDatabase mongoDatabaseMock = mock(MongoDatabase.class);
when(mongoClientMock.getDatabase("jobrunr")).thenReturn(mongoDatabaseMock);
when(mongoDatabaseMock.listCollectionNames()).thenReturn(mock(MongoIterable.class));

MongoCollection migrationCollectionMock = mock(MongoCollection.class);
when(migrationCollectionMock.find(any(Bson.class))).thenReturn(mock(FindIterable.class));
when(migrationCollectionMock.insertOne(any())).thenReturn(mock(InsertOneResult.class));
when(mongoDatabaseMock.getCollection(StorageProviderUtils.Migrations.NAME)).thenReturn(migrationCollectionMock);

ListIndexesIterable listIndicesMock = mock(ListIndexesIterable.class);
when(listIndicesMock.spliterator()).thenReturn(mock(Spliterator.class));

MongoCollection recurringJobCollectionMock = mock(MongoCollection.class);
when(recurringJobCollectionMock.listIndexes()).thenReturn(listIndicesMock);

MongoCollection jobCollectionMock = mock(MongoCollection.class);
when(jobCollectionMock.listIndexes()).thenReturn(listIndicesMock);

when(mongoDatabaseMock.getCollection(StorageProviderUtils.RecurringJobs.NAME, Document.class)).thenReturn(jobCollectionMock);
when(mongoDatabaseMock.getCollection(StorageProviderUtils.Jobs.NAME, Document.class)).thenReturn(jobCollectionMock);
when(mongoDatabaseMock.getCollection(StorageProviderUtils.BackgroundJobServers.NAME, Document.class)).thenReturn(mock(MongoCollection.class));
when(mongoDatabaseMock.getCollection(StorageProviderUtils.Metadata.NAME, Document.class)).thenReturn(mock(MongoCollection.class));
return mongoClientMock;
return Mocks.mongoClient();
}
}
Original file line number Diff line number Diff line change
@@ -1,40 +1,32 @@
package org.jobrunr.micronaut.autoconfigure.storage;


import co.elastic.clients.elasticsearch.ElasticsearchClient;
import io.micronaut.context.ApplicationContext;
import io.micronaut.context.annotation.Property;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import org.jobrunr.storage.InMemoryStorageProvider;
import org.jobrunr.storage.StorageProvider;
import org.jobrunr.storage.sql.SqlStorageProvider;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.*;
import java.sql.SQLException;

import static org.jobrunr.micronaut.MicronautAssertions.assertThat;
import static org.jobrunr.micronaut.autoconfigure.storage.JobRunrElasticSearchStorageProviderFactoryTest.elasticsearchClient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@MicronautTest(rebuildContext = true)
@MicronautTest
@Property(name = "jobrunr.database.skip-create", value = "true")
@Property(name = "jobrunr.database.type", value = "sql")
class JobRunrMultipleStorageProviderFactoryTest {

@Inject
ApplicationContext context;

@BeforeEach
void setupDataSource() throws SQLException, IOException {
context.registerSingleton(elasticsearchClient());
context.registerSingleton(dataSource());
}

@Test
@Property(name = "jobrunr.database.skip-create", value = "true")
@Property(name = "jobrunr.database.type", value = "sql")
void sqlStorageProviderAutoConfigurationTest() {
assertThat(context).hasSingleBean(StorageProvider.class);
assertThat(context.getBean(StorageProvider.class))
Expand All @@ -43,28 +35,14 @@ void sqlStorageProviderAutoConfigurationTest() {
assertThat(context).doesNotHaveBean(InMemoryStorageProvider.class);
}

@Singleton
public DataSource dataSource() throws SQLException {
DataSource dataSourceMock = mock(DataSource.class);
Connection connectionMock = mock(Connection.class);
DatabaseMetaData databaseMetaData = mock(DatabaseMetaData.class);
when(dataSourceMock.getConnection()).thenReturn(connectionMock);
when(connectionMock.getMetaData()).thenReturn(databaseMetaData);
when(databaseMetaData.getURL()).thenReturn("jdbc:sqlite:this is not important");

mockTablePresent(connectionMock, "jobrunr_jobs", "jobrunr_recurring_jobs", "jobrunr_backgroundjobservers", "jobrunr_metadata");

return dataSourceMock;
return Mocks.dataSource();
}

private void mockTablePresent(Connection connectionMock, String... tableNames) throws SQLException {
Statement statementMock = mock(Statement.class);
when(connectionMock.createStatement()).thenReturn(statementMock);
for (String tableName : tableNames) {
ResultSet resultSetMock = mock(ResultSet.class);
when(statementMock.executeQuery("select count(*) from " + tableName)).thenReturn(resultSetMock);
when(resultSetMock.next()).thenReturn(true);
when(resultSetMock.getInt(1)).thenReturn(1);
}
@Singleton
public ElasticsearchClient elasticsearchClient() throws IOException {
return Mocks.elasticsearchClient();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.jobrunr.micronaut.autoconfigure.storage;


import io.micronaut.context.ApplicationContext;
import io.micronaut.context.annotation.Property;
import io.micronaut.inject.qualifiers.Qualifiers;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.inject.Singleton;
import org.jobrunr.storage.InMemoryStorageProvider;
import org.jobrunr.storage.StorageProvider;
import org.jobrunr.storage.sql.SqlStorageProvider;
import org.junit.jupiter.api.Test;

import javax.sql.DataSource;
import java.sql.SQLException;

import static org.jobrunr.micronaut.MicronautAssertions.assertThat;

@MicronautTest
@Property(name = "jobrunr.database.skip-create", value = "true")
@Property(name = "jobrunr.database.datasource", value = "jobrunr")
class JobRunrNamedSqlStorageProviderFactoryTest {

@Inject
ApplicationContext context;

@Test
void sqlStorageProviderAutoConfigurationTestWithMultipleNamedDataSources() throws SQLException {
// GIVEN
context.registerSingleton(dataSource());
context.registerSingleton(DataSource.class, dataSource(), Qualifiers.byName("jobrunr"));

// WHEN & THEN
assertThat(context).hasSingleBean(StorageProvider.class);
assertThat(context.getBean(StorageProvider.class))
.isInstanceOf(SqlStorageProvider.class)
.hasJobMapper();
assertThat(context).doesNotHaveBean(InMemoryStorageProvider.class);
}

@Singleton
public DataSource dataSource() throws SQLException {
return Mocks.dataSource();
}

@Singleton
@Named("jobrunr")
public DataSource jobRunrDataSource() throws SQLException {
return Mocks.dataSource();
}

}

0 comments on commit cab0d63

Please sign in to comment.