diff --git a/airbyte-server/src/main/java/io/airbyte/server/ServerApp.java b/airbyte-server/src/main/java/io/airbyte/server/ServerApp.java index 6eb2c4f7391eb..8ec8ac60b8248 100644 --- a/airbyte-server/src/main/java/io/airbyte/server/ServerApp.java +++ b/airbyte-server/src/main/java/io/airbyte/server/ServerApp.java @@ -59,6 +59,7 @@ import io.airbyte.server.handlers.DbMigrationHandler; import io.airbyte.server.handlers.DestinationDefinitionsHandler; import io.airbyte.server.handlers.DestinationHandler; +import io.airbyte.server.handlers.HealthCheckHandler; import io.airbyte.server.handlers.OperationsHandler; import io.airbyte.server.handlers.SchedulerHandler; import io.airbyte.server.scheduler.DefaultSynchronousSchedulerClient; @@ -299,6 +300,8 @@ public static ServerRunnable getServer(final ServerFactory apiFactory, final DestinationDefinitionsHandler destinationDefinitionsHandler = new DestinationDefinitionsHandler(configRepository, syncSchedulerClient, destinationHandler); + final HealthCheckHandler healthCheckHandler = new HealthCheckHandler(configRepository); + LOGGER.info("Starting server..."); return apiFactory.create( @@ -323,6 +326,7 @@ public static ServerRunnable getServer(final ServerFactory apiFactory, dbMigrationHandler, destinationDefinitionsHandler, destinationHandler, + healthCheckHandler, operationsHandler, schedulerHandler); } diff --git a/airbyte-server/src/main/java/io/airbyte/server/ServerFactory.java b/airbyte-server/src/main/java/io/airbyte/server/ServerFactory.java index 8a6e6246bc5f1..42a18c32ddc6e 100644 --- a/airbyte-server/src/main/java/io/airbyte/server/ServerFactory.java +++ b/airbyte-server/src/main/java/io/airbyte/server/ServerFactory.java @@ -21,23 +21,27 @@ import io.airbyte.server.apis.DestinationApiController; import io.airbyte.server.apis.DestinationDefinitionApiController; import io.airbyte.server.apis.DestinationDefinitionSpecificationApiController; +import io.airbyte.server.apis.HealthApiController; import io.airbyte.server.apis.binders.AttemptApiBinder; import io.airbyte.server.apis.binders.ConnectionApiBinder; import io.airbyte.server.apis.binders.DbMigrationBinder; import io.airbyte.server.apis.binders.DestinationApiBinder; import io.airbyte.server.apis.binders.DestinationDefinitionApiBinder; import io.airbyte.server.apis.binders.DestinationDefinitionSpecificationApiBinder; +import io.airbyte.server.apis.binders.HealthApiBinder; import io.airbyte.server.apis.factories.AttemptApiFactory; import io.airbyte.server.apis.factories.ConnectionApiFactory; import io.airbyte.server.apis.factories.DbMigrationApiFactory; import io.airbyte.server.apis.factories.DestinationApiFactory; import io.airbyte.server.apis.factories.DestinationDefinitionApiFactory; import io.airbyte.server.apis.factories.DestinationDefinitionSpecificationApiFactory; +import io.airbyte.server.apis.factories.HealthApiFactory; import io.airbyte.server.handlers.AttemptHandler; import io.airbyte.server.handlers.ConnectionsHandler; import io.airbyte.server.handlers.DbMigrationHandler; import io.airbyte.server.handlers.DestinationDefinitionsHandler; import io.airbyte.server.handlers.DestinationHandler; +import io.airbyte.server.handlers.HealthCheckHandler; import io.airbyte.server.handlers.OperationsHandler; import io.airbyte.server.handlers.SchedulerHandler; import io.airbyte.server.scheduler.EventRunner; @@ -72,6 +76,7 @@ ServerRunnable create(final SynchronousSchedulerClient synchronousSchedulerClien final DbMigrationHandler dbMigrationHandler, final DestinationDefinitionsHandler destinationDefinitionsHandler, final DestinationHandler destinationApiHandler, + final HealthCheckHandler healthCheckHandler, final OperationsHandler operationsHandler, final SchedulerHandler schedulerHandler); @@ -99,6 +104,7 @@ public ServerRunnable create(final SynchronousSchedulerClient synchronousSchedul final DbMigrationHandler dbMigrationHandler, final DestinationDefinitionsHandler destinationDefinitionsHandler, final DestinationHandler destinationApiHandler, + final HealthCheckHandler healthCheckHandler, final OperationsHandler operationsHandler, final SchedulerHandler schedulerHandler) { final Map mdc = MDC.getCopyOfContextMap(); @@ -140,13 +146,29 @@ public ServerRunnable create(final SynchronousSchedulerClient synchronousSchedul DestinationDefinitionSpecificationApiFactory.setValues(schedulerHandler); + HealthApiFactory.setValues(healthCheckHandler); + // server configurations - final Set> componentClasses = Set.of(ConfigurationApi.class, AttemptApiController.class, ConnectionApiController.class, - DbMigrationApiController.class, DestinationApiController.class, DestinationDefinitionApiController.class, - DestinationDefinitionSpecificationApiController.class); - final Set components = Set.of(new CorsFilter(), new ConfigurationApiBinder(), new AttemptApiBinder(), new ConnectionApiBinder(), - new DbMigrationBinder(), new DestinationApiBinder(), new DestinationDefinitionApiBinder(), - new DestinationDefinitionSpecificationApiBinder()); + final Set> componentClasses = Set.of( + ConfigurationApi.class, + AttemptApiController.class, + ConnectionApiController.class, + DbMigrationApiController.class, + DestinationApiController.class, + DestinationDefinitionApiController.class, + DestinationDefinitionSpecificationApiController.class, + HealthApiController.class); + + final Set components = Set.of( + new CorsFilter(), + new ConfigurationApiBinder(), + new AttemptApiBinder(), + new ConnectionApiBinder(), + new DbMigrationBinder(), + new DestinationApiBinder(), + new DestinationDefinitionApiBinder(), + new DestinationDefinitionSpecificationApiBinder(), + new HealthApiBinder()); // construct server return new ServerApp(airbyteVersion, componentClasses, components); diff --git a/airbyte-server/src/main/java/io/airbyte/server/apis/ConfigurationApi.java b/airbyte-server/src/main/java/io/airbyte/server/apis/ConfigurationApi.java index f6172b53dea11..6bc240c92a41e 100644 --- a/airbyte-server/src/main/java/io/airbyte/server/apis/ConfigurationApi.java +++ b/airbyte-server/src/main/java/io/airbyte/server/apis/ConfigurationApi.java @@ -116,7 +116,6 @@ import io.airbyte.server.handlers.ConnectionsHandler; import io.airbyte.server.handlers.DestinationDefinitionsHandler; import io.airbyte.server.handlers.DestinationHandler; -import io.airbyte.server.handlers.HealthCheckHandler; import io.airbyte.server.handlers.JobHistoryHandler; import io.airbyte.server.handlers.LogsHandler; import io.airbyte.server.handlers.OAuthHandler; @@ -157,7 +156,6 @@ public class ConfigurationApi implements io.airbyte.api.generated.V1Api { private final JobHistoryHandler jobHistoryHandler; private final WebBackendConnectionsHandler webBackendConnectionsHandler; private final WebBackendGeographiesHandler webBackendGeographiesHandler; - private final HealthCheckHandler healthCheckHandler; private final LogsHandler logsHandler; private final OpenApiConfigHandler openApiConfigHandler; private final OAuthHandler oAuthHandler; @@ -169,7 +167,6 @@ public ConfigurationApi(final ConfigRepository configRepository, final JobPersistence jobPersistence, final SecretsRepositoryReader secretsRepositoryReader, final SecretsRepositoryWriter secretsRepositoryWriter, - final SynchronousSchedulerClient synchronousSchedulerClient, final StatePersistence statePersistence, final TrackingClient trackingClient, @@ -238,7 +235,6 @@ public ConfigurationApi(final ConfigRepository configRepository, eventRunner, configRepository); webBackendGeographiesHandler = new WebBackendGeographiesHandler(); - healthCheckHandler = new HealthCheckHandler(configRepository); logsHandler = new LogsHandler(); openApiConfigHandler = new OpenApiConfigHandler(); } @@ -936,9 +932,13 @@ public File getOpenApiSpec() { } // HEALTH + /** + * This implementation has been moved to {@link HealthApiController}. Since the path of + * {@link HealthApiController} is more granular, it will override this implementation + */ @Override public HealthCheckRead getHealthCheck() { - return healthCheckHandler.health(); + throw new NotImplementedException(); } // WEB BACKEND diff --git a/airbyte-server/src/main/java/io/airbyte/server/apis/HealthApiController.java b/airbyte-server/src/main/java/io/airbyte/server/apis/HealthApiController.java new file mode 100644 index 0000000000000..75c10ca4852b2 --- /dev/null +++ b/airbyte-server/src/main/java/io/airbyte/server/apis/HealthApiController.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.server.apis; + +import io.airbyte.api.generated.HealthApi; +import io.airbyte.api.model.generated.HealthCheckRead; +import io.airbyte.server.handlers.HealthCheckHandler; +import javax.ws.rs.Path; +import lombok.AllArgsConstructor; + +@Path("/v1/health") +@AllArgsConstructor +public class HealthApiController implements HealthApi { + + private final HealthCheckHandler healthCheckHandler; + + @Override + public HealthCheckRead getHealthCheck() { + return healthCheckHandler.health(); + } + +} diff --git a/airbyte-server/src/main/java/io/airbyte/server/apis/binders/HealthApiBinder.java b/airbyte-server/src/main/java/io/airbyte/server/apis/binders/HealthApiBinder.java new file mode 100644 index 0000000000000..bfe6161529f8f --- /dev/null +++ b/airbyte-server/src/main/java/io/airbyte/server/apis/binders/HealthApiBinder.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2022 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.server.apis.binders; + +import io.airbyte.server.apis.HealthApiController; +import io.airbyte.server.apis.factories.HealthApiFactory; +import org.glassfish.hk2.utilities.binding.AbstractBinder; +import org.glassfish.jersey.process.internal.RequestScoped; + +public class HealthApiBinder extends AbstractBinder { + + @Override + protected void configure() { + bindFactory(HealthApiFactory.class) + .to(HealthApiController.class) + .in(RequestScoped.class); + } + +} diff --git a/airbyte-server/src/main/java/io/airbyte/server/apis/factories/HealthApiFactory.java b/airbyte-server/src/main/java/io/airbyte/server/apis/factories/HealthApiFactory.java new file mode 100644 index 0000000000000..b13c17d5ebb25 --- /dev/null +++ b/airbyte-server/src/main/java/io/airbyte/server/apis/factories/HealthApiFactory.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.server.apis.factories; + +import io.airbyte.server.apis.HealthApiController; +import io.airbyte.server.handlers.HealthCheckHandler; +import org.glassfish.hk2.api.Factory; + +public class HealthApiFactory implements Factory { + + private static HealthCheckHandler healthCheckHandler; + + public static void setValues(final HealthCheckHandler healthCheckHandler) { + HealthApiFactory.healthCheckHandler = healthCheckHandler; + } + + @Override + public HealthApiController provide() { + return new HealthApiController(healthCheckHandler); + } + + @Override + public void dispose(final HealthApiController instance) { + /* no op */ + } + +} diff --git a/airbyte-server/src/test/java/io/airbyte/server/apis/ConfigurationApiTest.java b/airbyte-server/src/test/java/io/airbyte/server/apis/ConfigurationApiTest.java deleted file mode 100644 index 34ec37f2cd4de..0000000000000 --- a/airbyte-server/src/test/java/io/airbyte/server/apis/ConfigurationApiTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2022 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.server.apis; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import io.airbyte.analytics.TrackingClient; -import io.airbyte.commons.version.AirbyteVersion; -import io.airbyte.config.Configs; -import io.airbyte.config.Configs.WorkerEnvironment; -import io.airbyte.config.helpers.LogConfigs; -import io.airbyte.config.persistence.ConfigRepository; -import io.airbyte.config.persistence.SecretsRepositoryReader; -import io.airbyte.config.persistence.SecretsRepositoryWriter; -import io.airbyte.config.persistence.StatePersistence; -import io.airbyte.persistence.job.JobPersistence; -import io.airbyte.server.scheduler.EventRunner; -import io.airbyte.server.scheduler.SynchronousSchedulerClient; -import java.net.http.HttpClient; -import java.nio.file.Path; -import org.junit.jupiter.api.Test; - -class ConfigurationApiTest { - - @Test - void testImportDefinitions() { - final Configs configs = mock(Configs.class); - when(configs.getAirbyteVersion()).thenReturn(new AirbyteVersion("0.1.0-alpha")); - when(configs.getWebappUrl()).thenReturn("http://localhost"); - - final ConfigurationApi configurationApi = new ConfigurationApi( - mock(ConfigRepository.class), - mock(JobPersistence.class), - mock(SecretsRepositoryReader.class), - mock(SecretsRepositoryWriter.class), - mock(SynchronousSchedulerClient.class), - mock(StatePersistence.class), - mock(TrackingClient.class), - WorkerEnvironment.DOCKER, - LogConfigs.EMPTY, - new AirbyteVersion("0.1.0-alpha"), - Path.of(""), - mock(HttpClient.class), - mock(EventRunner.class)); - - assertFalse(configurationApi.getHealthCheck().getAvailable()); - } - -} diff --git a/airbyte-server/src/test/java/io/airbyte/server/apis/HealthCheckApiTest.java b/airbyte-server/src/test/java/io/airbyte/server/apis/HealthCheckApiTest.java new file mode 100644 index 0000000000000..cc4f5d814e35e --- /dev/null +++ b/airbyte-server/src/test/java/io/airbyte/server/apis/HealthCheckApiTest.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.server.apis; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.airbyte.api.model.generated.HealthCheckRead; +import io.airbyte.server.handlers.HealthCheckHandler; +import org.junit.jupiter.api.Test; + +class HealthCheckApiTest { + + @Test + void testImportDefinitions() { + final HealthCheckHandler healthCheckHandler = mock(HealthCheckHandler.class); + when(healthCheckHandler.health()) + .thenReturn(new HealthCheckRead().available( + false)); + + final HealthApiController configurationApi = new HealthApiController(healthCheckHandler); + + assertFalse(configurationApi.getHealthCheck().getAvailable()); + } + +}