Fix #8416: Restore Entities after soft delete with all it's old data (#8635)

This commit is contained in:
Sriharsha Chintalapani 2022-11-13 10:16:01 -08:00 committed by GitHub
parent ebfb872e16
commit 9e34cb8440
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 710 additions and 60 deletions

View File

@ -901,7 +901,7 @@ public abstract class EntityRepository<T extends EntityInterface> {
return RestUtil.getHref(uriInfo, collectionPath, id); return RestUtil.getHref(uriInfo, collectionPath, id);
} }
public void restoreEntity(String updatedBy, String entityType, UUID id) throws IOException { public T restoreEntity(String updatedBy, String entityType, UUID id) throws IOException {
// If an entity being restored contains other **deleted** children entities, restore them // If an entity being restored contains other **deleted** children entities, restore them
List<EntityRelationshipRecord> records = List<EntityRelationshipRecord> records =
daoCollection.relationshipDAO().findTo(id.toString(), entityType, Relationship.CONTAINS.ordinal()); daoCollection.relationshipDAO().findTo(id.toString(), entityType, Relationship.CONTAINS.ordinal());
@ -919,6 +919,7 @@ public abstract class EntityRepository<T extends EntityInterface> {
T entity = dao.findEntityById(id, DELETED); T entity = dao.findEntityById(id, DELETED);
entity.setDeleted(false); entity.setDeleted(false);
dao.update(entity.getId(), JsonUtils.pojoToJson(entity)); dao.update(entity.getId(), JsonUtils.pojoToJson(entity));
return entity;
} }
public void addRelationship(UUID fromId, UUID toId, String fromEntity, String toEntity, Relationship relationship) { public void addRelationship(UUID fromId, UUID toId, String fromEntity, String toEntity, Relationship relationship) {

View File

@ -247,6 +247,14 @@ public abstract class EntityResource<T extends EntityInterface, K extends Entity
return response.toResponse(); return response.toResponse();
} }
public Response restoreEntity(UriInfo uriInfo, SecurityContext securityContext, UUID id) throws IOException {
OperationContext operationContext = new OperationContext(entityType, MetadataOperation.EDIT_ALL);
authorizer.authorize(securityContext, operationContext, getResourceContextById(id));
T entity = addHref(uriInfo, dao.restoreEntity(securityContext.getUserPrincipal().getName(), entityType, id));
LOG.info("Restored {}:{}", Entity.getEntityTypeFromObject(entity), entity.getId());
return Response.ok(entity.getHref()).entity(entity).build();
}
public T copy(T entity, CreateEntity request, String updatedBy) throws IOException { public T copy(T entity, CreateEntity request, String updatedBy) throws IOException {
EntityReference owner = dao.validateOwner(request.getOwner()); EntityReference owner = dao.validateOwner(request.getOwner());
entity.setId(UUID.randomUUID()); entity.setId(UUID.randomUUID());

View File

@ -37,6 +37,7 @@ import lombok.NonNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.openmetadata.schema.analytics.WebAnalyticEvent; import org.openmetadata.schema.analytics.WebAnalyticEvent;
import org.openmetadata.schema.analytics.WebAnalyticEventData; import org.openmetadata.schema.analytics.WebAnalyticEventData;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.tests.CreateWebAnalyticEvent; import org.openmetadata.schema.api.tests.CreateWebAnalyticEvent;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.Include;
@ -278,6 +279,26 @@ public class WebAnalyticEventResource extends EntityResource<WebAnalyticEvent, W
return delete(uriInfo, securityContext, id, false, hardDelete); return delete(uriInfo, securityContext, id, false, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted WebAnalyticEvent.",
tags = "webAnalyticEvent",
description = "Restore a soft deleted WebAnalyticEvent.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the WebAnalyticEvent. ",
content =
@Content(mediaType = "application/json", schema = @Schema(implementation = WebAnalyticEvent.class)))
})
public Response restoreWebAnalyticEvent(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
@GET @GET
@Path("/name/{name}") @Path("/name/{name}")
@Operation( @Operation(

View File

@ -49,6 +49,7 @@ import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.openmetadata.schema.api.CreateBot; import org.openmetadata.schema.api.CreateBot;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.entity.Bot; import org.openmetadata.schema.entity.Bot;
import org.openmetadata.schema.entity.teams.User; import org.openmetadata.schema.entity.teams.User;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
@ -350,6 +351,25 @@ public class BotResource extends EntityResource<Bot, BotRepository> {
return delete(uriInfo, securityContext, id, true, hardDelete); return delete(uriInfo, securityContext, id, true, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted bot.",
tags = "bots",
description = "Restore a soft deleted bot.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Bot ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Bot.class)))
})
public Response restoreBot(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private Bot getBot(CreateBot create, String user) throws IOException { private Bot getBot(CreateBot create, String user) throws IOException {
return copy(new Bot(), create, user) return copy(new Bot(), create, user)
.withBotUser(create.getBotUser()) .withBotUser(create.getBotUser())

View File

@ -45,6 +45,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.CreateChart; import org.openmetadata.schema.api.data.CreateChart;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.entity.data.Chart; import org.openmetadata.schema.entity.data.Chart;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.Include;
@ -380,6 +381,25 @@ public class ChartResource extends EntityResource<Chart, ChartRepository> {
return delete(uriInfo, securityContext, id, false, hardDelete); return delete(uriInfo, securityContext, id, false, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted chart.",
tags = "charts",
description = "Restore a soft deleted chart.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Chart ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Chart.class)))
})
public Response restoreChart(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private Chart getChart(CreateChart create, String user) throws IOException { private Chart getChart(CreateChart create, String user) throws IOException {
return copy(new Chart(), create, user) return copy(new Chart(), create, user)
.withService(create.getService()) .withService(create.getService())

View File

@ -45,6 +45,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.CreateDashboard; import org.openmetadata.schema.api.data.CreateDashboard;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.entity.data.Dashboard; import org.openmetadata.schema.entity.data.Dashboard;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.Include;
@ -382,6 +383,25 @@ public class DashboardResource extends EntityResource<Dashboard, DashboardReposi
return delete(uriInfo, securityContext, id, false, hardDelete); return delete(uriInfo, securityContext, id, false, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted dashboard.",
tags = "dashboards",
description = "Restore a soft deleted dashboard.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Dashboard.",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Dashboard.class)))
})
public Response restoreDashboard(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private Dashboard getDashboard(CreateDashboard create, String user) throws IOException { private Dashboard getDashboard(CreateDashboard create, String user) throws IOException {
return copy(new Dashboard(), create, user) return copy(new Dashboard(), create, user)
.withService(create.getService()) .withService(create.getService())

View File

@ -46,6 +46,7 @@ import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.dataInsight.CreateDataInsightChart; import org.openmetadata.schema.api.dataInsight.CreateDataInsightChart;
import org.openmetadata.schema.dataInsight.DataInsightChart; import org.openmetadata.schema.dataInsight.DataInsightChart;
import org.openmetadata.schema.dataInsight.DataInsightChartResult; import org.openmetadata.schema.dataInsight.DataInsightChartResult;
@ -383,6 +384,26 @@ public class DataInsightChartResource extends EntityResource<DataInsightChart, D
return delete(uriInfo, securityContext, id, false, hardDelete); return delete(uriInfo, securityContext, id, false, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted DataInsightChart.",
tags = "dataInsight",
description = "Restore a soft deleted DataInsightChart.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the DataInsightChart. ",
content =
@Content(mediaType = "application/json", schema = @Schema(implementation = DataInsightChart.class)))
})
public Response restoreDataInsightChart(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
@GET @GET
@Path("/aggregate") @Path("/aggregate")
@Operation( @Operation(

View File

@ -45,6 +45,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.CreateDatabase; import org.openmetadata.schema.api.data.CreateDatabase;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.entity.data.Database; import org.openmetadata.schema.entity.data.Database;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.Include;
@ -362,6 +363,25 @@ public class DatabaseResource extends EntityResource<Database, DatabaseRepositor
return delete(uriInfo, securityContext, id, recursive, hardDelete); return delete(uriInfo, securityContext, id, recursive, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted Database.",
tags = "tables",
description = "Restore a soft deleted Database.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Database. ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Database.class)))
})
public Response restoreDatabase(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private Database getDatabase(CreateDatabase create, String user) throws IOException { private Database getDatabase(CreateDatabase create, String user) throws IOException {
return copy(new Database(), create, user).withService(create.getService()); return copy(new Database(), create, user).withService(create.getService());
} }

View File

@ -45,6 +45,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.CreateDatabaseSchema; import org.openmetadata.schema.api.data.CreateDatabaseSchema;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.entity.data.DatabaseSchema; import org.openmetadata.schema.entity.data.DatabaseSchema;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.Include;
@ -349,6 +350,25 @@ public class DatabaseSchemaResource extends EntityResource<DatabaseSchema, Datab
return delete(uriInfo, securityContext, id, recursive, hardDelete); return delete(uriInfo, securityContext, id, recursive, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted DatabaseSchema.",
tags = "tables",
description = "Restore a soft deleted DatabaseSchema.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the DatabaseSchema ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = DatabaseSchema.class)))
})
public Response restoreDatabaseSchema(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private DatabaseSchema getDatabaseSchema(CreateDatabaseSchema create, String user) throws IOException { private DatabaseSchema getDatabaseSchema(CreateDatabaseSchema create, String user) throws IOException {
return copy(new DatabaseSchema(), create, user).withDatabase(create.getDatabase()); return copy(new DatabaseSchema(), create, user).withDatabase(create.getDatabase());
} }

View File

@ -49,6 +49,7 @@ import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.CreateTable; import org.openmetadata.schema.api.data.CreateTable;
import org.openmetadata.schema.api.data.CreateTableProfile; import org.openmetadata.schema.api.data.CreateTableProfile;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.tests.CreateCustomMetric; import org.openmetadata.schema.api.tests.CreateCustomMetric;
import org.openmetadata.schema.entity.data.Table; import org.openmetadata.schema.entity.data.Table;
import org.openmetadata.schema.tests.CustomMetric; import org.openmetadata.schema.tests.CustomMetric;
@ -425,6 +426,25 @@ public class TableResource extends EntityResource<Table, TableRepository> {
return deleteByName(uriInfo, securityContext, fqn, false, hardDelete); return deleteByName(uriInfo, securityContext, fqn, false, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted table.",
tags = "tables",
description = "Restore a soft deleted table.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Table ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Table.class)))
})
public Response restoreTable(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
@PUT @PUT
@Path("/{id}/followers") @Path("/{id}/followers")
@Operation( @Operation(

View File

@ -37,6 +37,7 @@ import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import lombok.NonNull; import lombok.NonNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.tests.CreateTestCase; import org.openmetadata.schema.api.tests.CreateTestCase;
import org.openmetadata.schema.tests.TestCase; import org.openmetadata.schema.tests.TestCase;
import org.openmetadata.schema.tests.type.TestCaseResult; import org.openmetadata.schema.tests.type.TestCaseResult;
@ -425,6 +426,25 @@ public class TestCaseResource extends EntityResource<TestCase, TestCaseRepositor
return response.toResponse(); return response.toResponse();
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted TestCase.",
tags = "TestCases",
description = "Restore a soft deleted TestCase.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Chart ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = TestCase.class)))
})
public Response restoreTestCase(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
@PUT @PUT
@Path("/{fqn}/testCaseResult") @Path("/{fqn}/testCaseResult")
@Operation( @Operation(

View File

@ -34,6 +34,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.tests.CreateTestDefinition; import org.openmetadata.schema.api.tests.CreateTestDefinition;
import org.openmetadata.schema.tests.TestDefinition; import org.openmetadata.schema.tests.TestDefinition;
import org.openmetadata.schema.tests.TestPlatform; import org.openmetadata.schema.tests.TestPlatform;
@ -368,6 +369,25 @@ public class TestDefinitionResource extends EntityResource<TestDefinition, TestD
return delete(uriInfo, securityContext, id, false, hardDelete); return delete(uriInfo, securityContext, id, false, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted TestDefinition.",
tags = "TestDefinitions",
description = "Restore a soft deleted TestDefinition.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the TestDefinition. ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = TestDefinition.class)))
})
public Response restoreTestDefinition(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private TestDefinition getTestDefinition(CreateTestDefinition create, String user) throws IOException { private TestDefinition getTestDefinition(CreateTestDefinition create, String user) throws IOException {
return copy(new TestDefinition(), create, user) return copy(new TestDefinition(), create, user)
.withDescription(create.getDescription()) .withDescription(create.getDescription())

View File

@ -33,6 +33,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.tests.CreateTestSuite; import org.openmetadata.schema.api.tests.CreateTestSuite;
import org.openmetadata.schema.tests.TestSuite; import org.openmetadata.schema.tests.TestSuite;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
@ -333,6 +334,25 @@ public class TestSuiteResource extends EntityResource<TestSuite, TestSuiteReposi
return delete(uriInfo, securityContext, id, recursive, hardDelete); return delete(uriInfo, securityContext, id, recursive, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted TestSuite.",
tags = "TestSuites",
description = "Restore a soft deleted TestSuite.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the TestSuite.",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = TestSuite.class)))
})
public Response restoreTestSuite(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private TestSuite getTestSuite(CreateTestSuite create, String user) throws IOException { private TestSuite getTestSuite(CreateTestSuite create, String user) throws IOException {
return copy(new TestSuite(), create, user) return copy(new TestSuite(), create, user)
.withDescription(create.getDescription()) .withDescription(create.getDescription())

View File

@ -46,6 +46,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.CreateGlossary; import org.openmetadata.schema.api.data.CreateGlossary;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.entity.data.Glossary; import org.openmetadata.schema.entity.data.Glossary;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.Include;
@ -345,6 +346,25 @@ public class GlossaryResource extends EntityResource<Glossary, GlossaryRepositor
return delete(uriInfo, securityContext, id, recursive, hardDelete); return delete(uriInfo, securityContext, id, recursive, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted Glossary.",
tags = "glossaries",
description = "Restore a soft deleted Glossary.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Glossary ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Glossary.class)))
})
public Response restoreGlossary(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private Glossary getGlossary(CreateGlossary create, String user) throws IOException { private Glossary getGlossary(CreateGlossary create, String user) throws IOException {
return copy(new Glossary(), create, user) return copy(new Glossary(), create, user)
.withReviewers(create.getReviewers()) .withReviewers(create.getReviewers())

View File

@ -46,6 +46,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.CreateGlossaryTerm; import org.openmetadata.schema.api.data.CreateGlossaryTerm;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.entity.data.Glossary; import org.openmetadata.schema.entity.data.Glossary;
import org.openmetadata.schema.entity.data.GlossaryTerm; import org.openmetadata.schema.entity.data.GlossaryTerm;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
@ -394,6 +395,25 @@ public class GlossaryTermResource extends EntityResource<GlossaryTerm, GlossaryT
return delete(uriInfo, securityContext, id, recursive, hardDelete); return delete(uriInfo, securityContext, id, recursive, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted GlossaryTerm.",
tags = "glossaryTerm",
description = "Restore a soft deleted GlossaryTerm.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Chart ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = GlossaryTerm.class)))
})
public Response restoreTable(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private GlossaryTerm getGlossaryTerm(CreateGlossaryTerm create, String user) throws IOException { private GlossaryTerm getGlossaryTerm(CreateGlossaryTerm create, String user) throws IOException {
return copy(new GlossaryTerm(), create, user) return copy(new GlossaryTerm(), create, user)
.withSynonyms(create.getSynonyms()) .withSynonyms(create.getSynonyms())

View File

@ -35,6 +35,7 @@ import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import lombok.NonNull; import lombok.NonNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.dataInsight.kpi.CreateKpiRequest; import org.openmetadata.schema.api.dataInsight.kpi.CreateKpiRequest;
import org.openmetadata.schema.dataInsight.kpi.Kpi; import org.openmetadata.schema.dataInsight.kpi.Kpi;
import org.openmetadata.schema.dataInsight.type.KpiResult; import org.openmetadata.schema.dataInsight.type.KpiResult;
@ -341,6 +342,25 @@ public class KpiResource extends EntityResource<Kpi, KpiRepository> {
return delete(uriInfo, securityContext, id, recursive, hardDelete); return delete(uriInfo, securityContext, id, recursive, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted Kpi.",
tags = "kpi",
description = "Restore a soft deleted Kpi.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Kpi. ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Kpi.class)))
})
public Response restoreKpi(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
@PUT @PUT
@Path("/{fqn}/kpiResult") @Path("/{fqn}/kpiResult")
@Operation( @Operation(

View File

@ -46,6 +46,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.CreateLocation; import org.openmetadata.schema.api.data.CreateLocation;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.entity.data.Location; import org.openmetadata.schema.entity.data.Location;
import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.ChangeEvent;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
@ -425,6 +426,25 @@ public class LocationResource extends EntityResource<Location, LocationRepositor
return delete(uriInfo, securityContext, id, false, hardDelete); return delete(uriInfo, securityContext, id, false, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted location.",
tags = "locations",
description = "Restore a soft deleted location.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Location ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Location.class)))
})
public Response restoreLocation(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
@PUT @PUT
@Path("/{id}/followers") @Path("/{id}/followers")
@Operation( @Operation(

View File

@ -45,6 +45,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.CreateMlModel; import org.openmetadata.schema.api.data.CreateMlModel;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.entity.data.MlModel; import org.openmetadata.schema.entity.data.MlModel;
import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.ChangeEvent;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
@ -396,6 +397,25 @@ public class MlModelResource extends EntityResource<MlModel, MlModelRepository>
return delete(uriInfo, securityContext, id, false, hardDelete); return delete(uriInfo, securityContext, id, false, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted MlModel.",
tags = "mlModels",
description = "Restore a soft deleted MlModel.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the MlModel ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = MlModel.class)))
})
public Response restoreMlModel(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private MlModel getMlModel(CreateMlModel create, String user) throws IOException { private MlModel getMlModel(CreateMlModel create, String user) throws IOException {
return copy(new MlModel(), create, user) return copy(new MlModel(), create, user)
.withService(create.getService()) .withService(create.getService())

View File

@ -46,6 +46,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.CreatePipeline; import org.openmetadata.schema.api.data.CreatePipeline;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.entity.data.Pipeline; import org.openmetadata.schema.entity.data.Pipeline;
import org.openmetadata.schema.entity.data.PipelineStatus; import org.openmetadata.schema.entity.data.PipelineStatus;
import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.ChangeEvent;
@ -497,6 +498,25 @@ public class PipelineResource extends EntityResource<Pipeline, PipelineRepositor
return delete(uriInfo, securityContext, id, false, hardDelete); return delete(uriInfo, securityContext, id, false, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted Pipeline.",
tags = "pipelines",
description = "Restore a soft deleted Pipeline.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Pipeline ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Pipeline.class)))
})
public Response restorePipeline(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private Pipeline getPipeline(CreatePipeline create, String user) throws IOException { private Pipeline getPipeline(CreatePipeline create, String user) throws IOException {
return copy(new Pipeline(), create, user) return copy(new Pipeline(), create, user)
.withService(create.getService()) .withService(create.getService())

View File

@ -49,6 +49,7 @@ import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.openmetadata.common.utils.CommonUtil; import org.openmetadata.common.utils.CommonUtil;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.policies.CreatePolicy; import org.openmetadata.schema.api.policies.CreatePolicy;
import org.openmetadata.schema.entity.policies.Policy; import org.openmetadata.schema.entity.policies.Policy;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
@ -419,6 +420,25 @@ public class PolicyResource extends EntityResource<Policy, PolicyRepository> {
return response; return response;
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted policy.",
tags = "policies",
description = "Restore a soft deleted policy.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Policy ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Policy.class)))
})
public Response restorePolicy(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
@GET @GET
@Path("/validation/condition/{expression}") @Path("/validation/condition/{expression}")
@Operation( @Operation(

View File

@ -43,6 +43,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.services.CreateDashboardService; import org.openmetadata.schema.api.services.CreateDashboardService;
import org.openmetadata.schema.entity.services.DashboardService; import org.openmetadata.schema.entity.services.DashboardService;
import org.openmetadata.schema.entity.services.ServiceType; import org.openmetadata.schema.entity.services.ServiceType;
@ -344,6 +345,26 @@ public class DashboardServiceResource
return delete(uriInfo, securityContext, id, recursive, hardDelete); return delete(uriInfo, securityContext, id, recursive, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted DashboardService.",
tags = "dashboardServices",
description = "Restore a soft deleted DashboardService.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Chart ",
content =
@Content(mediaType = "application/json", schema = @Schema(implementation = DashboardService.class)))
})
public Response restoreDashboardService(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private DashboardService getService(CreateDashboardService create, String user) throws IOException { private DashboardService getService(CreateDashboardService create, String user) throws IOException {
return copy(new DashboardService(), create, user) return copy(new DashboardService(), create, user)
.withServiceType(create.getServiceType()) .withServiceType(create.getServiceType())

View File

@ -42,6 +42,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.services.CreateDatabaseService; import org.openmetadata.schema.api.services.CreateDatabaseService;
import org.openmetadata.schema.api.services.DatabaseConnection; import org.openmetadata.schema.api.services.DatabaseConnection;
import org.openmetadata.schema.entity.services.DatabaseService; import org.openmetadata.schema.entity.services.DatabaseService;
@ -92,7 +93,7 @@ public class DatabaseServiceResource
@Operation( @Operation(
operationId = "listDatabaseServices", operationId = "listDatabaseServices",
summary = "List database services", summary = "List database services",
tags = "databaseService", tags = "databaseServices",
description = "Get a list of database services.", description = "Get a list of database services.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -143,7 +144,7 @@ public class DatabaseServiceResource
@Operation( @Operation(
operationId = "getDatabaseServiceByID", operationId = "getDatabaseServiceByID",
summary = "Get a database service", summary = "Get a database service",
tags = "databaseService", tags = "databaseServices",
description = "Get a database service by `id`.", description = "Get a database service by `id`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -178,7 +179,7 @@ public class DatabaseServiceResource
@Operation( @Operation(
operationId = "getDatabaseServiceByFQN", operationId = "getDatabaseServiceByFQN",
summary = "Get database service by name", summary = "Get database service by name",
tags = "databaseService", tags = "databaseServices",
description = "Get a database service by the service `name`.", description = "Get a database service by the service `name`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -213,7 +214,7 @@ public class DatabaseServiceResource
@Operation( @Operation(
operationId = "listAllDatabaseServiceVersion", operationId = "listAllDatabaseServiceVersion",
summary = "List database service versions", summary = "List database service versions",
tags = "databaseService", tags = "databaseServices",
description = "Get a list of all the versions of a database service identified by `id`", description = "Get a list of all the versions of a database service identified by `id`",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -249,7 +250,7 @@ public class DatabaseServiceResource
@Operation( @Operation(
operationId = "getSpecificDatabaseServiceVersion", operationId = "getSpecificDatabaseServiceVersion",
summary = "Get a version of the database service", summary = "Get a version of the database service",
tags = "databaseService", tags = "databaseServices",
description = "Get a version of the database service by given `id`", description = "Get a version of the database service by given `id`",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -279,7 +280,7 @@ public class DatabaseServiceResource
@Operation( @Operation(
operationId = "createDatabaseService", operationId = "createDatabaseService",
summary = "Create database service", summary = "Create database service",
tags = "databaseService", tags = "databaseServices",
description = "Create a new database service.", description = "Create a new database service.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -302,7 +303,7 @@ public class DatabaseServiceResource
@Operation( @Operation(
operationId = "createOrUpdateDatabaseService", operationId = "createOrUpdateDatabaseService",
summary = "Update database service", summary = "Update database service",
tags = "databaseService", tags = "databaseServices",
description = "Update an existing or create a new database service.", description = "Update an existing or create a new database service.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -326,7 +327,7 @@ public class DatabaseServiceResource
@Operation( @Operation(
operationId = "deleteDatabaseService", operationId = "deleteDatabaseService",
summary = "Delete a database service", summary = "Delete a database service",
tags = "databaseService", tags = "databaseServices",
description = description =
"Delete a database services. If databases (and tables) belong the service, it can't be " + "deleted.", "Delete a database services. If databases (and tables) belong the service, it can't be " + "deleted.",
responses = { responses = {
@ -350,6 +351,26 @@ public class DatabaseServiceResource
return delete(uriInfo, securityContext, id, recursive, hardDelete); return delete(uriInfo, securityContext, id, recursive, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted DatabaseService.",
tags = "databaseServices",
description = "Restore a soft deleted DatabaseService.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the DatabaseService.",
content =
@Content(mediaType = "application/json", schema = @Schema(implementation = DatabaseService.class)))
})
public Response restoreDatabaseService(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private DatabaseService getService(CreateDatabaseService create, String user) throws IOException { private DatabaseService getService(CreateDatabaseService create, String user) throws IOException {
return copy(new DatabaseService(), create, user) return copy(new DatabaseService(), create, user)
.withServiceType(create.getServiceType()) .withServiceType(create.getServiceType())

View File

@ -52,6 +52,7 @@ import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import lombok.NonNull; import lombok.NonNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.services.ingestionPipelines.CreateIngestionPipeline; import org.openmetadata.schema.api.services.ingestionPipelines.CreateIngestionPipeline;
import org.openmetadata.schema.api.services.ingestionPipelines.TestServiceConnection; import org.openmetadata.schema.api.services.ingestionPipelines.TestServiceConnection;
import org.openmetadata.schema.entity.services.ingestionPipelines.IngestionPipeline; import org.openmetadata.schema.entity.services.ingestionPipelines.IngestionPipeline;
@ -120,7 +121,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "listIngestionPipelines", operationId = "listIngestionPipelines",
summary = "List Ingestion Pipelines for Metadata Operations", summary = "List Ingestion Pipelines for Metadata Operations",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = description =
"Get a list of Airflow Pipelines for Metadata Operations. Use `fields` parameter to get only necessary fields. " "Get a list of Airflow Pipelines for Metadata Operations. Use `fields` parameter to get only necessary fields. "
+ " Use cursor-based pagination to limit the number " + " Use cursor-based pagination to limit the number "
@ -182,7 +183,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "listAllIngestionPipelineVersion", operationId = "listAllIngestionPipelineVersion",
summary = "List ingestion workflow versions", summary = "List ingestion workflow versions",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Get a list of all the versions of a IngestionPipeline identified by `id`", description = "Get a list of all the versions of a IngestionPipeline identified by `id`",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -203,7 +204,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "getIngestionPipelineByID", operationId = "getIngestionPipelineByID",
summary = "Get a IngestionPipeline", summary = "Get a IngestionPipeline",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Get a IngestionPipeline by `id`.", description = "Get a IngestionPipeline by `id`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -241,7 +242,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "getSpecificIngestionPipelineVersion", operationId = "getSpecificIngestionPipelineVersion",
summary = "Get a version of the IngestionPipeline", summary = "Get a version of the IngestionPipeline",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Get a version of the IngestionPipeline by given `id`", description = "Get a version of the IngestionPipeline by given `id`",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -271,7 +272,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "getSpecificIngestionPipelineByFQN", operationId = "getSpecificIngestionPipelineByFQN",
summary = "Get a IngestionPipeline by name", summary = "Get a IngestionPipeline by name",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Get a ingestion by fully qualified name.", description = "Get a ingestion by fully qualified name.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -308,7 +309,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "createIngestionPipeline", operationId = "createIngestionPipeline",
summary = "Create a Ingestion Pipeline", summary = "Create a Ingestion Pipeline",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Create a new Ingestion Pipeline.", description = "Create a new Ingestion Pipeline.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -332,7 +333,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "patchIngestionPipeline", operationId = "patchIngestionPipeline",
summary = "Update a IngestionPipeline", summary = "Update a IngestionPipeline",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Update an existing IngestionPipeline using JsonPatch.", description = "Update an existing IngestionPipeline using JsonPatch.",
externalDocs = @ExternalDocumentation(description = "JsonPatch RFC", url = "https://tools.ietf.org/html/rfc6902")) externalDocs = @ExternalDocumentation(description = "JsonPatch RFC", url = "https://tools.ietf.org/html/rfc6902"))
@Consumes(MediaType.APPLICATION_JSON_PATCH_JSON) @Consumes(MediaType.APPLICATION_JSON_PATCH_JSON)
@ -359,7 +360,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "createOrUpdateIngestionPipeline", operationId = "createOrUpdateIngestionPipeline",
summary = "Create or update a IngestionPipeline", summary = "Create or update a IngestionPipeline",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Create a new IngestionPipeline, if it does not exist or update an existing IngestionPipeline.", description = "Create a new IngestionPipeline, if it does not exist or update an existing IngestionPipeline.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -382,7 +383,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Path("/deploy/{id}") @Path("/deploy/{id}")
@Operation( @Operation(
summary = "Deploy a ingestion pipeline run", summary = "Deploy a ingestion pipeline run",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Trigger a ingestion pipeline run by id.", description = "Trigger a ingestion pipeline run by id.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -409,7 +410,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "triggerIngestionPipelineRun", operationId = "triggerIngestionPipelineRun",
summary = "Trigger a ingestion pipeline run", summary = "Trigger a ingestion pipeline run",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Trigger a ingestion pipeline run by id.", description = "Trigger a ingestion pipeline run by id.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -433,7 +434,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "toggleIngestionPipelineEnabled", operationId = "toggleIngestionPipelineEnabled",
summary = "Set an Ingestion pipeline either as Enabled or Disabled", summary = "Set an Ingestion pipeline either as Enabled or Disabled",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Toggle an ingestion pipeline state by id.", description = "Toggle an ingestion pipeline state by id.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -457,7 +458,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "killIngestionPipelineRuns", operationId = "killIngestionPipelineRuns",
summary = "Mark as failed and kill any not-finished workflow or task for the IngestionPipeline", summary = "Mark as failed and kill any not-finished workflow or task for the IngestionPipeline",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Kill an ingestion pipeline by ID.", description = "Kill an ingestion pipeline by ID.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -480,7 +481,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "testConnection", operationId = "testConnection",
summary = "Test Connection of a Service", summary = "Test Connection of a Service",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Test Connection of a Service.", description = "Test Connection of a Service.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -504,7 +505,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "checkAirflowHostIp", operationId = "checkAirflowHostIp",
summary = "Check the Airflow REST host IP", summary = "Check the Airflow REST host IP",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Check the Airflow REST host IP", description = "Check the Airflow REST host IP",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -522,7 +523,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "checkRestAirflowStatus", operationId = "checkRestAirflowStatus",
summary = "Check the Airflow REST status", summary = "Check the Airflow REST status",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Check that the Airflow REST endpoint is reachable and up and running", description = "Check that the Airflow REST endpoint is reachable and up and running",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -539,7 +540,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
@Operation( @Operation(
operationId = "deleteIngestionPipeline", operationId = "deleteIngestionPipeline",
summary = "Delete a Ingestion", summary = "Delete a Ingestion",
tags = "IngestionPipelines", tags = "ingestionPipelines",
description = "Delete a ingestion by `id`.", description = "Delete a ingestion by `id`.",
responses = { responses = {
@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "200", description = "OK"),
@ -557,6 +558,26 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
return delete(uriInfo, securityContext, id, false, hardDelete); return delete(uriInfo, securityContext, id, false, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted IngestionPipeline.",
tags = "ingestionPipelines",
description = "Restore a soft deleted IngestionPipeline.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the IngestionPipeline. ",
content =
@Content(mediaType = "application/json", schema = @Schema(implementation = IngestionPipeline.class)))
})
public Response restoreIngestionPipeline(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
@GET @GET
@Path("/logs/{id}/last") @Path("/logs/{id}/last")
@Operation( @Operation(

View File

@ -43,6 +43,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.services.CreateMessagingService; import org.openmetadata.schema.api.services.CreateMessagingService;
import org.openmetadata.schema.entity.services.MessagingService; import org.openmetadata.schema.entity.services.MessagingService;
import org.openmetadata.schema.entity.services.ServiceType; import org.openmetadata.schema.entity.services.ServiceType;
@ -91,7 +92,7 @@ public class MessagingServiceResource
@Operation( @Operation(
operationId = "listMessagingService", operationId = "listMessagingService",
summary = "List messaging services", summary = "List messaging services",
tags = "MessagingService", tags = "messagingServices",
description = description =
"Get a list of messaging services. Use cursor-based pagination to limit the number " "Get a list of messaging services. Use cursor-based pagination to limit the number "
+ "entries in the list using `limit` and `before` or `after` query params.", + "entries in the list using `limit` and `before` or `after` query params.",
@ -140,7 +141,7 @@ public class MessagingServiceResource
@Operation( @Operation(
operationId = "getMessagingServiceByID", operationId = "getMessagingServiceByID",
summary = "Get a messaging service", summary = "Get a messaging service",
tags = "MessagingService", tags = "messagingServices",
description = "Get a messaging service by `id`.", description = "Get a messaging service by `id`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -175,7 +176,7 @@ public class MessagingServiceResource
@Operation( @Operation(
operationId = "getMessagingServiceByFQN", operationId = "getMessagingServiceByFQN",
summary = "Get messaging service by name", summary = "Get messaging service by name",
tags = "MessagingService", tags = "messagingServices",
description = "Get a messaging service by the service `name`.", description = "Get a messaging service by the service `name`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -210,7 +211,7 @@ public class MessagingServiceResource
@Operation( @Operation(
operationId = "listAllMessagingServiceVersion", operationId = "listAllMessagingServiceVersion",
summary = "List messaging service versions", summary = "List messaging service versions",
tags = "MessagingService", tags = "messagingServices",
description = "Get a list of all the versions of a messaging service identified by `id`", description = "Get a list of all the versions of a messaging service identified by `id`",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -246,7 +247,7 @@ public class MessagingServiceResource
@Operation( @Operation(
operationId = "getSpecificMessagingServiceVersion", operationId = "getSpecificMessagingServiceVersion",
summary = "Get a version of the messaging service", summary = "Get a version of the messaging service",
tags = "MessagingService", tags = "messagingServices",
description = "Get a version of the messaging service by given `id`", description = "Get a version of the messaging service by given `id`",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -276,7 +277,7 @@ public class MessagingServiceResource
@Operation( @Operation(
operationId = "createMessagingService", operationId = "createMessagingService",
summary = "Create a messaging service", summary = "Create a messaging service",
tags = "MessagingService", tags = "messagingService",
description = "Create a new messaging service.", description = "Create a new messaging service.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -299,7 +300,7 @@ public class MessagingServiceResource
@Operation( @Operation(
operationId = "createOrUpdateMessagingService", operationId = "createOrUpdateMessagingService",
summary = "Update messaging service", summary = "Update messaging service",
tags = "MessagingService", tags = "messagingServices",
description = "Create a new messaging service or Update an existing messaging service identified by `id`.", description = "Create a new messaging service or Update an existing messaging service identified by `id`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -323,7 +324,7 @@ public class MessagingServiceResource
@Operation( @Operation(
operationId = "deleteMessagingService", operationId = "deleteMessagingService",
summary = "Delete a messaging service", summary = "Delete a messaging service",
tags = "MessagingService", tags = "messagingServices",
description = "Delete a messaging service. If topics belong the service, it can't be " + "deleted.", description = "Delete a messaging service. If topics belong the service, it can't be " + "deleted.",
responses = { responses = {
@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "200", description = "OK"),
@ -345,6 +346,26 @@ public class MessagingServiceResource
return delete(uriInfo, securityContext, id, recursive, hardDelete); return delete(uriInfo, securityContext, id, recursive, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted MessagingService.",
tags = "messagingServices",
description = "Restore a soft deleted MessagingService.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the MessagingService ",
content =
@Content(mediaType = "application/json", schema = @Schema(implementation = MessagingService.class)))
})
public Response restoreMessagingService(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private MessagingService getService(CreateMessagingService create, String user) throws IOException { private MessagingService getService(CreateMessagingService create, String user) throws IOException {
return copy(new MessagingService(), create, user) return copy(new MessagingService(), create, user)
.withConnection(create.getConnection()) .withConnection(create.getConnection())

View File

@ -41,6 +41,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.services.CreateMlModelService; import org.openmetadata.schema.api.services.CreateMlModelService;
import org.openmetadata.schema.entity.services.MlModelService; import org.openmetadata.schema.entity.services.MlModelService;
import org.openmetadata.schema.entity.services.ServiceType; import org.openmetadata.schema.entity.services.ServiceType;
@ -90,7 +91,7 @@ public class MlModelServiceResource
@Operation( @Operation(
operationId = "listMlModelService", operationId = "listMlModelService",
summary = "List mlModel services", summary = "List mlModel services",
tags = "mlModelService", tags = "mlModelServices",
description = description =
"Get a list of mlModel services. Use cursor-based pagination to limit the number " "Get a list of mlModel services. Use cursor-based pagination to limit the number "
+ "entries in the list using `limit` and `before` or `after` query params.", + "entries in the list using `limit` and `before` or `after` query params.",
@ -139,7 +140,7 @@ public class MlModelServiceResource
@Operation( @Operation(
operationId = "getMlModelServiceByID", operationId = "getMlModelServiceByID",
summary = "Get a mlModel service", summary = "Get a mlModel service",
tags = "mlModelService", tags = "mlModelServices",
description = "Get a mlModel service by `id`.", description = "Get a mlModel service by `id`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -174,7 +175,7 @@ public class MlModelServiceResource
@Operation( @Operation(
operationId = "getMlModelServiceByFQN", operationId = "getMlModelServiceByFQN",
summary = "Get mlModel service by name", summary = "Get mlModel service by name",
tags = "mlModelService", tags = "mlModelServices",
description = "Get a mlModel service by the service `name`.", description = "Get a mlModel service by the service `name`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -209,7 +210,7 @@ public class MlModelServiceResource
@Operation( @Operation(
operationId = "listAllMlModelServiceVersion", operationId = "listAllMlModelServiceVersion",
summary = "List mlModel service versions", summary = "List mlModel service versions",
tags = "mlModelService", tags = "mlModelServices",
description = "Get a list of all the versions of a mlModel service identified by `id`", description = "Get a list of all the versions of a mlModel service identified by `id`",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -245,7 +246,7 @@ public class MlModelServiceResource
@Operation( @Operation(
operationId = "getSpecificMlModelService", operationId = "getSpecificMlModelService",
summary = "Get a version of the mlModel service", summary = "Get a version of the mlModel service",
tags = "mlModelService", tags = "mlModelServices",
description = "Get a version of the mlModel service by given `id`", description = "Get a version of the mlModel service by given `id`",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -298,7 +299,7 @@ public class MlModelServiceResource
@Operation( @Operation(
operationId = "createOrUpdateMlModelService", operationId = "createOrUpdateMlModelService",
summary = "Update mlModel service", summary = "Update mlModel service",
tags = "mlModelService", tags = "mlModelServices",
description = "Create a new mlModel service or update an existing mlModel service identified by `id`.", description = "Create a new mlModel service or update an existing mlModel service identified by `id`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -322,7 +323,7 @@ public class MlModelServiceResource
@Operation( @Operation(
operationId = "deleteMlModelService", operationId = "deleteMlModelService",
summary = "Delete a mlModel service", summary = "Delete a mlModel service",
tags = "mlModelService", tags = "mlModelServices",
description = description =
"Delete a mlModel services. If mlModels (and tasks) belong to the service, it can't be " + "deleted.", "Delete a mlModel services. If mlModels (and tasks) belong to the service, it can't be " + "deleted.",
responses = { responses = {
@ -345,6 +346,25 @@ public class MlModelServiceResource
return delete(uriInfo, securityContext, id, recursive, hardDelete); return delete(uriInfo, securityContext, id, recursive, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted MlModelService.",
tags = "mlModelServices",
description = "Restore a soft deleted MlModelService.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the MlModelService ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = MlModelService.class)))
})
public Response restoreTable(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private MlModelService getService(CreateMlModelService create, String user) throws IOException { private MlModelService getService(CreateMlModelService create, String user) throws IOException {
return copy(new MlModelService(), create, user) return copy(new MlModelService(), create, user)
.withServiceType(create.getServiceType()) .withServiceType(create.getServiceType())

View File

@ -41,6 +41,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.services.CreatePipelineService; import org.openmetadata.schema.api.services.CreatePipelineService;
import org.openmetadata.schema.entity.services.PipelineService; import org.openmetadata.schema.entity.services.PipelineService;
import org.openmetadata.schema.entity.services.ServiceType; import org.openmetadata.schema.entity.services.ServiceType;
@ -89,7 +90,7 @@ public class PipelineServiceResource
@Operation( @Operation(
operationId = "listPipelineService", operationId = "listPipelineService",
summary = "List pipeline services", summary = "List pipeline services",
tags = "pipelineService", tags = "pipelineServices",
description = description =
"Get a list of pipeline services. Use cursor-based pagination to limit the number " "Get a list of pipeline services. Use cursor-based pagination to limit the number "
+ "entries in the list using `limit` and `before` or `after` query params.", + "entries in the list using `limit` and `before` or `after` query params.",
@ -138,7 +139,7 @@ public class PipelineServiceResource
@Operation( @Operation(
operationId = "getPipelineServiceByID", operationId = "getPipelineServiceByID",
summary = "Get a pipeline service", summary = "Get a pipeline service",
tags = "pipelineService", tags = "pipelineServices",
description = "Get a pipeline service by `id`.", description = "Get a pipeline service by `id`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -173,7 +174,7 @@ public class PipelineServiceResource
@Operation( @Operation(
operationId = "getPipelineServiceByFQN", operationId = "getPipelineServiceByFQN",
summary = "Get pipeline service by name", summary = "Get pipeline service by name",
tags = "pipelineService", tags = "pipelineServices",
description = "Get a pipeline service by the service `name`.", description = "Get a pipeline service by the service `name`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -208,7 +209,7 @@ public class PipelineServiceResource
@Operation( @Operation(
operationId = "listAllPipelineServiceVersion", operationId = "listAllPipelineServiceVersion",
summary = "List pipeline service versions", summary = "List pipeline service versions",
tags = "pipelineService", tags = "pipelineServices",
description = "Get a list of all the versions of a pipeline service identified by `id`", description = "Get a list of all the versions of a pipeline service identified by `id`",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -244,7 +245,7 @@ public class PipelineServiceResource
@Operation( @Operation(
operationId = "getSpecificPipelineService", operationId = "getSpecificPipelineService",
summary = "Get a version of the pipeline service", summary = "Get a version of the pipeline service",
tags = "pipelineService", tags = "pipelineServices",
description = "Get a version of the pipeline service by given `id`", description = "Get a version of the pipeline service by given `id`",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -274,7 +275,7 @@ public class PipelineServiceResource
@Operation( @Operation(
operationId = "createPipelineService", operationId = "createPipelineService",
summary = "Create a pipeline service", summary = "Create a pipeline service",
tags = "pipelineService", tags = "pipelineServices",
description = "Create a new pipeline service.", description = "Create a new pipeline service.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -297,7 +298,7 @@ public class PipelineServiceResource
@Operation( @Operation(
operationId = "createOrUpdatePipelineService", operationId = "createOrUpdatePipelineService",
summary = "Update pipeline service", summary = "Update pipeline service",
tags = "pipelineService", tags = "pipelineServices",
description = "Create a new pipeline service or update an existing pipeline service identified by `id`.", description = "Create a new pipeline service or update an existing pipeline service identified by `id`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -321,7 +322,7 @@ public class PipelineServiceResource
@Operation( @Operation(
operationId = "deletePipelineService", operationId = "deletePipelineService",
summary = "Delete a pipeline service", summary = "Delete a pipeline service",
tags = "pipelineService", tags = "pipelineServices",
description = description =
"Delete a pipeline services. If pipelines (and tasks) belong to the service, it can't be " + "deleted.", "Delete a pipeline services. If pipelines (and tasks) belong to the service, it can't be " + "deleted.",
responses = { responses = {
@ -345,6 +346,26 @@ public class PipelineServiceResource
return delete(uriInfo, securityContext, id, recursive, hardDelete); return delete(uriInfo, securityContext, id, recursive, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted PipelineService.",
tags = "pipelineServices",
description = "Restore a soft deleted PipelineService.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the PipelineService ",
content =
@Content(mediaType = "application/json", schema = @Schema(implementation = PipelineService.class)))
})
public Response restorePipelineService(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private PipelineService getService(CreatePipelineService create, String user) throws IOException { private PipelineService getService(CreatePipelineService create, String user) throws IOException {
return copy(new PipelineService(), create, user) return copy(new PipelineService(), create, user)
.withServiceType(create.getServiceType()) .withServiceType(create.getServiceType())

View File

@ -41,6 +41,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.services.CreateStorageService; import org.openmetadata.schema.api.services.CreateStorageService;
import org.openmetadata.schema.entity.services.StorageService; import org.openmetadata.schema.entity.services.StorageService;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
@ -85,7 +86,7 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
@Operation( @Operation(
operationId = "listStorageService", operationId = "listStorageService",
summary = "List storage services", summary = "List storage services",
tags = "storageService", tags = "storageServices",
description = description =
"Get a list of storage services. Use cursor-based pagination to limit the number " "Get a list of storage services. Use cursor-based pagination to limit the number "
+ "entries in the list using `limit` and `before` or `after` query params.", + "entries in the list using `limit` and `before` or `after` query params.",
@ -132,7 +133,7 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
@Operation( @Operation(
operationId = "getStorageServiceByID", operationId = "getStorageServiceByID",
summary = "Get a storage service", summary = "Get a storage service",
tags = "storageService", tags = "storageServices",
description = "Get a storage service by `id`.", description = "Get a storage service by `id`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -166,7 +167,7 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
@Operation( @Operation(
operationId = "getStorageServiceByFQN", operationId = "getStorageServiceByFQN",
summary = "Get storage service by name", summary = "Get storage service by name",
tags = "storageService", tags = "storageServices",
description = "Get a storage service by the service `name`.", description = "Get a storage service by the service `name`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -200,7 +201,7 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
@Operation( @Operation(
operationId = "listAllStorageServiceVersion", operationId = "listAllStorageServiceVersion",
summary = "List storage service versions", summary = "List storage service versions",
tags = "storageService", tags = "storageServices",
description = "Get a list of all the versions of a storage service identified by `id`", description = "Get a list of all the versions of a storage service identified by `id`",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -221,7 +222,7 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
@Operation( @Operation(
operationId = "getSpecificStorageServiceVersion", operationId = "getSpecificStorageServiceVersion",
summary = "Get a version of the storage service", summary = "Get a version of the storage service",
tags = "storageService", tags = "storageServices",
description = "Get a version of the storage service by given `id`", description = "Get a version of the storage service by given `id`",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -250,7 +251,7 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
@Operation( @Operation(
operationId = "createStorageService", operationId = "createStorageService",
summary = "Create storage service", summary = "Create storage service",
tags = "storageService", tags = "storageServices",
description = "Create a new storage service.", description = "Create a new storage service.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -271,7 +272,7 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
@Operation( @Operation(
operationId = "createOrUpdateStorageService", operationId = "createOrUpdateStorageService",
summary = "Update storage service", summary = "Update storage service",
tags = "storageService", tags = "storageServices",
description = "Update an existing storage service identified by `id`.", description = "Update an existing storage service identified by `id`.",
responses = { responses = {
@ApiResponse( @ApiResponse(
@ -293,7 +294,7 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
@Operation( @Operation(
operationId = "deleteStorageService", operationId = "deleteStorageService",
summary = "Delete a storage service", summary = "Delete a storage service",
tags = "storageService", tags = "storageServices",
description = "Delete a storage services. If storages (and tables) belong the service, it can't be " + "deleted.", description = "Delete a storage services. If storages (and tables) belong the service, it can't be " + "deleted.",
responses = { responses = {
@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "200", description = "OK"),
@ -315,6 +316,25 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
return delete(uriInfo, securityContext, id, recursive, hardDelete); return delete(uriInfo, securityContext, id, recursive, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted StorageService.",
tags = "storageServices",
description = "Restore a soft deleted StorageService.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the StorageService ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = StorageService.class)))
})
public Response restoreTable(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private StorageService getService(CreateStorageService create, String user) throws IOException { private StorageService getService(CreateStorageService create, String user) throws IOException {
return copy(new StorageService(), create, user).withServiceType(create.getServiceType()); return copy(new StorageService(), create, user).withServiceType(create.getServiceType());
} }

View File

@ -49,6 +49,7 @@ import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.openmetadata.schema.EntityInterface; import org.openmetadata.schema.EntityInterface;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.teams.CreateRole; import org.openmetadata.schema.api.teams.CreateRole;
import org.openmetadata.schema.entity.teams.Role; import org.openmetadata.schema.entity.teams.Role;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
@ -383,6 +384,25 @@ public class RoleResource extends EntityResource<Role, RoleRepository> {
return response; return response;
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted role.",
tags = "roles",
description = "Restore a soft deleted role.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Role. ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Role.class)))
})
public Response restoreRole(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private Role getRole(CreateRole create, String user) throws IOException { private Role getRole(CreateRole create, String user) throws IOException {
if (nullOrEmpty(create.getPolicies())) { if (nullOrEmpty(create.getPolicies())) {
throw new IllegalArgumentException("At least one policy is required to create a role"); throw new IllegalArgumentException("At least one policy is required to create a role");

View File

@ -48,6 +48,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.teams.CreateTeam; import org.openmetadata.schema.api.teams.CreateTeam;
import org.openmetadata.schema.api.teams.CreateTeam.TeamType; import org.openmetadata.schema.api.teams.CreateTeam.TeamType;
import org.openmetadata.schema.entity.teams.Team; import org.openmetadata.schema.entity.teams.Team;
@ -408,6 +409,25 @@ public class TeamResource extends EntityResource<Team, TeamRepository> {
return delete(uriInfo, securityContext, id, recursive, hardDelete); return delete(uriInfo, securityContext, id, recursive, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted Team.",
tags = "teams",
description = "Restore a soft deleted Team.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Team ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Team.class)))
})
public Response restoreTeam(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private Team getTeam(CreateTeam ct, String user) throws IOException { private Team getTeam(CreateTeam ct, String user) throws IOException {
if (ct.getTeamType().equals(TeamType.ORGANIZATION)) { if (ct.getTeamType().equals(TeamType.ORGANIZATION)) {
throw new IllegalArgumentException(CREATE_ORGANIZATION); throw new IllegalArgumentException(CREATE_ORGANIZATION);

View File

@ -67,6 +67,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.openmetadata.schema.EntityInterface; import org.openmetadata.schema.EntityInterface;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.security.AuthenticationConfiguration; import org.openmetadata.schema.api.security.AuthenticationConfiguration;
import org.openmetadata.schema.api.teams.CreateUser; import org.openmetadata.schema.api.teams.CreateUser;
import org.openmetadata.schema.auth.ChangePasswordRequest; import org.openmetadata.schema.auth.ChangePasswordRequest;
@ -743,6 +744,25 @@ public class UserResource extends EntityResource<User, UserRepository> {
return response; return response;
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted User.",
tags = "users",
description = "Restore a soft deleted User.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the User ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = User.class)))
})
public Response restoreTable(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
@POST @POST
@Path("/signup") @Path("/signup")
@Operation( @Operation(

View File

@ -46,6 +46,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.openmetadata.schema.api.data.CreateTopic; import org.openmetadata.schema.api.data.CreateTopic;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.entity.data.Topic; import org.openmetadata.schema.entity.data.Topic;
import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.ChangeEvent;
import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.EntityHistory;
@ -418,6 +419,25 @@ public class TopicResource extends EntityResource<Topic, TopicRepository> {
return delete(uriInfo, securityContext, id, false, hardDelete); return delete(uriInfo, securityContext, id, false, hardDelete);
} }
@PUT
@Path("/restore")
@Operation(
operationId = "restore",
summary = "Restore a soft deleted topic.",
tags = "topics",
description = "Restore a soft deleted topic.",
responses = {
@ApiResponse(
responseCode = "200",
description = "Successfully restored the Topic. ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Topic.class)))
})
public Response restoreTopic(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid RestoreEntity restore)
throws IOException {
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private Topic getTopic(CreateTopic create, String user) throws IOException { private Topic getTopic(CreateTopic create, String user) throws IOException {
return copy(new Topic(), create, user) return copy(new Topic(), create, user)
.withService(create.getService()) .withService(create.getService())

View File

@ -98,6 +98,7 @@ import org.junit.jupiter.api.TestInstance;
import org.openmetadata.common.utils.CommonUtil; import org.openmetadata.common.utils.CommonUtil;
import org.openmetadata.schema.CreateEntity; import org.openmetadata.schema.CreateEntity;
import org.openmetadata.schema.EntityInterface; import org.openmetadata.schema.EntityInterface;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.data.TermReference; import org.openmetadata.schema.api.data.TermReference;
import org.openmetadata.schema.api.teams.CreateTeam; import org.openmetadata.schema.api.teams.CreateTeam;
import org.openmetadata.schema.api.teams.CreateTeam.TeamType; import org.openmetadata.schema.api.teams.CreateTeam.TeamType;
@ -1439,9 +1440,9 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
permissionNotAllowed(TEST_USER_NAME, List.of(MetadataOperation.DELETE))); permissionNotAllowed(TEST_USER_NAME, List.of(MetadataOperation.DELETE)));
} }
/** Soft delete an entity and then use PUT request to restore it back */ /** Soft delete an entity and then use restore request to restore it back */
// @Test @Test
void delete_put_entity_200(TestInfo test) throws IOException { void delete_restore_entity_200(TestInfo test) throws IOException {
K request = createRequest(getEntityName(test), "", "", null); K request = createRequest(getEntityName(test), "", "", null);
T entity = createEntity(request, ADMIN_AUTH_HEADERS); T entity = createEntity(request, ADMIN_AUTH_HEADERS);
@ -1454,7 +1455,7 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
// Send PUT request (with no changes) to restore the entity from soft deleted state // Send PUT request (with no changes) to restore the entity from soft deleted state
ChangeDescription change = getChangeDescription(version); ChangeDescription change = getChangeDescription(version);
fieldUpdated(change, FIELD_DELETED, true, false); fieldUpdated(change, FIELD_DELETED, true, false);
updateAndCheckEntity(request, Response.Status.OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change); restoreAndCheckEntity(entity, Response.Status.OK, ADMIN_AUTH_HEADERS, NO_CHANGE, change);
} else { } else {
assertEntityDeleted(entity, true); assertEntityDeleted(entity, true);
} }
@ -1560,6 +1561,10 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
return getCollection().path("/name/" + name); return getCollection().path("/name/" + name);
} }
protected final WebTarget getRestoreResource(UUID id) {
return getCollection().path("/restore");
}
protected final WebTarget getFollowersCollection(UUID id) { protected final WebTarget getFollowersCollection(UUID id) {
return getResource(collectionName + "/" + id + "/followers"); return getResource(collectionName + "/" + id + "/followers");
} }
@ -1669,6 +1674,12 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
return entity; return entity;
} }
public final T restoreEntity(RestoreEntity restore, Status status, Map<String, String> authHeaders)
throws HttpResponseException {
WebTarget target = getRestoreResource(restore.getId());
return TestUtils.put(target, restore, entityClass, status, authHeaders);
}
/** Helper function to create an entity, submit POST API request and validate response. */ /** Helper function to create an entity, submit POST API request and validate response. */
public final T createAndCheckEntity(K create, Map<String, String> authHeaders) throws IOException { public final T createAndCheckEntity(K create, Map<String, String> authHeaders) throws IOException {
// Validate an entity that is created has all the information set in create request // Validate an entity that is created has all the information set in create request
@ -1723,6 +1734,27 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
return updated; return updated;
} }
protected final T restoreAndCheckEntity(
T entity,
Status status,
Map<String, String> authHeaders,
UpdateType updateType,
ChangeDescription changeDescription)
throws IOException {
T updated = restoreEntity(new RestoreEntity().withId(entity.getId()), status, authHeaders);
validateLatestVersion(updated, updateType, changeDescription, authHeaders);
// GET the newly updated entity and validate
T getEntity = getEntity(updated.getId(), authHeaders);
validateChangeDescription(getEntity, updateType, changeDescription);
// Check if the entity change events are record
if (updateType != NO_CHANGE) {
EventType expectedEventType =
updateType == UpdateType.CREATED ? EventType.ENTITY_CREATED : EventType.ENTITY_UPDATED;
validateChangeEvents(updated, updated.getUpdatedAt(), expectedEventType, changeDescription, authHeaders);
}
return updated;
}
protected void validateEntityHistory( protected void validateEntityHistory(
UUID id, UpdateType updateType, ChangeDescription expectedChangeDescription, Map<String, String> authHeaders) UUID id, UpdateType updateType, ChangeDescription expectedChangeDescription, Map<String, String> authHeaders)
throws IOException { throws IOException {

View File

@ -323,6 +323,12 @@ public final class TestUtils {
return readResponse(response, clz, Status.OK.getStatusCode()); return readResponse(response, clz, Status.OK.getStatusCode());
} }
public static <T> T put(WebTarget target, Class<T> clz, Status expectedStatus, Map<String, String> headers)
throws HttpResponseException {
Response response = SecurityUtil.addHeaders(target, headers).method("PUT");
return readResponse(response, clz, expectedStatus.getStatusCode());
}
public static <K> void put(WebTarget target, K request, Status expectedStatus, Map<String, String> headers) public static <K> void put(WebTarget target, K request, Status expectedStatus, Map<String, String> headers)
throws HttpResponseException { throws HttpResponseException {
Response response = Response response =

View File

@ -0,0 +1,16 @@
{
"$id": "https://open-metadata.org/schema/api/restoreEntity.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "restoreEntity",
"description": "Restore Entity API request to restore soft deleted entity.",
"type": "object",
"javaType": "org.openmetadata.schema.api.data.RestoreEntity",
"properties": {
"id": {
"description": "Unique identifier that identifies an entity instance.",
"$ref": "../../type/basic.json#/definitions/uuid"
}
},
"required": ["id"],
"additionalProperties": false
}