diff --git a/bootstrap/sql/migrations/native/1.2.0/mysql/schemaChanges.sql b/bootstrap/sql/migrations/native/1.2.0/mysql/schemaChanges.sql index 6312ce49bb8..5c181bf3d53 100644 --- a/bootstrap/sql/migrations/native/1.2.0/mysql/schemaChanges.sql +++ b/bootstrap/sql/migrations/native/1.2.0/mysql/schemaChanges.sql @@ -217,8 +217,6 @@ CREATE TABLE IF NOT EXISTS apps_marketplace ( CREATE TABLE IF NOT EXISTS apps_extension_time_series ( appId VARCHAR(36) GENERATED ALWAYS AS (json ->> '$.appId') STORED NOT NULL, - extension VARCHAR(256) NOT NULL, - jsonSchema VARCHAR(256) NOT NULL, json JSON NOT NULL, timestamp BIGINT UNSIGNED GENERATED ALWAYS AS (json ->> '$.timestamp') NOT NULL ); diff --git a/bootstrap/sql/migrations/native/1.2.0/postgres/schemaChanges.sql b/bootstrap/sql/migrations/native/1.2.0/postgres/schemaChanges.sql index 96b4f0023fe..c56f2ff43a8 100644 --- a/bootstrap/sql/migrations/native/1.2.0/postgres/schemaChanges.sql +++ b/bootstrap/sql/migrations/native/1.2.0/postgres/schemaChanges.sql @@ -227,8 +227,6 @@ CREATE TABLE IF NOT EXISTS apps_marketplace ( CREATE TABLE IF NOT EXISTS apps_extension_time_series ( appId VARCHAR(36) GENERATED ALWAYS AS (json ->> 'appId') STORED NOT NULL, - extension VARCHAR(256) NOT NULL, - jsonSchema VARCHAR(256) NOT NULL, json JSONB NOT NULL, timestamp BIGINT GENERATED ALWAYS AS ((json ->> 'timestamp')::bigint) STORED NOT NULL ); \ No newline at end of file diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/apps/scheduler/AbstractOmAppJobListener.java b/openmetadata-service/src/main/java/org/openmetadata/service/apps/scheduler/AbstractOmAppJobListener.java index ff3d1ccf581..6560d6b4adf 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/apps/scheduler/AbstractOmAppJobListener.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/apps/scheduler/AbstractOmAppJobListener.java @@ -51,9 +51,7 @@ public abstract class AbstractOmAppJobListener implements JobListener { dataMap.put(SCHEDULED_APP_RUN_EXTENSION, runRecord); // Run the Scheduled Run Record on the time series - collectionDAO - .appExtensionTimeSeriesDao() - .insert(SCHEDULED_APP_RUN_EXTENSION, SCHEDULED_APP_RUN_RECORD_SCHEMA, JsonUtils.pojoToJson(runRecord)); + collectionDAO.appExtensionTimeSeriesDao().insert(JsonUtils.pojoToJson(runRecord)); this.doJobToBeExecuted(jobExecutionContext); } @@ -85,11 +83,7 @@ public abstract class AbstractOmAppJobListener implements JobListener { collectionDAO .appExtensionTimeSeriesDao() - .update( - runRecord.getAppId().toString(), - SCHEDULED_APP_RUN_EXTENSION, - JsonUtils.pojoToJson(runRecord), - runRecord.getTimestamp()); + .update(runRecord.getAppId().toString(), JsonUtils.pojoToJson(runRecord), runRecord.getTimestamp()); this.doJobWasExecuted(jobExecutionContext, jobException); } 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 4ecb3dde565..c44e0c14d4e 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 @@ -203,6 +203,11 @@ public class AppRepository extends EntityRepository { } } + public AppRunRecord getLatestAppRuns(UUID appId) { + String json = daoCollection.appExtensionTimeSeriesDao().getLatestAppRun(appId); + return JsonUtils.readValue(json, AppRunRecord.class); + } + @Override public EntityUpdater getUpdater(App original, App updated, Operation operation) { return new AppRepository.AppUpdater(original, updated, operation); diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java index 9e63268ef89..93540494760 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java @@ -3334,35 +3334,22 @@ public interface CollectionDAO { } interface AppExtensionTimeSeries { - - @SqlQuery("SELECT json FROM apps_extension_time_series WHERE appId = :appId ORDER BY timestamp DESC LIMIT 1") - String getLatestAppRun(@Bind("appId") String appId); + @ConnectionAwareSqlUpdate( + value = "INSERT INTO apps_extension_time_series(json) " + "VALUES (:json)", + connectionType = MYSQL) + @ConnectionAwareSqlUpdate( + value = "INSERT INTO apps_extension_time_series(json) " + "VALUES ((:json :: jsonb))", + connectionType = POSTGRES) + void insert(@Bind("json") String json); @ConnectionAwareSqlUpdate( - value = - "INSERT INTO apps_extension_time_series(extension, jsonSchema, json) " - + "VALUES (:extension, :jsonSchema, :json)", + value = "UPDATE apps_extension_time_series set json = :json where appId=:appId and timestamp=:timestamp", connectionType = MYSQL) @ConnectionAwareSqlUpdate( value = - "INSERT INTO apps_extension_time_series(extension, jsonSchema, json) " - + "VALUES (:extension, :jsonSchema, (:json :: jsonb))", + "UPDATE apps_extension_time_series set json = (:json :: jsonb) where appId=:appId and timestamp=:timestamp", connectionType = POSTGRES) - void insert(@Bind("extension") String extension, @Bind("jsonSchema") String jsonSchema, @Bind("json") String json); - - @ConnectionAwareSqlUpdate( - value = - "UPDATE apps_extension_time_series set json = :json where appId=:appId and extension=:extension and timestamp=:timestamp", - connectionType = MYSQL) - @ConnectionAwareSqlUpdate( - value = - "UPDATE apps_extension_time_series set json = (:json :: jsonb) where appId=:appId and extension=:extension and timestamp=:timestamp", - connectionType = POSTGRES) - void update( - @Bind("appId") String appId, - @Bind("extension") String extension, - @Bind("json") String json, - @Bind("timestamp") Long timestamp); + void update(@Bind("appId") String appId, @Bind("json") String json, @Bind("timestamp") Long timestamp); @SqlQuery("SELECT count(*) FROM apps_extension_time_series where appId = :appId") int listAppRunRecordCount(@Bind("appId") String appId); @@ -3370,6 +3357,14 @@ public interface CollectionDAO { @SqlQuery( "SELECT json FROM apps_extension_time_series where appId = :appId ORDER BY timestamp DESC LIMIT :limit OFFSET :offset") List listAppRunRecord(@Bind("appId") String appId, @Bind("limit") int limit, @Bind("offset") int offset); + + default String getLatestAppRun(UUID appId) { + List result = listAppRunRecord(appId.toString(), 1, 0); + if (result != null && !result.isEmpty()) { + return result.get(0); + } + throw new RuntimeException("No Available Application Run Records."); + } } interface ReportDataTimeSeriesDAO extends EntityTimeSeriesDAO { 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 03166b719ca..4727af2c9bf 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 @@ -225,6 +225,26 @@ public class AppResource extends EntityResource { return repository.listAppRuns(installation.getId(), limitParam, offset); } + @GET + @Path("/name/{name}/runs/latest") + @Operation( + operationId = "latestAppRunRecord", + summary = "Get Latest App Run Record", + description = "Get a latest applications Run Record.", + responses = { + @ApiResponse( + responseCode = "200", + description = "List of Installed Applications Runs", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = AppRunRecord.class))) + }) + public AppRunRecord listLatestAppRun( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Name of the App", schema = @Schema(type = "string")) @PathParam("name") String name) { + App installation = repository.getByName(uriInfo, name, repository.getFields("id")); + return repository.getLatestAppRuns(installation.getId()); + } + @GET @Path("/{id}/versions") @Operation(