11package com .sap .ai .sdk .app .controllers ;
22
3+ import static com .sap .ai .sdk .foundationmodels .openai .OpenAiModel .TEXT_EMBEDDING_ADA_002 ;
4+ import static java .time .LocalDate .now ;
35import static java .util .stream .Collectors .joining ;
46
57import com .sap .ai .sdk .grounding .GroundingClient ;
68import com .sap .ai .sdk .grounding .api .PipelinesApi ;
79import com .sap .ai .sdk .grounding .api .RetrievalApi ;
810import com .sap .ai .sdk .grounding .api .VectorApi ;
11+ import com .sap .ai .sdk .grounding .model .BaseDocument ;
912import com .sap .ai .sdk .grounding .model .Collection ;
13+ import com .sap .ai .sdk .grounding .model .CollectionRequest ;
1014import com .sap .ai .sdk .grounding .model .DataRepository ;
15+ import com .sap .ai .sdk .grounding .model .DataRepositoryType ;
16+ import com .sap .ai .sdk .grounding .model .DocumentCreateRequest ;
17+ import com .sap .ai .sdk .grounding .model .DocumentKeyValueListPair ;
1118import com .sap .ai .sdk .grounding .model .DocumentWithoutChunks ;
19+ import com .sap .ai .sdk .grounding .model .EmbeddingConfig ;
20+ import com .sap .ai .sdk .grounding .model .KeyValueListPair ;
1221import com .sap .ai .sdk .grounding .model .Pipeline ;
22+ import com .sap .ai .sdk .grounding .model .ResultsInner1 ;
23+ import com .sap .ai .sdk .grounding .model .RetrievalSearchFilter ;
24+ import com .sap .ai .sdk .grounding .model .RetrievalSearchInput ;
25+ import com .sap .ai .sdk .grounding .model .SearchConfiguration ;
1326import com .sap .ai .sdk .grounding .model .TextOnlyBaseChunk ;
27+ import java .time .format .TextStyle ;
28+ import java .util .List ;
29+ import java .util .Locale ;
30+ import java .util .Map ;
1431import java .util .UUID ;
1532import javax .annotation .Nonnull ;
1633import javax .annotation .Nullable ;
@@ -31,7 +48,7 @@ class GroundingController {
3148 private static final PipelinesApi CLIENT_PIPELINES = GroundingClient .create ().pipelines ();
3249 private static final RetrievalApi CLIENT_RETRIEVAL = GroundingClient .create ().retrieval ();
3350 private static final VectorApi CLIENT_VECTOR = GroundingClient .create ().vector ();
34- private static final String RESOURCE_GROUP = "default " ;
51+ private static final String RESOURCE_GROUP = "ai-sdk-java-e2e " ;
3552
3653 /**
3754 * Stop all deployments with the Java specific configuration ID.
@@ -70,6 +87,30 @@ Object getAllRepositories(
7087 return "Found repositories with titles: " + titles ;
7188 }
7289
90+ /**
91+ * Delete all deployments with the Java specific configuration ID.
92+ *
93+ * <p>Only UNKNOWN and STOPPED deployments can be DELETED
94+ */
95+ @ GetMapping ("/retrieval/repositories" )
96+ Object searchInDocuments (
97+ @ Nullable @ RequestParam (value = "format" , required = false ) final String format ) {
98+ final var filter =
99+ RetrievalSearchFilter .create ()
100+ .id ("question" )
101+ .dataRepositoryType (DataRepositoryType .VECTOR )
102+ .dataRepositories (List .of ("*" ))
103+ .searchConfiguration (SearchConfiguration .create ().maxChunkCount (10 ));
104+ final var q = RetrievalSearchInput .create ().query ("When was the last upload?" ).filters (filter );
105+ final var results = CLIENT_RETRIEVAL .search (RESOURCE_GROUP , q );
106+
107+ if ("json" .equals (format )) {
108+ return results ;
109+ }
110+ final var messages = results .getResults ().stream ().map (ResultsInner1 ::getMessage ).toList ();
111+ return "Found the following response(s): " + messages ;
112+ }
113+
73114 /** Get all deployments with the Java specific configuration ID. */
74115 @ GetMapping ("/vector/collections" )
75116 Object getAllCollections (
@@ -96,6 +137,76 @@ Object getDocumentsByCollectionId(
96137 return "The following document ids are available: %s." .formatted (ids );
97138 }
98139
140+ /** Get all deployments, including non-Java specific deployments */
141+ @ GetMapping ("/vector/collection/create" )
142+ String createCollection (
143+ @ Nullable @ RequestParam (value = "format" , required = false ) final String format ) {
144+ final var embeddingConfig = EmbeddingConfig .create ().modelName (TEXT_EMBEDDING_ADA_002 .name ());
145+ final var request = CollectionRequest .create ().embeddingConfig (embeddingConfig ).title ("e2e" );
146+ final var documents = CLIENT_VECTOR .createCollection (RESOURCE_GROUP , request );
147+ final Map <String , List <String >> headers = documents .getHeaders ();
148+
149+ final var locationHeader = headers .get ("Location" ).get (0 );
150+ return locationHeader .replaceAll ("^.*?/([a-f0-9-]+)/.*?$" , "$1" );
151+ }
152+
153+ /** Get all deployments, including non-Java specific deployments */
154+ @ GetMapping ("/vector/collection/by-id/{id}/day" )
155+ Object createDocument (
156+ @ Nonnull @ PathVariable ("id" ) final UUID collectionId ,
157+ @ Nullable @ RequestParam (value = "format" , required = false ) final String format ) {
158+ final var dayOfWeek = now ().getDayOfWeek ().getDisplayName (TextStyle .FULL , Locale .ENGLISH );
159+ ;
160+ final var documentContent = "Last upload on " + dayOfWeek ;
161+
162+ final var chunkMeta = KeyValueListPair .create ().key ("context" ).value ("day-of-week" );
163+ final var chunk = TextOnlyBaseChunk .create ().content (documentContent ).metadata (chunkMeta );
164+ final var docMeta = DocumentKeyValueListPair .create ().key ("purpose" ).value ("testing" );
165+ final var doc = BaseDocument .create ().chunks (chunk ).metadata (docMeta );
166+ final var request = DocumentCreateRequest .create ().documents (doc );
167+ final var response = CLIENT_VECTOR .createDocuments (RESOURCE_GROUP , collectionId , request );
168+
169+ if ("json" .equals (format )) {
170+ return response ;
171+ }
172+ final var ids = response .getDocuments ().stream ().map (DocumentWithoutChunks ::getId ).toList ();
173+ return "The following document ids are available: %s." .formatted (ids );
174+ }
175+
176+ /** Get all deployments, including non-Java specific deployments */
177+ @ GetMapping ("/vector/collection/by-id/{id}/clear" )
178+ Object deleteDocuments (
179+ @ Nonnull @ PathVariable ("id" ) final UUID collectionId ,
180+ @ Nullable @ RequestParam (value = "format" , required = false ) final String format ) {
181+ final var dayOfWeek = now ().getDayOfWeek ().getDisplayName (TextStyle .FULL , Locale .ENGLISH );
182+ ;
183+ final var chunkMeta = KeyValueListPair .create ().key ("context" ).value ("day-of-week" );
184+ final var chunk =
185+ TextOnlyBaseChunk .create ().content ("Today is " + dayOfWeek ).metadata (chunkMeta );
186+ final var docMeta = DocumentKeyValueListPair .create ().key ("purpose" ).value ("testing" );
187+ final var doc = BaseDocument .create ().chunks (chunk ).metadata (docMeta );
188+ final var request = DocumentCreateRequest .create ().documents (doc );
189+
190+ final var documents = CLIENT_VECTOR .getAllDocuments (RESOURCE_GROUP , collectionId );
191+ final var ids = documents .getResources ().stream ().map (DocumentWithoutChunks ::getId ).toList ();
192+ log .info ("Deleting collection {} with {} documents: {}" , collectionId , ids .size (), ids );
193+
194+ for (UUID documentId : ids ) {
195+ final var del = CLIENT_VECTOR .deleteDocumentById (RESOURCE_GROUP , collectionId , documentId );
196+ if (del .getStatusCode () >= 400 ) {
197+ final var msg = "Document {} could not be deleted, status code [{}], headers: " ;
198+ log .error (msg , documentId , del .getStatusCode (), del .getHeaders ());
199+ throw new IllegalStateException ("Document deletion failed for id " + documentId );
200+ }
201+ }
202+ final var response = CLIENT_VECTOR .deleteCollectionById (RESOURCE_GROUP , collectionId + "" );
203+
204+ if ("json" .equals (format )) {
205+ return response ;
206+ }
207+ return response .getStatusCode () >= 400 ? "Failed to delete collection" : "Deletion successful" ;
208+ }
209+
99210 /** Get all deployments, including non-Java specific deployments */
100211 @ GetMapping ("/vector/collection/by-id/{collectionId}/document/by-id/{documentId}" )
101212 Object getDocumentChunksById (
0 commit comments