11package com .sap .ai .sdk .app .controllers ;
22
3+ import com .fasterxml .jackson .annotation .JsonAutoDetect ;
4+ import com .fasterxml .jackson .annotation .PropertyAccessor ;
5+ import com .fasterxml .jackson .core .JsonProcessingException ;
6+ import com .fasterxml .jackson .databind .ObjectMapper ;
7+ import com .fasterxml .jackson .datatype .jsr310 .JavaTimeModule ;
38import com .sap .ai .sdk .core .client .ConfigurationApi ;
49import com .sap .ai .sdk .core .client .DeploymentApi ;
510import com .sap .ai .sdk .core .model .AiConfigurationBaseData ;
1823import javax .annotation .Nonnull ;
1924import javax .annotation .Nullable ;
2025import lombok .extern .slf4j .Slf4j ;
26+ import org .springframework .http .MediaType ;
27+ import org .springframework .http .ResponseEntity ;
2128import org .springframework .web .bind .annotation .GetMapping ;
2229import org .springframework .web .bind .annotation .PathVariable ;
30+ import org .springframework .web .bind .annotation .RequestHeader ;
2331import org .springframework .web .bind .annotation .RequestMapping ;
2432import org .springframework .web .bind .annotation .RestController ;
2533
2634/** Endpoints for AI Core AiDeployment operations */
2735@ Slf4j
2836@ RestController
37+ @ SuppressWarnings ("unused" )
2938@ RequestMapping ("/deployments" )
3039class DeploymentController {
3140
3241 private static final DeploymentApi CLIENT = new DeploymentApi ();
3342 private static final String RESOURCE_GROUP = "default" ;
43+ private final ObjectMapper mapper =
44+ new ObjectMapper ().setVisibility (PropertyAccessor .FIELD , JsonAutoDetect .Visibility .ANY )
45+ .registerModule (new JavaTimeModule ());
3446
3547 /**
3648 * Create and delete a deployment with the Java specific configuration ID
3749 *
3850 * @param configId The configuration id.
3951 * @return the deployment deletion response
4052 */
41- @ GetMapping ("/by-config/{id}/createDelete" )
4253 @ Nullable
43- AiDeploymentDeletionResponse createAndDeleteDeploymentByConfigId (
44- @ Nonnull @ PathVariable ("id" ) final String configId ) {
54+ AiDeploymentDeletionResponse createAndDeleteDeploymentByConfigId (final String configId ) {
4555 final var deployment =
4656 CLIENT .create (
4757 RESOURCE_GROUP , AiDeploymentCreationRequest .create ().configurationId (configId ));
@@ -51,6 +61,20 @@ AiDeploymentDeletionResponse createAndDeleteDeploymentByConfigId(
5161 return CLIENT .delete (RESOURCE_GROUP , deployment .getId ());
5262 }
5363
64+ @ GetMapping ("/by-config/{id}/createDelete" )
65+ ResponseEntity <String > createAndDeleteDeploymentByConfigId (
66+ @ Nonnull @ PathVariable ("id" ) final String configId ,
67+ @ RequestHeader (value = "accept" , required = false ) final String accept )
68+ throws JsonProcessingException {
69+ final var response = createAndDeleteDeploymentByConfigId (configId );
70+ if ("application/json" .equals (accept )) {
71+ return ResponseEntity .ok ()
72+ .contentType (MediaType .APPLICATION_JSON )
73+ .body (mapper .writeValueAsString (response ));
74+ }
75+ return ResponseEntity .ok ("Deployment under config with id " + configId + " created and deleted." );
76+ }
77+
5478 /**
5579 * Stop all deployments with the Java specific configuration ID
5680 *
@@ -61,14 +85,14 @@ AiDeploymentDeletionResponse createAndDeleteDeploymentByConfigId(
6185 */
6286 @ GetMapping ("/by-config/{id}/stop" )
6387 @ Nonnull
64- @ SuppressWarnings ( "unused" ) // debug method that doesn't need to be tested
65- List < AiDeploymentModificationResponse > stopByConfigId (
66- @ Nonnull @ PathVariable ( "id" ) final String configId ) {
88+ ResponseEntity < String > stopByConfigId (
89+ @ Nonnull @ PathVariable ( "id" ) final String configId ,
90+ @ RequestHeader ( value = "accept" , required = false ) final String accept ) throws JsonProcessingException {
6791 final List <AiDeployment > myDeployments = getAllByConfigId (configId );
6892 log .info ("Found {} deployments to STOP" , myDeployments .size ());
6993
7094 // STOP my deployments
71- return myDeployments .stream ()
95+ var stoppedDeployments = myDeployments .stream ()
7296 .map (
7397 deployment ->
7498 CLIENT .modify (
@@ -77,6 +101,13 @@ List<AiDeploymentModificationResponse> stopByConfigId(
77101 AiDeploymentModificationRequest .create ()
78102 .targetStatus (AiDeploymentTargetStatus .STOPPED )))
79103 .toList ();
104+
105+ if ("application/json" .equals (accept )) {
106+ return ResponseEntity .ok ()
107+ .contentType (MediaType .APPLICATION_JSON )
108+ .body (mapper .writeValueAsString (stoppedDeployments ));
109+ }
110+ return ResponseEntity .ok ("Deployments under config with id " + configId + " stopped." );
80111 }
81112
82113 /**
@@ -89,16 +120,21 @@ List<AiDeploymentModificationResponse> stopByConfigId(
89120 */
90121 @ GetMapping ("/by-config/{id}/delete" )
91122 @ Nonnull
92- @ SuppressWarnings ("unused" ) // debug method that doesn't need to be tested
93- List <AiDeploymentDeletionResponse > deleteByConfigId (
94- @ Nonnull @ PathVariable ("id" ) final String configId ) {
123+ ResponseEntity <String > deleteByConfigId (
124+ @ Nonnull @ PathVariable ("id" ) final String configId , @ RequestHeader (value = "accept" , required = false ) final String accept ) throws JsonProcessingException {
95125 final List <AiDeployment > myDeployments = getAllByConfigId (configId );
96126 log .info ("Found {} deployments to DELETE" , myDeployments .size ());
97127
98128 // DELETE my deployments
99- return myDeployments .stream ()
129+ var responseList = myDeployments .stream ()
100130 .map (deployment -> CLIENT .delete (RESOURCE_GROUP , deployment .getId ()))
101131 .toList ();
132+ if ("application/json" .equals (accept )) {
133+ return ResponseEntity .ok ()
134+ .contentType (MediaType .APPLICATION_JSON )
135+ .body (mapper .writeValueAsString (responseList ));
136+ }
137+ return ResponseEntity .ok ("Deployments under config with id " + configId + " deleted." );
102138 }
103139
104140 /**
@@ -108,6 +144,29 @@ List<AiDeploymentDeletionResponse> deleteByConfigId(
108144 * @return the Java specific deployments
109145 */
110146 @ GetMapping ("/by-config/{id}/getAll" )
147+ ResponseEntity <String > getAllByConfigId (
148+ @ Nonnull @ PathVariable ("id" ) final String configId ,
149+ @ RequestHeader (value = "accept" , required = false ) final String accept )
150+ throws JsonProcessingException {
151+ final var deployments = getAllByConfigId (configId );
152+ if ("application/json" .equals (accept )) {
153+ return ResponseEntity .ok ()
154+ .contentType (MediaType .APPLICATION_JSON )
155+ .body (mapper .writeValueAsString (deployments ));
156+ }
157+ return ResponseEntity .ok (buildMessage (deployments ));
158+ }
159+
160+ private String buildMessage (List <AiDeployment > deployments ) {
161+ var message = new StringBuilder ("The following deployments are available: " );
162+ for (var deployment : deployments ) {
163+ message .append (deployment .getId ()).append (", " );
164+ }
165+ message .setCharAt (message .length () - 2 , '.' );
166+ return message .toString ();
167+ }
168+
169+
111170 @ Nonnull
112171 List <AiDeployment > getAllByConfigId (@ Nonnull @ PathVariable ("id" ) final String configId ) {
113172 final AiDeploymentList deploymentList = CLIENT .query (RESOURCE_GROUP );
@@ -123,6 +182,19 @@ List<AiDeployment> getAllByConfigId(@Nonnull @PathVariable("id") final String co
123182 * @return the Java specific deployments
124183 */
125184 @ GetMapping ("/getAll" )
185+ @ Nonnull
186+ ResponseEntity <String > getAll (
187+ @ RequestHeader (value = "accept" , required = false ) final String accept )
188+ throws JsonProcessingException {
189+ final var deployments = getAll ();
190+ if ("application/json" .equals (accept )) {
191+ return ResponseEntity .ok ()
192+ .contentType (MediaType .APPLICATION_JSON )
193+ .body (mapper .writeValueAsString (deployments ));
194+ }
195+ return ResponseEntity .ok (buildMessage (deployments .getResources ().stream ().toList ()));
196+ }
197+
126198 @ Nullable
127199 AiDeploymentList getAll () {
128200 return CLIENT .query (RESOURCE_GROUP );
0 commit comments