MINOR: add the systemApp property (#15473)

* feat: add "systemApp" property

* use BAD_REQUEST for System Apps uninstall

* use IllegalArgumentException
This commit is contained in:
Imri Paran 2024-03-11 15:39:20 +01:00 committed by GitHub
parent 67c57ec4f0
commit 4bb5550a46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 52 additions and 3 deletions

View File

@ -442,7 +442,8 @@ public class AppMarketPlaceResource
.withAppScreenshots(create.getAppScreenshots())
.withFeatures(create.getFeatures())
.withSourcePythonClass(create.getSourcePythonClass())
.withAllowConfiguration(create.getAllowConfiguration());
.withAllowConfiguration(create.getAllowConfiguration())
.withSystemApp(create.getSystemApp());
// Validate App
validateApplication(app);

View File

@ -66,6 +66,7 @@ import org.openmetadata.service.OpenMetadataApplicationConfig;
import org.openmetadata.service.apps.ApplicationHandler;
import org.openmetadata.service.apps.scheduler.AppScheduler;
import org.openmetadata.service.clients.pipeline.PipelineServiceClientFactory;
import org.openmetadata.service.exception.CatalogExceptionMessage;
import org.openmetadata.service.exception.EntityNotFoundException;
import org.openmetadata.service.jdbi3.AppRepository;
import org.openmetadata.service.jdbi3.CollectionDAO;
@ -651,6 +652,9 @@ public class AppResource extends EntityResource<App, AppRepository> {
description = "Delete a App by `name`.",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(
responseCode = "400",
description = "System entity {name} of type SystemApp can not be deleted."),
@ApiResponse(responseCode = "404", description = "App for instance {name} is not found")
})
public Response delete(
@ -664,6 +668,10 @@ public class AppResource extends EntityResource<App, AppRepository> {
@PathParam("name")
String name) {
App app = repository.getByName(null, name, repository.getFields("bot,pipelines"));
if (app.getSystemApp()) {
throw new IllegalArgumentException(
CatalogExceptionMessage.systemEntityDeleteNotAllowed(app.getName(), "SystemApp"));
}
// Remove from Pipeline Service
deleteApp(securityContext, app, hardDelete);
return deleteByName(uriInfo, securityContext, name, true, hardDelete);
@ -677,6 +685,9 @@ public class AppResource extends EntityResource<App, AppRepository> {
description = "Delete a App by `Id`.",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(
responseCode = "400",
description = "System entity {name} of type SystemApp can not be deleted."),
@ApiResponse(responseCode = "404", description = "App for instance {id} is not found")
})
public Response delete(
@ -689,6 +700,10 @@ public class AppResource extends EntityResource<App, AppRepository> {
@Parameter(description = "Id of the App", schema = @Schema(type = "UUID")) @PathParam("id")
UUID id) {
App app = repository.get(null, id, repository.getFields("bot,pipelines"));
if (app.getSystemApp()) {
throw new IllegalArgumentException(
CatalogExceptionMessage.systemEntityDeleteNotAllowed(app.getName(), "SystemApp"));
}
// Remove from Pipeline Service
deleteApp(securityContext, app, hardDelete);
// Remove from repository
@ -955,7 +970,8 @@ public class AppResource extends EntityResource<App, AppRepository> {
.withAppScreenshots(marketPlaceDefinition.getAppScreenshots())
.withFeatures(marketPlaceDefinition.getFeatures())
.withSourcePythonClass(marketPlaceDefinition.getSourcePythonClass())
.withAllowConfiguration(marketPlaceDefinition.getAllowConfiguration());
.withAllowConfiguration(marketPlaceDefinition.getAllowConfiguration())
.withSystemApp(marketPlaceDefinition.getSystemApp());
// validate Bot if provided
validateAndAddBot(app, createAppRequest.getBot());

View File

@ -1,7 +1,10 @@
package org.openmetadata.service.resources.apps;
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import static org.openmetadata.service.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.service.util.TestUtils.assertResponseContains;
import java.io.IOException;
import java.util.Map;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@ -19,6 +22,7 @@ import org.openmetadata.service.util.TestUtils;
@Slf4j
public class AppsResourceTest extends EntityResourceTest<App, CreateApp> {
private static final String SYSTEM_APP_NAME = "systemApp";
public AppsResourceTest() {
super(Entity.APPLICATION, App.class, AppResource.AppList.class, "apps", AppResource.FIELDS);
@ -36,7 +40,10 @@ public class AppsResourceTest extends EntityResourceTest<App, CreateApp> {
appMarketPlaceDefinition =
appMarketPlaceResourceTest.getEntityByName(name, ADMIN_AUTH_HEADERS);
} catch (EntityNotFoundException | HttpResponseException ex) {
CreateAppMarketPlaceDefinitionReq req = appMarketPlaceResourceTest.createRequest(name);
CreateAppMarketPlaceDefinitionReq req =
appMarketPlaceResourceTest
.createRequest(name)
.withSystemApp(name.equals(SYSTEM_APP_NAME));
appMarketPlaceDefinition =
appMarketPlaceResourceTest.createAndCheckEntity(req, ADMIN_AUTH_HEADERS);
}
@ -54,6 +61,16 @@ public class AppsResourceTest extends EntityResourceTest<App, CreateApp> {
// Does not apply since the App is already validated in the AppMarketDefinition
}
@Test
void delete_systemApp_400() throws IOException {
CreateApp systemAppRequest = createRequest(SYSTEM_APP_NAME);
App systemApp = createAndCheckEntity(systemAppRequest, ADMIN_AUTH_HEADERS);
assertResponseContains(
() -> deleteEntity(systemApp.getId(), ADMIN_AUTH_HEADERS),
BAD_REQUEST,
"of type SystemApp can not be deleted");
}
@Override
public void validateCreatedEntity(
App createdEntity, CreateApp request, Map<String, String> authHeaders)

View File

@ -195,6 +195,11 @@
"type": "boolean",
"default": true
},
"systemApp": {
"description": "A system app cannot be uninstall.",
"type": "boolean",
"default": false
},
"appConfiguration": {
"description": "Application Configuration object.",
"$ref": "./configuration/applicationConfig.json#/definitions/appConfig"

View File

@ -130,6 +130,11 @@
"type": "string"
},
"uniqueItems": true
},
"systemApp": {
"description": "If the app is a system app, it cannot be uninstalled.",
"type": "boolean",
"default": false
}
},
"additionalProperties": false,

View File

@ -97,6 +97,11 @@
"type": "string"
},
"uniqueItems": true
},
"systemApp": {
"description": "If the app is a system app, it cannot be uninstalled.",
"type": "boolean",
"default": false
}
},
"additionalProperties": false,