From ce9127e871aee888df4afc242dffe1f17280cc18 Mon Sep 17 00:00:00 2001 From: Cole Snodgrass Date: Fri, 9 Dec 2022 11:58:05 -0800 Subject: [PATCH] micronaut OperationApiController (#20270) * micronaut OperationApiController * pass micronaut client to OperationApi --- .../airbyte/api/client/AirbyteApiClient.java | 8 ++--- airbyte-proxy/nginx-auth.conf.template | 34 +++++++++++++++++++ airbyte-proxy/nginx-no-auth.conf.template | 16 +++++++++ .../java/io/airbyte/server/ServerFactory.java | 5 --- .../server/apis/OperationApiController.java | 30 ++++++++++------ .../apis/binders/OperationApiBinder.java | 21 ------------ .../apis/factories/OperationApiFactory.java | 29 ---------------- .../server/handlers/OperationsHandler.java | 12 ++++--- 8 files changed, 82 insertions(+), 73 deletions(-) delete mode 100644 airbyte-server/src/main/java/io/airbyte/server/apis/binders/OperationApiBinder.java delete mode 100644 airbyte-server/src/main/java/io/airbyte/server/apis/factories/OperationApiFactory.java diff --git a/airbyte-api/src/main/java/io/airbyte/api/client/AirbyteApiClient.java b/airbyte-api/src/main/java/io/airbyte/api/client/AirbyteApiClient.java index d0cdb1225257..cf53428e296d 100644 --- a/airbyte-api/src/main/java/io/airbyte/api/client/AirbyteApiClient.java +++ b/airbyte-api/src/main/java/io/airbyte/api/client/AirbyteApiClient.java @@ -28,12 +28,12 @@ * This class is meant to consolidate all our API endpoints into a fluent-ish client. Currently, all * open API generators create a separate class per API "root-route". For example, if our API has two * routes "/v1/First/get" and "/v1/Second/get", OpenAPI generates (essentially) the following files: - * + *

* ApiClient.java, FirstApi.java, SecondApi.java - * + *

* To call the API type-safely, we'd do new FirstApi(new ApiClient()).get() or new SecondApi(new * ApiClient()).get(), which can get cumbersome if we're interacting with many pieces of the API. - * + *

* This is currently manually maintained. We could look into autogenerating it if needed. */ public class AirbyteApiClient { @@ -67,7 +67,7 @@ public AirbyteApiClient(final ApiClient apiClient, final ApiClient micronautApiC destinationSpecificationApi = new DestinationDefinitionSpecificationApi(apiClient); jobsApi = new JobsApi(apiClient); logsApi = new PatchedLogsApi(apiClient); - operationApi = new OperationApi(apiClient); + operationApi = new OperationApi(micronautApiClient); sourceDefinitionApi = new SourceDefinitionApi(apiClient); sourceApi = new SourceApi(apiClient); sourceDefinitionSpecificationApi = new SourceDefinitionSpecificationApi(apiClient); diff --git a/airbyte-proxy/nginx-auth.conf.template b/airbyte-proxy/nginx-auth.conf.template index 6a8019ca4857..1a0f6ee8c247 100644 --- a/airbyte-proxy/nginx-auth.conf.template +++ b/airbyte-proxy/nginx-auth.conf.template @@ -37,6 +37,23 @@ http { auth_basic off; } } + + location /api/v1/operations { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + auth_basic "Welcome to Airbyte"; + auth_basic_user_file /etc/nginx/.htpasswd; + + proxy_pass "${PROXY_PASS_MICRONAUT_API}"; + + error_page 401 /etc/nginx/401.html; + location ~ (401.html)$ { + alias /etc/nginx/$1; + auth_basic off; + } + } } server { @@ -75,6 +92,23 @@ http { auth_basic off; } } + + location /api/v1/operations { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + auth_basic "Welcome to Airbyte"; + auth_basic_user_file /etc/nginx/.htpasswd; + + proxy_pass "${PROXY_PASS_MICRONAUT_API}"; + + error_page 401 /etc/nginx/401.html; + location ~ (401.html)$ { + alias /etc/nginx/$1; + auth_basic off; + } + } } server { diff --git a/airbyte-proxy/nginx-no-auth.conf.template b/airbyte-proxy/nginx-no-auth.conf.template index 631abdf127c6..3de1d4fa54c8 100644 --- a/airbyte-proxy/nginx-no-auth.conf.template +++ b/airbyte-proxy/nginx-no-auth.conf.template @@ -19,6 +19,14 @@ http { proxy_pass "${PROXY_PASS_MICRONAUT_API}"; } + + location /api/v1/operations { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_pass "${PROXY_PASS_MICRONAUT_API}"; + } } server { @@ -39,6 +47,14 @@ http { proxy_pass "${PROXY_PASS_MICRONAUT_API}"; } + + location /api/v1/operations { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_pass "${PROXY_PASS_MICRONAUT_API}"; + } } server { 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 7af5812856c4..4a8ba1617dfa 100644 --- a/airbyte-server/src/main/java/io/airbyte/server/ServerFactory.java +++ b/airbyte-server/src/main/java/io/airbyte/server/ServerFactory.java @@ -40,7 +40,6 @@ import io.airbyte.server.apis.binders.LogsApiBinder; import io.airbyte.server.apis.binders.NotificationApiBinder; import io.airbyte.server.apis.binders.OpenapiApiBinder; -import io.airbyte.server.apis.binders.OperationApiBinder; import io.airbyte.server.apis.binders.SchedulerApiBinder; import io.airbyte.server.apis.binders.SourceApiBinder; import io.airbyte.server.apis.binders.SourceDefinitionApiBinder; @@ -58,7 +57,6 @@ import io.airbyte.server.apis.factories.LogsApiFactory; import io.airbyte.server.apis.factories.NotificationsApiFactory; import io.airbyte.server.apis.factories.OpenapiApiFactory; -import io.airbyte.server.apis.factories.OperationApiFactory; import io.airbyte.server.apis.factories.SchedulerApiFactory; import io.airbyte.server.apis.factories.SourceApiFactory; import io.airbyte.server.apis.factories.SourceDefinitionApiFactory; @@ -192,8 +190,6 @@ public ServerRunnable create(final SynchronousSchedulerClient synchronousSchedul NotificationsApiFactory.setValues(workspacesHandler); - OperationApiFactory.setValues(operationsHandler); - OpenapiApiFactory.setValues(openApiConfigHandler); SchedulerApiFactory.setValues(schedulerHandler); @@ -242,7 +238,6 @@ public ServerRunnable create(final SynchronousSchedulerClient synchronousSchedul new LogsApiBinder(), new NotificationApiBinder(), new OpenapiApiBinder(), - new OperationApiBinder(), new SchedulerApiBinder(), new SourceApiBinder(), new SourceDefinitionApiBinder(), diff --git a/airbyte-server/src/main/java/io/airbyte/server/apis/OperationApiController.java b/airbyte-server/src/main/java/io/airbyte/server/apis/OperationApiController.java index 3b4eeb9ee431..10eabb1571fd 100644 --- a/airbyte-server/src/main/java/io/airbyte/server/apis/OperationApiController.java +++ b/airbyte-server/src/main/java/io/airbyte/server/apis/OperationApiController.java @@ -14,45 +14,55 @@ import io.airbyte.api.model.generated.OperationUpdate; import io.airbyte.api.model.generated.OperatorConfiguration; import io.airbyte.server.handlers.OperationsHandler; -import javax.ws.rs.Path; -import lombok.AllArgsConstructor; +import io.micronaut.http.annotation.Body; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Post; -@Path("/v1/operations") -@AllArgsConstructor +@Controller("/api/v1/operations") public class OperationApiController implements OperationApi { private final OperationsHandler operationsHandler; + public OperationApiController(final OperationsHandler operationsHandler) { + this.operationsHandler = operationsHandler; + } + + @Post("/check") @Override - public CheckOperationRead checkOperation(final OperatorConfiguration operatorConfiguration) { + public CheckOperationRead checkOperation(@Body final OperatorConfiguration operatorConfiguration) { return ApiHelper.execute(() -> operationsHandler.checkOperation(operatorConfiguration)); } + @Post("/create") @Override - public OperationRead createOperation(final OperationCreate operationCreate) { + public OperationRead createOperation(@Body final OperationCreate operationCreate) { return ApiHelper.execute(() -> operationsHandler.createOperation(operationCreate)); } + @Post("/delete") @Override - public void deleteOperation(final OperationIdRequestBody operationIdRequestBody) { + public void deleteOperation(@Body final OperationIdRequestBody operationIdRequestBody) { ApiHelper.execute(() -> { operationsHandler.deleteOperation(operationIdRequestBody); return null; }); } + @Post("/get") @Override - public OperationRead getOperation(final OperationIdRequestBody operationIdRequestBody) { + public OperationRead getOperation(@Body final OperationIdRequestBody operationIdRequestBody) { return ApiHelper.execute(() -> operationsHandler.getOperation(operationIdRequestBody)); } + @Post("/list") @Override - public OperationReadList listOperationsForConnection(final ConnectionIdRequestBody connectionIdRequestBody) { + public OperationReadList listOperationsForConnection(@Body final ConnectionIdRequestBody connectionIdRequestBody) { return ApiHelper.execute(() -> operationsHandler.listOperationsForConnection(connectionIdRequestBody)); } + @Post("/update") @Override - public OperationRead updateOperation(final OperationUpdate operationUpdate) { + public OperationRead updateOperation(@Body final OperationUpdate operationUpdate) { return ApiHelper.execute(() -> operationsHandler.updateOperation(operationUpdate)); } diff --git a/airbyte-server/src/main/java/io/airbyte/server/apis/binders/OperationApiBinder.java b/airbyte-server/src/main/java/io/airbyte/server/apis/binders/OperationApiBinder.java deleted file mode 100644 index 52d55383aeca..000000000000 --- a/airbyte-server/src/main/java/io/airbyte/server/apis/binders/OperationApiBinder.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2022 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.server.apis.binders; - -import io.airbyte.server.apis.OperationApiController; -import io.airbyte.server.apis.factories.OperationApiFactory; -import org.glassfish.hk2.utilities.binding.AbstractBinder; -import org.glassfish.jersey.process.internal.RequestScoped; - -public class OperationApiBinder extends AbstractBinder { - - @Override - protected void configure() { - bindFactory(OperationApiFactory.class) - .to(OperationApiController.class) - .in(RequestScoped.class); - } - -} diff --git a/airbyte-server/src/main/java/io/airbyte/server/apis/factories/OperationApiFactory.java b/airbyte-server/src/main/java/io/airbyte/server/apis/factories/OperationApiFactory.java deleted file mode 100644 index d74ad9138170..000000000000 --- a/airbyte-server/src/main/java/io/airbyte/server/apis/factories/OperationApiFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2022 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.server.apis.factories; - -import io.airbyte.server.apis.OperationApiController; -import io.airbyte.server.handlers.OperationsHandler; -import org.glassfish.hk2.api.Factory; - -public class OperationApiFactory implements Factory { - - private static OperationsHandler operationsHandler; - - public static void setValues(final OperationsHandler operationsHandler) { - OperationApiFactory.operationsHandler = operationsHandler; - } - - @Override - public OperationApiController provide() { - return new OperationApiController(OperationApiFactory.operationsHandler); - } - - @Override - public void dispose(final OperationApiController instance) { - /* no op */ - } - -} diff --git a/airbyte-server/src/main/java/io/airbyte/server/handlers/OperationsHandler.java b/airbyte-server/src/main/java/io/airbyte/server/handlers/OperationsHandler.java index 749a6ebf0e83..7e6c45140508 100644 --- a/airbyte-server/src/main/java/io/airbyte/server/handlers/OperationsHandler.java +++ b/airbyte-server/src/main/java/io/airbyte/server/handlers/OperationsHandler.java @@ -25,6 +25,8 @@ import io.airbyte.config.persistence.ConfigRepository; import io.airbyte.server.converters.OperationsConverter; import io.airbyte.validation.json.JsonValidationException; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; @@ -32,21 +34,23 @@ import java.util.UUID; import java.util.function.Supplier; +@Singleton public class OperationsHandler { private final ConfigRepository configRepository; private final Supplier uuidGenerator; + @Inject + public OperationsHandler(final ConfigRepository configRepository) { + this(configRepository, UUID::randomUUID); + } + @VisibleForTesting OperationsHandler(final ConfigRepository configRepository, final Supplier uuidGenerator) { this.configRepository = configRepository; this.uuidGenerator = uuidGenerator; } - public OperationsHandler(final ConfigRepository configRepository) { - this(configRepository, UUID::randomUUID); - } - public CheckOperationRead checkOperation(final OperatorConfiguration operationCheck) { try { validateOperation(operationCheck);