mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-25 08:50:18 +00:00
This commit is contained in:
parent
9138b85913
commit
e6abd86797
@ -87,7 +87,7 @@ public final class Entity {
|
||||
public static final String MLMODEL = "mlmodel";
|
||||
// Not deleted to ensure the ordinal value of the entities after this remains the same
|
||||
public static final String UNUSED = "unused";
|
||||
public static final String BOTS = "bots";
|
||||
public static final String BOT = "bot";
|
||||
public static final String THREAD = "THREAD";
|
||||
public static final String LOCATION = "location";
|
||||
public static final String GLOSSARY = "glossary";
|
||||
@ -122,7 +122,7 @@ public final class Entity {
|
||||
TEAM,
|
||||
ROLE,
|
||||
POLICY,
|
||||
BOTS,
|
||||
BOT,
|
||||
INGESTION_PIPELINE,
|
||||
DATABASE_SERVICE,
|
||||
PIPELINE_SERVICE,
|
||||
@ -247,8 +247,7 @@ public final class Entity {
|
||||
}
|
||||
|
||||
public static void deleteEntity(
|
||||
String updatedBy, String entityType, UUID entityId, boolean recursive, boolean hardDelete, boolean internal)
|
||||
throws IOException {
|
||||
String updatedBy, String entityType, UUID entityId, boolean recursive, boolean hardDelete) throws IOException {
|
||||
EntityRepository<?> dao = getEntityRepository(entityType);
|
||||
dao.delete(updatedBy, entityId.toString(), recursive, hardDelete);
|
||||
}
|
||||
|
@ -14,108 +14,20 @@
|
||||
package org.openmetadata.catalog.elasticsearch;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class ElasticSearchConfiguration {
|
||||
|
||||
@NotEmpty private String host;
|
||||
|
||||
@NotEmpty private Integer port;
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
private String scheme;
|
||||
|
||||
private String truststorePath;
|
||||
|
||||
private String truststorePassword;
|
||||
|
||||
private Integer connectionTimeoutSecs = 5;
|
||||
|
||||
private Integer socketTimeoutSecs = 60;
|
||||
|
||||
private Integer batchSize = 10;
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public Integer getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(Integer port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getScheme() {
|
||||
return scheme;
|
||||
}
|
||||
|
||||
public void setScheme(String scheme) {
|
||||
this.scheme = scheme;
|
||||
}
|
||||
|
||||
public String getTruststorePath() {
|
||||
return truststorePath;
|
||||
}
|
||||
|
||||
public void setTruststorePath(String truststorePath) {
|
||||
this.truststorePath = truststorePath;
|
||||
}
|
||||
|
||||
public String getTruststorePassword() {
|
||||
return truststorePassword;
|
||||
}
|
||||
|
||||
public void setTruststorePassword(String truststorePassword) {
|
||||
this.truststorePassword = truststorePassword;
|
||||
}
|
||||
|
||||
public Integer getConnectionTimeoutSecs() {
|
||||
return connectionTimeoutSecs;
|
||||
}
|
||||
|
||||
public void setConnectionTimeoutSecs(Integer connectionTimeoutSecs) {
|
||||
this.connectionTimeoutSecs = connectionTimeoutSecs;
|
||||
}
|
||||
|
||||
public Integer getSocketTimeoutSecs() {
|
||||
return socketTimeoutSecs;
|
||||
}
|
||||
|
||||
public void setSocketTimeoutSecs(Integer socketTimeoutSecs) {
|
||||
this.socketTimeoutSecs = socketTimeoutSecs;
|
||||
}
|
||||
|
||||
public Integer getBatchSize() {
|
||||
return batchSize;
|
||||
}
|
||||
|
||||
public void setBatchSize(Integer batchSize) {
|
||||
this.batchSize = batchSize;
|
||||
}
|
||||
@NotEmpty @Getter @Setter private String host;
|
||||
@NotEmpty @Getter @Setter private Integer port;
|
||||
@Getter @Setter private String username;
|
||||
@Getter @Setter private String password;
|
||||
@Getter @Setter private String scheme;
|
||||
@Getter @Setter private String truststorePath;
|
||||
@Getter @Setter private String truststorePassword;
|
||||
@Getter @Setter private Integer connectionTimeoutSecs = 5;
|
||||
@Getter @Setter private Integer socketTimeoutSecs = 60;
|
||||
@Getter @Setter private Integer batchSize = 10;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -13,15 +13,9 @@
|
||||
package org.openmetadata.catalog.events;
|
||||
|
||||
import java.util.Set;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class EventHandlerConfiguration {
|
||||
private Set<String> eventHandlerClassNames;
|
||||
|
||||
public Set<String> getEventHandlerClassNames() {
|
||||
return eventHandlerClassNames;
|
||||
}
|
||||
|
||||
public void setEventHandlerClassNames(Set<String> eventHandlerClassNames) {
|
||||
this.eventHandlerClassNames = eventHandlerClassNames;
|
||||
}
|
||||
@Getter @Setter private Set<String> eventHandlerClassNames;
|
||||
}
|
||||
|
@ -1,21 +1,10 @@
|
||||
package org.openmetadata.catalog.events;
|
||||
|
||||
import java.util.Map;
|
||||
import lombok.Getter;
|
||||
|
||||
public class EventPublisherConfiguration {
|
||||
String name;
|
||||
String className;
|
||||
Map<String, Object> config;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public Map<String, Object> getConfig() {
|
||||
return config;
|
||||
}
|
||||
@Getter String name;
|
||||
@Getter String className;
|
||||
@Getter Map<String, Object> config;
|
||||
}
|
||||
|
@ -15,9 +15,10 @@ package org.openmetadata.catalog.exception;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import lombok.Getter;
|
||||
|
||||
public abstract class WebServiceException extends RuntimeException {
|
||||
private final transient Response response;
|
||||
@Getter private final transient Response response;
|
||||
|
||||
protected WebServiceException(Response.Status status, String msg) {
|
||||
super(msg);
|
||||
@ -41,20 +42,12 @@ public abstract class WebServiceException extends RuntimeException {
|
||||
return new ErrorResponse(msg);
|
||||
}
|
||||
|
||||
public Response getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
private static class ErrorResponse {
|
||||
/** Response message. */
|
||||
private final String responseMessage;
|
||||
@Getter private final String responseMessage;
|
||||
|
||||
ErrorResponse(String responseMessage) {
|
||||
this.responseMessage = responseMessage;
|
||||
}
|
||||
|
||||
public String getResponseMessage() {
|
||||
return responseMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,46 +15,75 @@ package org.openmetadata.catalog.jdbi3;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.openmetadata.catalog.Entity;
|
||||
import org.openmetadata.catalog.entity.Bots;
|
||||
import org.openmetadata.catalog.resources.bots.BotsResource;
|
||||
import org.openmetadata.catalog.entity.Bot;
|
||||
import org.openmetadata.catalog.entity.teams.User;
|
||||
import org.openmetadata.catalog.resources.bots.BotResource;
|
||||
import org.openmetadata.catalog.type.ChangeDescription;
|
||||
import org.openmetadata.catalog.type.EntityReference;
|
||||
import org.openmetadata.catalog.type.Include;
|
||||
import org.openmetadata.catalog.type.Relationship;
|
||||
import org.openmetadata.catalog.util.EntityInterface;
|
||||
import org.openmetadata.catalog.util.EntityUtil.Fields;
|
||||
|
||||
public class BotsRepository extends EntityRepository<Bots> {
|
||||
public BotsRepository(CollectionDAO dao) {
|
||||
super(BotsResource.COLLECTION_PATH, Entity.BOTS, Bots.class, dao.botsDAO(), dao, "", "");
|
||||
public class BotRepository extends EntityRepository<Bot> {
|
||||
public BotRepository(CollectionDAO dao) {
|
||||
super(BotResource.COLLECTION_PATH, Entity.BOT, Bot.class, dao.botDAO(), dao, "", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bots setFields(Bots entity, Fields fields) {
|
||||
return entity;
|
||||
public Bot setFields(Bot entity, Fields fields) throws IOException {
|
||||
return entity.withBotUser(getBotUser(entity));
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityInterface<Bots> getEntityInterface(Bots entity) {
|
||||
return new BotsEntityInterface(entity);
|
||||
public EntityInterface<Bot> getEntityInterface(Bot entity) {
|
||||
return new BotEntityInterface(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare(Bots entity) {}
|
||||
public void prepare(Bot entity) throws IOException {
|
||||
User user = daoCollection.userDAO().findEntityById(entity.getBotUser().getId(), Include.ALL);
|
||||
entity.getBotUser().withName(user.getName()).withDisplayName(user.getDisplayName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeEntity(Bots entity, boolean update) throws IOException {
|
||||
public void storeEntity(Bot entity, boolean update) throws IOException {
|
||||
EntityReference botUser = entity.getBotUser();
|
||||
entity.withBotUser(null);
|
||||
store(entity.getId(), entity, update);
|
||||
entity.withBotUser(botUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeRelationships(Bots entity) {
|
||||
/* Nothing to do */
|
||||
public void storeRelationships(Bot entity) {
|
||||
addRelationship(entity.getId(), entity.getBotUser().getId(), Entity.BOT, Entity.USER, Relationship.CONTAINS);
|
||||
}
|
||||
|
||||
public static class BotsEntityInterface extends EntityInterface<Bots> {
|
||||
public BotsEntityInterface(Bots entity) {
|
||||
super(Entity.BOTS, entity);
|
||||
@Override
|
||||
public EntityRepository<Bot>.EntityUpdater getUpdater(Bot original, Bot updated, Operation operation) {
|
||||
return new BotUpdater(original, updated, operation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restorePatchAttributes(Bot original, Bot updated) {
|
||||
// Bot user can't be changed by patch
|
||||
updated.withBotUser(original.getBotUser());
|
||||
}
|
||||
|
||||
public EntityReference getBotUser(Bot bot) throws IOException {
|
||||
List<String> refs = findTo(bot.getId(), Entity.BOT, Relationship.CONTAINS, Entity.USER);
|
||||
ensureSingleRelationship(Entity.BOT, bot.getId(), refs, "botUser", true);
|
||||
return refs.isEmpty()
|
||||
? null
|
||||
: daoCollection.userDAO().findEntityReferenceById(UUID.fromString(refs.get(0)), Include.ALL);
|
||||
}
|
||||
|
||||
public static class BotEntityInterface extends EntityInterface<Bot> {
|
||||
public BotEntityInterface(Bot entity) {
|
||||
super(Entity.BOT, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -113,7 +142,7 @@ public class BotsRepository extends EntityRepository<Bots> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bots getEntity() {
|
||||
public Bot getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
@ -160,8 +189,14 @@ public class BotsRepository extends EntityRepository<Bots> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bots withHref(URI href) {
|
||||
public Bot withHref(URI href) {
|
||||
return entity.withHref(href);
|
||||
}
|
||||
}
|
||||
|
||||
public class BotUpdater extends EntityUpdater {
|
||||
public BotUpdater(Bot original, Bot updated, Operation operation) {
|
||||
super(original, updated, operation);
|
||||
}
|
||||
}
|
||||
}
|
@ -32,7 +32,7 @@ import org.jdbi.v3.sqlobject.customizer.Define;
|
||||
import org.jdbi.v3.sqlobject.statement.SqlQuery;
|
||||
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
|
||||
import org.openmetadata.catalog.Entity;
|
||||
import org.openmetadata.catalog.entity.Bots;
|
||||
import org.openmetadata.catalog.entity.Bot;
|
||||
import org.openmetadata.catalog.entity.data.Chart;
|
||||
import org.openmetadata.catalog.entity.data.Dashboard;
|
||||
import org.openmetadata.catalog.entity.data.Database;
|
||||
@ -56,7 +56,7 @@ import org.openmetadata.catalog.entity.services.ingestionPipelines.IngestionPipe
|
||||
import org.openmetadata.catalog.entity.teams.Role;
|
||||
import org.openmetadata.catalog.entity.teams.Team;
|
||||
import org.openmetadata.catalog.entity.teams.User;
|
||||
import org.openmetadata.catalog.jdbi3.BotsRepository.BotsEntityInterface;
|
||||
import org.openmetadata.catalog.jdbi3.BotRepository.BotEntityInterface;
|
||||
import org.openmetadata.catalog.jdbi3.ChartRepository.ChartEntityInterface;
|
||||
import org.openmetadata.catalog.jdbi3.CollectionDAO.TagUsageDAO.TagLabelMapper;
|
||||
import org.openmetadata.catalog.jdbi3.CollectionDAO.UsageDAO.UsageDetailsMapper;
|
||||
@ -164,7 +164,7 @@ public interface CollectionDAO {
|
||||
GlossaryTermDAO glossaryTermDAO();
|
||||
|
||||
@CreateSqlObject
|
||||
BotsDAO botsDAO();
|
||||
BotDAO botDAO();
|
||||
|
||||
@CreateSqlObject
|
||||
PolicyDAO policyDAO();
|
||||
@ -860,25 +860,25 @@ public interface CollectionDAO {
|
||||
}
|
||||
}
|
||||
|
||||
interface BotsDAO extends EntityDAO<Bots> {
|
||||
interface BotDAO extends EntityDAO<Bot> {
|
||||
@Override
|
||||
default String getTableName() {
|
||||
return "bots_entity";
|
||||
return "bot_entity";
|
||||
}
|
||||
|
||||
@Override
|
||||
default Class<Bots> getEntityClass() {
|
||||
return Bots.class;
|
||||
default Class<Bot> getEntityClass() {
|
||||
return Bot.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
default String getNameColumn() {
|
||||
return "fullyQualifiedName";
|
||||
return "name";
|
||||
}
|
||||
|
||||
@Override
|
||||
default EntityReference getEntityReference(Bots entity) {
|
||||
return new BotsEntityInterface(entity).getEntityReference();
|
||||
default EntityReference getEntityReference(Bot entity) {
|
||||
return new BotEntityInterface(entity).getEntityReference();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -529,6 +529,7 @@ public abstract class EntityRepository<T> {
|
||||
cleanup(entityInterface);
|
||||
changeType = RestUtil.ENTITY_DELETED;
|
||||
}
|
||||
LOG.info("{} deleted {} {}", hardDelete ? "Hard" : "Soft", entityInterface.getFullyQualifiedName());
|
||||
return new DeleteResponse<>(updated, changeType);
|
||||
}
|
||||
|
||||
@ -546,8 +547,12 @@ public abstract class EntityRepository<T> {
|
||||
}
|
||||
// Delete all the contained entities
|
||||
for (EntityReference entityReference : contains) {
|
||||
LOG.info("Recursively deleting {} {}", entityReference.getType(), entityReference.getId());
|
||||
Entity.deleteEntity(updatedBy, entityReference.getType(), entityReference.getId(), true, hardDelete, true);
|
||||
LOG.info(
|
||||
"Recursively {} deleting {} {}",
|
||||
hardDelete ? "hard" : "soft",
|
||||
entityReference.getType(),
|
||||
entityReference.getId());
|
||||
Entity.deleteEntity(updatedBy, entityReference.getType(), entityReference.getId(), true, hardDelete);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright 2021 Collate
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.openmetadata.catalog.resources.bots;
|
||||
|
||||
import static org.openmetadata.catalog.security.SecurityUtil.ADMIN;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.v3.oas.annotations.ExternalDocumentation;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.json.JsonPatch;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.DefaultValue;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PATCH;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.SecurityContext;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import org.openmetadata.catalog.Entity;
|
||||
import org.openmetadata.catalog.api.CreateBot;
|
||||
import org.openmetadata.catalog.entity.Bot;
|
||||
import org.openmetadata.catalog.jdbi3.BotRepository;
|
||||
import org.openmetadata.catalog.jdbi3.CollectionDAO;
|
||||
import org.openmetadata.catalog.jdbi3.ListFilter;
|
||||
import org.openmetadata.catalog.resources.Collection;
|
||||
import org.openmetadata.catalog.resources.EntityResource;
|
||||
import org.openmetadata.catalog.security.Authorizer;
|
||||
import org.openmetadata.catalog.type.EntityHistory;
|
||||
import org.openmetadata.catalog.type.Include;
|
||||
import org.openmetadata.catalog.util.ResultList;
|
||||
|
||||
@Path("/v1/bots")
|
||||
@Api(value = "Bot collection", tags = "Bot collection")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Collection(name = "bots")
|
||||
public class BotResource extends EntityResource<Bot, BotRepository> {
|
||||
public static final String COLLECTION_PATH = "/v1/bots/";
|
||||
|
||||
public BotResource(CollectionDAO dao, Authorizer authorizer) {
|
||||
super(Bot.class, new BotRepository(dao), authorizer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bot addHref(UriInfo uriInfo, Bot entity) {
|
||||
Entity.withHref(uriInfo, entity.getBotUser());
|
||||
return entity;
|
||||
}
|
||||
|
||||
public static class BotList extends ResultList<Bot> {
|
||||
@SuppressWarnings("unused")
|
||||
public BotList() {
|
||||
/* Required for serde */
|
||||
}
|
||||
|
||||
public BotList(List<Bot> data) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Operation(
|
||||
summary = "List Bot",
|
||||
tags = "bots",
|
||||
description = "Get a list of Bot.",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "List of Bot",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = BotList.class)))
|
||||
})
|
||||
public ResultList<Bot> list(
|
||||
@Context UriInfo uriInfo,
|
||||
@Context SecurityContext securityContext,
|
||||
@DefaultValue("10") @Min(0) @Max(1000000) @QueryParam("limit") int limitParam,
|
||||
@Parameter(description = "Returns list of Bot before this cursor", schema = @Schema(type = "string"))
|
||||
@QueryParam("before")
|
||||
String before,
|
||||
@Parameter(description = "Returns list of Bot after this cursor", schema = @Schema(type = "string"))
|
||||
@QueryParam("after")
|
||||
String after,
|
||||
@Parameter(
|
||||
description = "Include all, deleted, or non-deleted entities.",
|
||||
schema = @Schema(implementation = Include.class))
|
||||
@QueryParam("include")
|
||||
@DefaultValue("non-deleted")
|
||||
Include include)
|
||||
throws IOException {
|
||||
return listInternal(uriInfo, securityContext, "", new ListFilter(include), limitParam, before, after);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
@Operation(
|
||||
summary = "Get a bot",
|
||||
tags = "bots",
|
||||
description = "Get a bot by `id`.",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "The bot",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Bot.class))),
|
||||
@ApiResponse(responseCode = "404", description = "Bot for instance {id} is not found")
|
||||
})
|
||||
public Bot get(
|
||||
@Context UriInfo uriInfo,
|
||||
@Context SecurityContext securityContext,
|
||||
@QueryParam("include") @DefaultValue("non-deleted") Include include,
|
||||
@PathParam("id") String id)
|
||||
throws IOException {
|
||||
return getInternal(uriInfo, securityContext, id, "", include);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/name/{fqn}")
|
||||
@Operation(
|
||||
summary = "Get a bot by name",
|
||||
tags = "bots",
|
||||
description = "Get a bot by name.",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "bot",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Bot.class))),
|
||||
@ApiResponse(responseCode = "404", description = "Bot for instance {name} is not found")
|
||||
})
|
||||
public Bot getByName(
|
||||
@Context UriInfo uriInfo,
|
||||
@Context SecurityContext securityContext,
|
||||
@Parameter(description = "Fully qualified name of the table", schema = @Schema(type = "string")) @PathParam("fqn")
|
||||
String fqn,
|
||||
@Parameter(
|
||||
description = "Include all, deleted, or non-deleted entities.",
|
||||
schema = @Schema(implementation = Include.class))
|
||||
@QueryParam("include")
|
||||
@DefaultValue("non-deleted")
|
||||
Include include)
|
||||
throws IOException {
|
||||
return getByNameInternal(uriInfo, securityContext, fqn, "", include);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}/versions")
|
||||
@Operation(
|
||||
summary = "List bot versions",
|
||||
tags = "bots",
|
||||
description = "Get a list of all the versions of a bot identified by `id`",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "List of bot versions",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = EntityHistory.class)))
|
||||
})
|
||||
public EntityHistory listVersions(
|
||||
@Context UriInfo uriInfo,
|
||||
@Context SecurityContext securityContext,
|
||||
@Parameter(description = "bot Id", schema = @Schema(type = "string")) @PathParam("id") String id)
|
||||
throws IOException {
|
||||
return dao.listVersions(id);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}/versions/{version}")
|
||||
@Operation(
|
||||
summary = "Get a version of the bot",
|
||||
tags = "bots",
|
||||
description = "Get a version of the bot by given `id`",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "bot",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Bot.class))),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "Bot for instance {id} and version {version} is " + "not found")
|
||||
})
|
||||
public Bot getVersion(
|
||||
@Context UriInfo uriInfo,
|
||||
@Context SecurityContext securityContext,
|
||||
@Parameter(description = "bot Id", schema = @Schema(type = "string")) @PathParam("id") String id,
|
||||
@Parameter(
|
||||
description = "bot version number in the form `major`.`minor`",
|
||||
schema = @Schema(type = "string", example = "0.1 or 1.1"))
|
||||
@PathParam("version")
|
||||
String version)
|
||||
throws IOException {
|
||||
return dao.getVersion(id, version);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Operation(
|
||||
summary = "Create a bot",
|
||||
tags = "bots",
|
||||
description = "Create a new bot.",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "The bot ",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Bot.class))),
|
||||
@ApiResponse(responseCode = "400", description = "Bad request")
|
||||
})
|
||||
public Response create(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateBot create)
|
||||
throws IOException {
|
||||
Bot bot = getBot(securityContext, create);
|
||||
return create(uriInfo, securityContext, bot, ADMIN);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Operation(
|
||||
summary = "Create or update a bot",
|
||||
tags = "bots",
|
||||
description = "Create a bot, if it does not exist. If a bot already exists, update the bot.",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "The bot",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = CreateBot.class))),
|
||||
@ApiResponse(responseCode = "400", description = "Bad request")
|
||||
})
|
||||
public Response createOrUpdate(
|
||||
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateBot create) throws IOException {
|
||||
Bot bot = getBot(securityContext, create);
|
||||
return createOrUpdate(uriInfo, securityContext, bot, ADMIN);
|
||||
}
|
||||
|
||||
@PATCH
|
||||
@Path("/{id}")
|
||||
@Operation(
|
||||
summary = "Update a bot",
|
||||
tags = "bots",
|
||||
description = "Update an existing bot using JsonPatch.",
|
||||
externalDocs = @ExternalDocumentation(description = "JsonPatch RFC", url = "https://tools.ietf.org/html/rfc6902"))
|
||||
@Consumes(MediaType.APPLICATION_JSON_PATCH_JSON)
|
||||
public Response patch(
|
||||
@Context UriInfo uriInfo,
|
||||
@Context SecurityContext securityContext,
|
||||
@Parameter(description = "Id of the bot", schema = @Schema(type = "string")) @PathParam("id") String id,
|
||||
@RequestBody(
|
||||
description = "JsonPatch with array of operations",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = MediaType.APPLICATION_JSON_PATCH_JSON,
|
||||
examples = {
|
||||
@ExampleObject("[" + "{op:remove, path:/a}," + "{op:add, path: /b, value: val}" + "]")
|
||||
}))
|
||||
JsonPatch patch)
|
||||
throws IOException {
|
||||
return patchInternal(uriInfo, securityContext, id, patch);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
@Operation(
|
||||
summary = "Delete a bot",
|
||||
tags = "bots",
|
||||
description = "Delete a bot by `id`. Bot is not immediately deleted and is only marked as deleted.",
|
||||
responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK"),
|
||||
@ApiResponse(responseCode = "404", description = "Bot for instance {id} is not found")
|
||||
})
|
||||
public Response delete(
|
||||
@Context UriInfo uriInfo,
|
||||
@Context SecurityContext securityContext,
|
||||
@Parameter(description = "Hard delete the entity. (Default = `false`)")
|
||||
@QueryParam("hardDelete")
|
||||
@DefaultValue("false")
|
||||
boolean hardDelete,
|
||||
@Parameter(description = "Id of the Bot", schema = @Schema(type = "string")) @PathParam("id") String id)
|
||||
throws IOException {
|
||||
return delete(uriInfo, securityContext, id, true, hardDelete, ADMIN);
|
||||
}
|
||||
|
||||
private Bot getBot(SecurityContext securityContext, CreateBot create) {
|
||||
return new Bot()
|
||||
.withId(UUID.randomUUID())
|
||||
.withName(create.getName())
|
||||
.withDescription(create.getDescription())
|
||||
.withDisplayName(create.getDisplayName())
|
||||
.withBotUser(create.getBotUser())
|
||||
.withUpdatedBy(securityContext.getUserPrincipal().getName())
|
||||
.withUpdatedAt(System.currentTimeMillis());
|
||||
}
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 Collate
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.openmetadata.catalog.resources.bots;
|
||||
|
||||
import static org.openmetadata.catalog.security.SecurityUtil.ADMIN;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DefaultValue;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.SecurityContext;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import org.openmetadata.catalog.entity.Bots;
|
||||
import org.openmetadata.catalog.jdbi3.BotsRepository;
|
||||
import org.openmetadata.catalog.jdbi3.CollectionDAO;
|
||||
import org.openmetadata.catalog.jdbi3.ListFilter;
|
||||
import org.openmetadata.catalog.resources.Collection;
|
||||
import org.openmetadata.catalog.resources.EntityResource;
|
||||
import org.openmetadata.catalog.security.Authorizer;
|
||||
import org.openmetadata.catalog.util.EntityUtil.Fields;
|
||||
import org.openmetadata.catalog.util.ResultList;
|
||||
|
||||
@Path("/v1/bots")
|
||||
@Api(value = "Bots collection", tags = "Bots collection")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Collection(name = "bots")
|
||||
public class BotsResource extends EntityResource<Bots, BotsRepository> {
|
||||
public static final String COLLECTION_PATH = "/v1/bots/";
|
||||
|
||||
public BotsResource(CollectionDAO dao, Authorizer authorizer) {
|
||||
super(Bots.class, new BotsRepository(dao), authorizer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bots addHref(UriInfo uriInfo, Bots entity) {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public static class BotsList extends ResultList<Bots> {
|
||||
public BotsList(List<Bots> data) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Operation(
|
||||
summary = "List bots",
|
||||
tags = "bots",
|
||||
description = "Get a list of bots.",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "List of bots",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = BotsList.class)))
|
||||
})
|
||||
public ResultList<Bots> list(
|
||||
@Context UriInfo uriInfo,
|
||||
@Context SecurityContext securityContext,
|
||||
@DefaultValue("10") @Min(0) @Max(1000000) @QueryParam("limit") int limitParam,
|
||||
@Parameter(description = "Returns list of bots before this cursor", schema = @Schema(type = "string"))
|
||||
@QueryParam("before")
|
||||
String before,
|
||||
@Parameter(description = "Returns list of bots after this cursor", schema = @Schema(type = "string"))
|
||||
@QueryParam("after")
|
||||
String after)
|
||||
throws IOException {
|
||||
return super.listInternal(uriInfo, securityContext, "", new ListFilter(), limitParam, before, after);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
@Operation(
|
||||
summary = "Get a bot",
|
||||
tags = "bots",
|
||||
description = "Get a bot by `id`.",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "The bot",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Bots.class))),
|
||||
@ApiResponse(responseCode = "404", description = "Bot for instance {id} is not found")
|
||||
})
|
||||
public Bots get(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @PathParam("id") String id)
|
||||
throws IOException {
|
||||
return dao.get(uriInfo, id, Fields.EMPTY_FIELDS);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Operation(
|
||||
summary = "Create a bot",
|
||||
tags = "bots",
|
||||
description = "Create a new bot.",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "The bot ",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Bots.class))),
|
||||
@ApiResponse(responseCode = "400", description = "Bad request")
|
||||
})
|
||||
public Response create(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid Bots bot)
|
||||
throws IOException {
|
||||
bot.withId(UUID.randomUUID())
|
||||
.withUpdatedBy(securityContext.getUserPrincipal().getName())
|
||||
.withUpdatedAt(System.currentTimeMillis());
|
||||
return create(uriInfo, securityContext, bot, ADMIN);
|
||||
}
|
||||
}
|
@ -14,41 +14,23 @@
|
||||
package org.openmetadata.catalog.security;
|
||||
|
||||
import java.security.Principal;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.openmetadata.catalog.entity.teams.User;
|
||||
import org.openmetadata.catalog.util.EntityUtil.Fields;
|
||||
|
||||
/** Holds context information of authenticated user, which will be used for authorization. */
|
||||
public final class AuthenticationContext {
|
||||
private final Principal principal;
|
||||
private User user;
|
||||
private Fields userFields;
|
||||
@Getter private final Principal principal;
|
||||
@Getter @Setter private User user;
|
||||
@Getter @Setter private Fields userFields;
|
||||
|
||||
public AuthenticationContext(Principal principal) {
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
public Principal getPrincipal() {
|
||||
return principal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AuthenticationContext{" + ", principal=" + principal + '}';
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public Fields getUserFields() {
|
||||
return userFields;
|
||||
}
|
||||
|
||||
public void setUserFields(Fields userFields) {
|
||||
this.userFields = userFields;
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,10 @@ package org.openmetadata.catalog.security;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import lombok.Getter;
|
||||
|
||||
public class AuthenticationException extends RuntimeException {
|
||||
private final transient Response response;
|
||||
@Getter private final transient Response response;
|
||||
|
||||
public AuthenticationException(String msg) {
|
||||
super(msg);
|
||||
@ -41,20 +42,12 @@ public class AuthenticationException extends RuntimeException {
|
||||
return new ErrorResponse(msg);
|
||||
}
|
||||
|
||||
public Response getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
private static class ErrorResponse {
|
||||
/** Response message. */
|
||||
private final String responseMessage;
|
||||
@Getter private final String responseMessage;
|
||||
|
||||
ErrorResponse(String responseMessage) {
|
||||
this.responseMessage = responseMessage;
|
||||
}
|
||||
|
||||
public String getResponseMessage() {
|
||||
return responseMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,10 @@ package org.openmetadata.catalog.security;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import lombok.Getter;
|
||||
|
||||
public class AuthorizationException extends RuntimeException {
|
||||
private final transient Response response;
|
||||
@Getter private final transient Response response;
|
||||
|
||||
public AuthorizationException(String msg) {
|
||||
super(msg);
|
||||
@ -41,20 +42,12 @@ public class AuthorizationException extends RuntimeException {
|
||||
return new ErrorResponse(msg);
|
||||
}
|
||||
|
||||
public Response getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
private static class ErrorResponse {
|
||||
/** Response message. */
|
||||
private final String responseMessage;
|
||||
@Getter private final String responseMessage;
|
||||
|
||||
ErrorResponse(String responseMessage) {
|
||||
this.responseMessage = responseMessage;
|
||||
}
|
||||
|
||||
public String getResponseMessage() {
|
||||
return responseMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,19 +14,15 @@
|
||||
package org.openmetadata.catalog.security;
|
||||
|
||||
import java.security.Principal;
|
||||
import lombok.Getter;
|
||||
|
||||
public class CatalogPrincipal implements Principal {
|
||||
private final String name;
|
||||
@Getter private final String name;
|
||||
|
||||
public CatalogPrincipal(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CatalogPrincipal{" + "name='" + name + '\'' + '}';
|
||||
|
@ -20,7 +20,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
/** Holds authenticated principal and security context which is passed to the JAX-RS request methods */
|
||||
public class CatalogSecurityContext implements SecurityContext {
|
||||
|
||||
private final Principal principal;
|
||||
private final String scheme;
|
||||
private final String authenticationScheme;
|
||||
|
@ -15,6 +15,7 @@ import java.time.ZoneId;
|
||||
import java.util.Base64;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.openmetadata.catalog.entity.teams.User;
|
||||
import org.openmetadata.catalog.teams.authn.JWTTokenExpiry;
|
||||
@ -23,7 +24,7 @@ import org.openmetadata.catalog.teams.authn.JWTTokenExpiry;
|
||||
public class JWTTokenGenerator {
|
||||
private static volatile JWTTokenGenerator instance;
|
||||
private RSAPrivateKey privateKey;
|
||||
private RSAPublicKey publicKey;
|
||||
@Getter private RSAPublicKey publicKey;
|
||||
private String issuer;
|
||||
private String kid;
|
||||
|
||||
@ -66,10 +67,6 @@ public class JWTTokenGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
public RSAPublicKey getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
public String generateJWTToken(User user, JWTTokenExpiry expiry) {
|
||||
try {
|
||||
Algorithm algorithm = Algorithm.RSA256(null, privateKey);
|
||||
|
@ -0,0 +1,28 @@
|
||||
{
|
||||
"$id": "https://open-metadata.org/schema/entity/createBot.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "createBot",
|
||||
"description": "Create bot API request",
|
||||
"type": "object",
|
||||
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Name of the bot.",
|
||||
"$ref": "../type/basic.json#/definitions/entityName"
|
||||
},
|
||||
"displayName": {
|
||||
"description": "Name used for display purposes. Example 'FirstName LastName'.",
|
||||
"type": "string"
|
||||
},
|
||||
"botUser" : {
|
||||
"description": "Bot user created for this bot on behalf of which the bot performs all the operations, such as updating description, responding on the conversation threads, etc.",
|
||||
"$ref" : "../type/entityReference.json"
|
||||
},
|
||||
"description": {
|
||||
"description": "Description of the bot.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["name", "botUser"],
|
||||
"additionalProperties": false
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
"$id": "https://open-metadata.org/schema/entity/bots.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Bot",
|
||||
"description": "This schema defines Bot entity. A bot automates tasks, such as adding description, identifying the importance of data. It runs as a special user in the system.",
|
||||
"description": "This schema defines a Bot entity. A bot automates tasks, such as adding description, identifying the importance of data. It performs this task as a special user in the system.",
|
||||
"type": "object",
|
||||
|
||||
"properties": {
|
||||
@ -22,6 +22,10 @@
|
||||
"description": "Description of the bot.",
|
||||
"type": "string"
|
||||
},
|
||||
"botUser" : {
|
||||
"description": "Bot user created for this bot on behalf of which the bot performs all the operations, such as updating description, responding on the conversation threads, etc.",
|
||||
"$ref" : "../type/entityReference.json"
|
||||
},
|
||||
"version": {
|
||||
"description": "Metadata version of the entity.",
|
||||
"$ref": "../type/entityHistory.json#/definitions/entityVersion"
|
||||
@ -48,5 +52,6 @@
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"required": ["id", "name", "botUser"],
|
||||
"additionalProperties": false
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
package org.openmetadata.catalog.resources.bots;
|
||||
|
||||
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.getPrincipal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Map;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.http.client.HttpResponseException;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInfo;
|
||||
import org.openmetadata.catalog.Entity;
|
||||
import org.openmetadata.catalog.api.CreateBot;
|
||||
import org.openmetadata.catalog.api.teams.CreateUser;
|
||||
import org.openmetadata.catalog.entity.Bot;
|
||||
import org.openmetadata.catalog.entity.teams.User;
|
||||
import org.openmetadata.catalog.jdbi3.BotRepository.BotEntityInterface;
|
||||
import org.openmetadata.catalog.jdbi3.UserRepository.UserEntityInterface;
|
||||
import org.openmetadata.catalog.resources.EntityResourceTest;
|
||||
import org.openmetadata.catalog.resources.bots.BotResource.BotList;
|
||||
import org.openmetadata.catalog.resources.teams.UserResourceTest;
|
||||
import org.openmetadata.catalog.type.EntityReference;
|
||||
import org.openmetadata.catalog.util.EntityInterface;
|
||||
import org.openmetadata.catalog.util.TestUtils;
|
||||
|
||||
public class BotResourceTest extends EntityResourceTest<Bot, CreateBot> {
|
||||
public static User botUser;
|
||||
public static EntityReference botUserRef;
|
||||
|
||||
public BotResourceTest() {
|
||||
super(Entity.BOT, Bot.class, BotList.class, "bots", ""); // TODO fix this
|
||||
supportsFieldsQueryParam = false;
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public void setup(TestInfo test) throws URISyntaxException, IOException {
|
||||
super.setup(test);
|
||||
UserResourceTest userResourceTest = new UserResourceTest();
|
||||
CreateUser createUser = userResourceTest.createRequest("botUser", "", "", null);
|
||||
botUser = new UserResourceTest().createEntity(createUser, ADMIN_AUTH_HEADERS);
|
||||
botUserRef = new UserEntityInterface(botUser).getEntityReference();
|
||||
}
|
||||
|
||||
@Test
|
||||
void delete_ensureBotUserDelete(TestInfo test) throws IOException {
|
||||
UserResourceTest userResourceTest = new UserResourceTest();
|
||||
CreateUser createUser = userResourceTest.createRequest(test);
|
||||
User testUser = new UserResourceTest().createEntity(createUser, ADMIN_AUTH_HEADERS);
|
||||
EntityReference testUserRef = new UserEntityInterface(testUser).getEntityReference();
|
||||
|
||||
CreateBot create = createRequest(test).withBotUser(testUserRef);
|
||||
Bot bot = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
|
||||
|
||||
deleteAndCheckEntity(bot, true, true, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// When bot is deleted, the corresponding bot user is also deleted
|
||||
assertEntityDeleted(testUser.getId(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateBot createRequest(String name, String description, String displayName, EntityReference owner) {
|
||||
return new CreateBot()
|
||||
.withName(name)
|
||||
.withDescription(description)
|
||||
.withDisplayName(displayName)
|
||||
.withBotUser(botUserRef);
|
||||
}
|
||||
|
||||
@SneakyThrows // TODO remove
|
||||
@Override
|
||||
public void validateCreatedEntity(Bot entity, CreateBot request, Map<String, String> authHeaders)
|
||||
throws HttpResponseException {
|
||||
validateCommonEntityFields(getEntityInterface(entity), request.getDescription(), getPrincipal(authHeaders), null);
|
||||
assertReference(request.getBotUser(), entity.getBotUser());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compareEntities(Bot expected, Bot updated, Map<String, String> authHeaders) throws HttpResponseException {
|
||||
validateCommonEntityFields(
|
||||
getEntityInterface(updated), expected.getDescription(), TestUtils.getPrincipal(authHeaders), null);
|
||||
assertReference(expected.getBotUser(), updated.getBotUser());
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityInterface<Bot> getEntityInterface(Bot entity) {
|
||||
return new BotEntityInterface(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityInterface<Bot> validateGetWithDifferentFields(Bot entity, boolean byName) throws HttpResponseException {
|
||||
return new BotEntityInterface(entity); // TODO cleanup
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assertFieldChange(String fieldName, Object expected, Object actual) throws IOException {}
|
||||
}
|
@ -19,6 +19,8 @@ import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.SecurityContext;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.openmetadata.catalog.resources.events.EventResource.ChangeEventList;
|
||||
import org.openmetadata.catalog.type.ChangeEvent;
|
||||
@ -153,28 +155,8 @@ public class WebhookCallbackResource {
|
||||
|
||||
/** Class to keep track of all the events received by a webhook endpoint */
|
||||
static class EventDetails {
|
||||
long firstEventTime;
|
||||
long latestEventTime;
|
||||
ConcurrentLinkedQueue<ChangeEvent> events = new ConcurrentLinkedQueue<>();
|
||||
|
||||
public long getFirstEventTime() {
|
||||
return firstEventTime;
|
||||
}
|
||||
|
||||
public void setFirstEventTime(long firstEventTime) {
|
||||
this.firstEventTime = firstEventTime;
|
||||
}
|
||||
|
||||
public long getLatestEventTime() {
|
||||
return latestEventTime;
|
||||
}
|
||||
|
||||
public void setLatestEventTime(long latestEventTime) {
|
||||
this.latestEventTime = latestEventTime;
|
||||
}
|
||||
|
||||
public ConcurrentLinkedQueue<ChangeEvent> getEvents() {
|
||||
return events;
|
||||
}
|
||||
@Getter @Setter long firstEventTime;
|
||||
@Getter @Setter long latestEventTime;
|
||||
@Getter ConcurrentLinkedQueue<ChangeEvent> events = new ConcurrentLinkedQueue<>();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user