From cc878bf94e8b6aec040e728012e3f0794593d858 Mon Sep 17 00:00:00 2001 From: Pere Miquel Brull Date: Fri, 23 Feb 2024 08:14:12 +0100 Subject: [PATCH] MINOR - Prepare App Instances & fix bigtable json (#15292) * MINOR - Prepare App Exception & fix bigtable json * Do not init the app all the time and allow to fetch initialized resources * init installed apps * Add runtime props * Add runtime props * Format --- .../service/apps/AppException.java | 32 +++++++++++++++ .../service/apps/ApplicationHandler.java | 40 +++++++++++++++---- .../service/jdbi3/AppRepository.java | 6 +-- .../service/resources/apps/AppResource.java | 15 +++++++ .../testConnections/database/bigtable.json | 2 +- 5 files changed, 83 insertions(+), 12 deletions(-) create mode 100644 openmetadata-service/src/main/java/org/openmetadata/service/apps/AppException.java diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/apps/AppException.java b/openmetadata-service/src/main/java/org/openmetadata/service/apps/AppException.java new file mode 100644 index 000000000000..dc8dcba82760 --- /dev/null +++ b/openmetadata-service/src/main/java/org/openmetadata/service/apps/AppException.java @@ -0,0 +1,32 @@ +package org.openmetadata.service.apps; + +import javax.ws.rs.core.Response; +import org.openmetadata.sdk.exception.WebServiceException; + +public class AppException extends WebServiceException { + + private static final String BY_NAME_MESSAGE = "Application [%s] Exception [%s] due to [%s]."; + private static final String ERROR_TYPE = "PIPELINE_SERVICE_ERROR"; + + public AppException(String message) { + super(Response.Status.BAD_REQUEST, ERROR_TYPE, message); + } + + private AppException(Response.Status status, String message) { + super(status, ERROR_TYPE, message); + } + + public static AppException byMessage( + String appName, String name, String errorMessage, Response.Status status) { + return new AppException(status, buildMessageByName(appName, name, errorMessage)); + } + + public static AppException byMessage(String appName, String name, String errorMessage) { + return new AppException( + Response.Status.BAD_REQUEST, buildMessageByName(appName, name, errorMessage)); + } + + private static String buildMessageByName(String appName, String name, String errorMessage) { + return String.format(BY_NAME_MESSAGE, appName, name, errorMessage); + } +} diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/apps/ApplicationHandler.java b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ApplicationHandler.java index 1b65ba76eb8e..c70edba97d81 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/apps/ApplicationHandler.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ApplicationHandler.java @@ -2,6 +2,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.HashMap; import lombok.extern.slf4j.Slf4j; import org.openmetadata.schema.entity.app.App; import org.openmetadata.service.exception.UnhandledServerException; @@ -11,6 +12,12 @@ @Slf4j public class ApplicationHandler { + private static HashMap instances = new HashMap<>(); + + public static Object getAppInstance(String className) { + return instances.get(className); + } + private ApplicationHandler() { /*Helper*/ } @@ -30,19 +37,36 @@ public static void configureApplication( runMethodFromApplication(app, daoCollection, searchRepository, "configure"); } + public static Object runAppInit( + App app, CollectionDAO daoCollection, SearchRepository searchRepository) + throws ClassNotFoundException, + NoSuchMethodException, + InvocationTargetException, + InstantiationException, + IllegalAccessException { + Class clz = Class.forName(app.getClassName()); + Object resource = + clz.getDeclaredConstructor(CollectionDAO.class, SearchRepository.class) + .newInstance(daoCollection, searchRepository); + + // Call init Method + Method initMethod = resource.getClass().getMethod("init", App.class); + initMethod.invoke(resource, app); + + instances.put(app.getClassName(), resource); + + return resource; + } + /** Load an App from its className and call its methods dynamically */ public static void runMethodFromApplication( App app, CollectionDAO daoCollection, SearchRepository searchRepository, String methodName) { // Native Application try { - Class clz = Class.forName(app.getClassName()); - Object resource = - clz.getDeclaredConstructor(CollectionDAO.class, SearchRepository.class) - .newInstance(daoCollection, searchRepository); - - // Call init Method - Method initMethod = resource.getClass().getMethod("init", App.class); - initMethod.invoke(resource, app); + Object resource = getAppInstance(app.getClassName()); + if (resource == null) { + resource = runAppInit(app, daoCollection, searchRepository); + } // Call method on demand Method scheduleMethod = resource.getClass().getMethod(methodName); diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/AppRepository.java b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/AppRepository.java index dfa42c3d6085..23d5d0ab7666 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/AppRepository.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/AppRepository.java @@ -164,12 +164,12 @@ public void storeRelationships(App entity) { } } - public final List listAll() { + public final List listAll() { // forward scrolling, if after == null then first page is being asked List jsons = dao.listAfterWithOffset(Integer.MAX_VALUE, 0); - List entities = new ArrayList<>(); + List entities = new ArrayList<>(); for (String json : jsons) { - AppRunRecord entity = JsonUtils.readValue(json, AppRunRecord.class); + App entity = JsonUtils.readValue(json, App.class); entities.add(entity); } return entities; diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/apps/AppResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/apps/AppResource.java index 596fed2f7922..3cf18bb2d130 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/apps/AppResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/apps/AppResource.java @@ -143,6 +143,21 @@ public void initialize(OpenMetadataApplicationConfig config) { ApplicationHandler.installApplication(app, Entity.getCollectionDAO(), searchRepository); } } + + // Initialize installed applications + for (App installedApp : repository.listAll()) { + App appWithBot = getAppForInit(installedApp.getName()); + if (appWithBot == null) { + LOG.error( + String.format( + "Failed to init app [%s]. GET should return the installed app", + installedApp.getName())); + } else { + setAppRuntimeProperties(appWithBot); + ApplicationHandler.runAppInit(appWithBot, dao, searchRepository); + LOG.info(String.format("Initialized installed app [%s]", installedApp.getName())); + } + } } catch (Exception ex) { LOG.error("Failed in Create App Requests", ex); } diff --git a/openmetadata-service/src/main/resources/json/data/testConnections/database/bigtable.json b/openmetadata-service/src/main/resources/json/data/testConnections/database/bigtable.json index 86ca0bb17ac2..2de02892236d 100644 --- a/openmetadata-service/src/main/resources/json/data/testConnections/database/bigtable.json +++ b/openmetadata-service/src/main/resources/json/data/testConnections/database/bigtable.json @@ -20,7 +20,7 @@ { "name": "ReadRows", "description": "Validate that we can read rows with the given credentials.", - "errorMessage": "Failed to read rows from BigTable, please validate to the credentials of service account" + "errorMessage": "Failed to read rows from BigTable, please validate to the credentials of service account", "shortCircuit": true, "mandatory": true }