MINOR - Prepare AI chat feed (#15510)

* MINOR - Prepare AI chat feed

* Rename ai to chatbot

* Rename ai to chatbot
This commit is contained in:
Pere Miquel Brull 2024-03-18 10:29:52 +01:00 committed by GitHub
parent 9097eaf182
commit 060a9d7f68
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 108 additions and 7 deletions

View File

@ -61,6 +61,7 @@ import org.jdbi.v3.sqlobject.SqlObjects;
import org.openmetadata.schema.api.security.AuthenticationConfiguration;
import org.openmetadata.schema.api.security.AuthorizerConfiguration;
import org.openmetadata.schema.services.connections.metadata.AuthProvider;
import org.openmetadata.service.apps.ApplicationHandler;
import org.openmetadata.service.apps.scheduler.AppScheduler;
import org.openmetadata.service.config.OMWebBundle;
import org.openmetadata.service.config.OMWebConfiguration;
@ -86,7 +87,6 @@ import org.openmetadata.service.resources.CollectionRegistry;
import org.openmetadata.service.resources.databases.DatasourceConfig;
import org.openmetadata.service.resources.settings.SettingsCache;
import org.openmetadata.service.search.SearchRepository;
import org.openmetadata.service.secrets.SecretsManager;
import org.openmetadata.service.secrets.SecretsManagerFactory;
import org.openmetadata.service.secrets.masker.EntityMaskerFactory;
import org.openmetadata.service.security.Authorizer;
@ -159,9 +159,8 @@ public class OpenMetadataApplication extends Application<OpenMetadataApplication
Fernet.getInstance().setFernetKey(catalogConfig);
// init Secret Manager
final SecretsManager secretsManager =
SecretsManagerFactory.createSecretsManager(
catalogConfig.getSecretsManagerConfiguration(), catalogConfig.getClusterName());
SecretsManagerFactory.createSecretsManager(
catalogConfig.getSecretsManagerConfiguration(), catalogConfig.getClusterName());
// init Entity Masker
EntityMaskerFactory.createEntityMasker();
@ -205,6 +204,7 @@ public class OpenMetadataApplication extends Application<OpenMetadataApplication
// start event hub before registering publishers
EventPubSub.start();
ApplicationHandler.initialize(catalogConfig);
registerResources(catalogConfig, environment, jdbi);
// Register Event Handler

View File

@ -28,6 +28,9 @@ public class ApplicationHandler {
}
public static void initialize(OpenMetadataApplicationConfig config) {
if (instance != null) {
return;
}
instance = new ApplicationHandler(config);
}

View File

@ -913,7 +913,7 @@ public class FeedRepository {
}
private boolean fieldsChanged(Thread original, Thread updated) {
// Patch supports isResolved, message, task assignees, reactions, and announcements for now
// Patch supports isResolved, message, task assignees, reactions, announcements and AI for now
return !original.getResolved().equals(updated.getResolved())
|| !original.getMessage().equals(updated.getMessage())
|| (Collections.isEmpty(original.getReactions())
@ -935,6 +935,10 @@ public class FeedRepository {
|| !Objects.equals(
original.getAnnouncement().getEndTime(),
updated.getAnnouncement().getEndTime())))
|| (original.getChatbot() == null && updated.getChatbot() != null)
|| (original.getChatbot() != null
&& updated.getChatbot() != null
&& !original.getChatbot().getQuery().equals(updated.getChatbot().getQuery()))
|| (original.getTask() != null
&& (original.getTask().getAssignees().size() != updated.getTask().getAssignees().size()
|| !original

View File

@ -112,7 +112,6 @@ public class AppResource extends EntityResource<App, AppRepository> {
// Create an On Demand DAO
CollectionDAO dao = Entity.getCollectionDAO();
searchRepository = new SearchRepository(config.getElasticSearchConfiguration());
ApplicationHandler.initialize(config);
AppScheduler.initialize(config, dao, searchRepository);
// Get Create App Requests

View File

@ -590,6 +590,7 @@ public class FeedResource {
.withType(create.getType())
.withTask(getTaskDetails(create.getTaskDetails()))
.withAnnouncement(create.getAnnouncementDetails())
.withChatbot(create.getChatbotDetails())
.withUpdatedBy(securityContext.getUserPrincipal().getName())
.withUpdatedAt(System.currentTimeMillis());
}

View File

@ -89,6 +89,7 @@ import org.openmetadata.schema.entity.feed.Thread;
import org.openmetadata.schema.entity.teams.Team;
import org.openmetadata.schema.entity.teams.User;
import org.openmetadata.schema.type.AnnouncementDetails;
import org.openmetadata.schema.type.ChatbotDetails;
import org.openmetadata.schema.type.Column;
import org.openmetadata.schema.type.ColumnDataType;
import org.openmetadata.schema.type.EntityReference;
@ -518,6 +519,17 @@ public class FeedResourceTest extends OpenMetadataApplicationTest {
assertEquals(totalAnnouncementCount + 3, announcements.getData().size());
}
@Test
void post_validAI_200() throws IOException {
// Sample EntityLink
String about = String.format("<#E::%s::%s>", Entity.BOT, "ingestion-bot");
createAI(USER.getName(), about, "First AI", "query", USER_AUTH_HEADERS);
createAI(USER.getName(), about, "Second AI", "query", USER_AUTH_HEADERS);
// List all the AI and make sure the number of AI increased by 2
assertEquals(2, listAI(null, null, ADMIN_AUTH_HEADERS).getPaging().getTotal());
}
@Test
void post_invalidAnnouncement_400() throws IOException {
// create two announcements with same start time in the future
@ -922,6 +934,37 @@ public class FeedResourceTest extends OpenMetadataApplicationTest {
assertEquals(TEST_USER_NAME, patched.getUpdatedBy());
}
@Test
void patch_ai_200() throws IOException {
String about = String.format("<#E::%s::%s>", Entity.BOT, "ingestion-bot");
// Create thread without AI
CreateThread create =
new CreateThread()
.withFrom(USER.getName())
.withMessage("message")
.withAbout(about)
.withType(ThreadType.Chatbot);
Thread thread = createAndCheck(create, ADMIN_AUTH_HEADERS);
String originalJson = JsonUtils.pojoToJson(thread);
Thread updated = thread.withChatbot(new ChatbotDetails().withQuery("query"));
Thread patched = patchThreadAndCheck(updated, originalJson, TEST_AUTH_HEADERS);
assertNotEquals(patched.getUpdatedAt(), thread.getUpdatedAt());
assertEquals(TEST_USER_NAME, patched.getUpdatedBy());
assertEquals("query", patched.getChatbot().getQuery());
// Patch again to update the query
String originalJson2 = JsonUtils.pojoToJson(patched);
Thread updated2 = patched.withChatbot(new ChatbotDetails().withQuery("query2"));
Thread patched2 = patchThreadAndCheck(updated2, originalJson2, TEST_AUTH_HEADERS);
assertNotEquals(patched2.getUpdatedAt(), patched.getUpdatedAt());
assertEquals(TEST_USER_NAME, patched2.getUpdatedBy());
assertEquals("query2", patched2.getChatbot().getQuery());
}
@Test
void patch_announcement_200() throws IOException {
LocalDateTime now = LocalDateTime.now();
@ -1550,6 +1593,22 @@ public class FeedResourceTest extends OpenMetadataApplicationTest {
null);
}
public ThreadList listAI(String entityLink, Integer limitPosts, Map<String, String> authHeaders)
throws HttpResponseException {
return listThreads(
entityLink,
limitPosts,
authHeaders,
null,
null,
null,
ThreadType.Chatbot.toString(),
null,
null,
null,
null);
}
public ThreadList listThreads(
String entityLink, Integer limitPosts, Map<String, String> authHeaders)
throws HttpResponseException {
@ -1776,6 +1835,19 @@ public class FeedResourceTest extends OpenMetadataApplicationTest {
return createAndCheck(create, authHeaders);
}
public Thread createAI(
String fromUser, String about, String message, String query, Map<String, String> authHeaders)
throws HttpResponseException {
CreateThread create =
new CreateThread()
.withFrom(fromUser)
.withMessage(message)
.withAbout(about)
.withType(ThreadType.Chatbot)
.withChatbotDetails(new ChatbotDetails().withQuery(query));
return createAndCheck(create, authHeaders);
}
public void validateTaskList(
UUID expectedAssignee,
String expectedSuggestion,

View File

@ -55,6 +55,10 @@
},
"announcementDetails": {
"$ref": "../../entity/feed/thread.json#/definitions/announcementDetails"
},
"chatbotDetails": {
"description": "Details about the Chatbot conversation. This is only applicable if thread is of type Chatbot.",
"$ref": "../../entity/feed/thread.json#/definitions/chatbotDetails"
}
},
"required": ["message", "from", "about"],

View File

@ -109,7 +109,7 @@
"javaType": "org.openmetadata.schema.type.ThreadType",
"type": "string",
"description": "Type of thread.",
"enum": ["Conversation", "Task", "Announcement"],
"enum": ["Conversation", "Task", "Announcement", "Chatbot"],
"javaEnums": [
{
"name": "Conversation"
@ -119,6 +119,9 @@
},
{
"name": "Announcement"
},
{
"name": "Chatbot"
}
],
"default": "Conversation"
@ -144,6 +147,17 @@
"required": ["startTime", "endTime"],
"additionalProperties": false
},
"chatbotDetails": {
"javaType": "org.openmetadata.schema.type.ChatbotDetails",
"description": "Details about the Chatbot conversation. This is only applicable if thread is of type Chatbot.",
"type": "object",
"properties": {
"query": {
"description": "The query being discussed with the Chatbot",
"type": "string"
}
}
},
"post": {
"javaType": "org.openmetadata.schema.type.Post",
"type": "object",
@ -245,6 +259,10 @@
"announcement": {
"description": "Details about the announcement. This is only applicable if thread is of type announcement.",
"$ref": "#/definitions/announcementDetails"
},
"chatbot": {
"description": "Details about the Chatbot conversation. This is only applicable if thread is of type Chatbot.",
"$ref": "#/definitions/chatbotDetails"
}
},
"required": ["id", "about", "message"],