Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core-services/prompt-registry/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,11 @@
<inputSpec>${project.basedir}/src/main/resources/spec/prompt-registry.yaml</inputSpec>
<apiPackage>com.sap.ai.sdk.prompt.registry.client</apiPackage>
<modelPackage>com.sap.ai.sdk.prompt.registry.model</modelPackage>
<typeMappings>
<typeMapping>File=byte[]</typeMapping>
</typeMappings>
<additionalProperties>
<useAbstractionForFiles>true</useAbstractionForFiles>
<pojoBuilderMethodName>create</pojoBuilderMethodName>
<pojoBuildMethodName/>
<pojoConstructorVisibility>protected</pojoConstructorVisibility>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@
import com.sap.cloud.sdk.services.openapi.apiclient.ApiClient;
import com.sap.cloud.sdk.services.openapi.core.AbstractOpenApiService;
import com.sap.cloud.sdk.services.openapi.core.OpenApiRequestException;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
Expand Down Expand Up @@ -238,11 +236,11 @@ public OrchestrationConfigDeleteResponse deleteOrchestrationConfig(
*
* @param orchestrationConfigId (required) The value for the parameter orchestrationConfigId
* @param aiResourceGroup (optional) Specify a resource group id to use
* @return File
* @return byte[]
* @throws OpenApiRequestException if an error occurs while attempting to invoke the API
*/
@Nonnull
public File exportOrchestrationConfig(
public byte[] exportOrchestrationConfig(
Copy link
Contributor

@newtork newtork Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Comment)

After discussion we aligned on byte[] to be used over File.
Because the latter would require life-cycle handling, i.e. deletion after usage.

@Nonnull final UUID orchestrationConfigId, @Nullable final String aiResourceGroup)
throws OpenApiRequestException {
final Object localVarPostBody = null;
Expand Down Expand Up @@ -278,8 +276,8 @@ public File exportOrchestrationConfig(

final String[] localVarAuthNames = new String[] {};

final ParameterizedTypeReference<File> localVarReturnType =
new ParameterizedTypeReference<File>() {};
final ParameterizedTypeReference<byte[]> localVarReturnType =
new ParameterizedTypeReference<byte[]>() {};
return apiClient.invokeAPI(
localVarPath,
HttpMethod.GET,
Expand All @@ -303,11 +301,11 @@ public File exportOrchestrationConfig(
* <p><b>0</b> - Common Error
*
* @param orchestrationConfigId The value for the parameter orchestrationConfigId
* @return File
* @return byte[]
* @throws OpenApiRequestException if an error occurs while attempting to invoke the API
*/
@Nonnull
public File exportOrchestrationConfig(@Nonnull final UUID orchestrationConfigId)
public byte[] exportOrchestrationConfig(@Nonnull final UUID orchestrationConfigId)
throws OpenApiRequestException {
return exportOrchestrationConfig(orchestrationConfigId, null);
}
Expand Down Expand Up @@ -423,7 +421,8 @@ public OrchestrationConfigGetResponse getOrchestrationConfigByUuid(
*/
@Nonnull
public OrchestrationConfigPostResponse importOrchestrationConfig(
@Nullable final String aiResourceGroup, @Nullable final File _file)
@Nullable final String aiResourceGroup,
@Nullable final org.springframework.core.io.Resource _file)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Comment)

Usage of org.springframework.core.io.Resource was a compromise. In the future we may find a way to offer File or byte[] as argument without compilation to fail. Since this is generated code we do not offer hard API contract. The argument type here may be affected by breaking changes in the future - e.g. when migrating away from RestTemplate / Spring classes.

throws OpenApiRequestException {
final Object localVarPostBody = null;

Expand All @@ -441,7 +440,7 @@ public OrchestrationConfigPostResponse importOrchestrationConfig(
if (aiResourceGroup != null)
localVarHeaderParams.add("AI-Resource-Group", apiClient.parameterToString(aiResourceGroup));

if (_file != null) localVarFormParams.add("file", new FileSystemResource(_file));
if (_file != null) localVarFormParams.add("file", _file);

final String[] localVarAccepts = {"application/json"};
final List<MediaType> localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@
import com.sap.cloud.sdk.services.openapi.apiclient.ApiClient;
import com.sap.cloud.sdk.services.openapi.core.AbstractOpenApiService;
import com.sap.cloud.sdk.services.openapi.core.OpenApiRequestException;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
Expand Down Expand Up @@ -251,11 +249,11 @@ public PromptTemplateDeleteResponse deletePromptTemplate(@Nonnull final UUID pro
* @param promptTemplateId (required) The value for the parameter promptTemplateId
* @param aiResourceGroup (optional) Specify a resource group id to use
* @param aiResourceGroupScope (optional) Specify whether the resource group scope is to be used
* @return File
* @return byte[]
* @throws OpenApiRequestException if an error occurs while attempting to invoke the API
*/
@Nonnull
public File exportPromptTemplate(
public byte[] exportPromptTemplate(
@Nonnull final UUID promptTemplateId,
@Nullable final String aiResourceGroup,
@Nullable final String aiResourceGroupScope)
Expand Down Expand Up @@ -295,8 +293,8 @@ public File exportPromptTemplate(

final String[] localVarAuthNames = new String[] {};

final ParameterizedTypeReference<File> localVarReturnType =
new ParameterizedTypeReference<File>() {};
final ParameterizedTypeReference<byte[]> localVarReturnType =
new ParameterizedTypeReference<byte[]>() {};
return apiClient.invokeAPI(
localVarPath,
HttpMethod.GET,
Expand All @@ -320,11 +318,11 @@ public File exportPromptTemplate(
* <p><b>0</b> - Common Error
*
* @param promptTemplateId The value for the parameter promptTemplateId
* @return File
* @return byte[]
* @throws OpenApiRequestException if an error occurs while attempting to invoke the API
*/
@Nonnull
public File exportPromptTemplate(@Nonnull final UUID promptTemplateId)
public byte[] exportPromptTemplate(@Nonnull final UUID promptTemplateId)
throws OpenApiRequestException {
return exportPromptTemplate(promptTemplateId, null, null);
}
Expand Down Expand Up @@ -442,7 +440,7 @@ public PromptTemplateGetResponse getPromptTemplateByUuid(@Nonnull final UUID pro
public PromptTemplatePostResponse importPromptTemplate(
@Nullable final String aiResourceGroup,
@Nullable final String aiResourceGroupScope,
@Nullable final File _file)
@Nullable final org.springframework.core.io.Resource _file)
throws OpenApiRequestException {
final Object localVarPostBody = null;

Expand All @@ -461,7 +459,7 @@ public PromptTemplatePostResponse importPromptTemplate(
localVarHeaderParams.add(
"AI-Resource-Group-Scope", apiClient.parameterToString(aiResourceGroupScope));

if (_file != null) localVarFormParams.add("file", new FileSystemResource(_file));
if (_file != null) localVarFormParams.add("file", _file);

final String[] localVarAccepts = {"application/json"};
final List<MediaType> localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
Expand Down
5 changes: 5 additions & 0 deletions sample-code/spring-app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,11 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import com.sap.ai.sdk.prompt.registry.model.PromptTemplateSubstitutionResponse;
import com.sap.ai.sdk.prompt.registry.model.SingleChatTemplate;
import com.sap.ai.sdk.prompt.registry.spring.SpringAiConverter;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -82,11 +81,11 @@ PromptTemplateListResponse history() {
@GetMapping("/importTemplate")
PromptTemplatePostResponse importTemplate() throws IOException {
final Resource template = new ClassPathResource("prompt-template.yaml");
return client.importPromptTemplate("default", null, template.getFile());
return client.importPromptTemplate("default", null, template);
}

@GetMapping("/exportTemplate")
File exportTemplate() throws IOException {
byte[] exportTemplate() throws IOException {
final var template = importTemplate();
return client.exportPromptTemplate(template.getId());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static org.assertj.core.api.Assertions.assertThat;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.sap.ai.sdk.prompt.registry.model.PromptTemplate;
import com.sap.ai.sdk.prompt.registry.model.PromptTemplateDeleteResponse;
import com.sap.ai.sdk.prompt.registry.model.PromptTemplateListResponse;
Expand All @@ -11,9 +13,12 @@
import java.io.IOException;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.core.io.ClassPathResource;

public class PromptRegistryTest {

static final ObjectMapper YAML_MAPPER = new ObjectMapper(new YAMLFactory());

@Test
void listTemplates() {
var controller = new PromptRegistryController();
Expand Down Expand Up @@ -53,10 +58,15 @@ void importExportTemplate() throws IOException {
controller.deleteTemplate();

// import
PromptTemplatePostResponse template = controller.importTemplate();
assertThat(template.getMessage()).contains("successful");
var importResult = controller.importTemplate();
assertThat(importResult.getMessage()).contains("successful");

// export
var exportedTemplate = controller.exportTemplate();

// export TODO: NOT WORKING
var importedTemplate = new ClassPathResource("prompt-template.yaml");
var expectedYaml = YAML_MAPPER.readTree(importedTemplate.getContentAsByteArray());
assertThat(YAML_MAPPER.readTree(exportedTemplate)).isEqualTo(expectedYaml);

// cleanup
List<PromptTemplateDeleteResponse> deletedTemplate = controller.deleteTemplate();
Expand Down
Loading