Skip to content

Commit 0f8ed88

Browse files
committed
Register new File converter and test
1 parent 31fc552 commit 0f8ed88

File tree

5 files changed

+156
-2
lines changed

5 files changed

+156
-2
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.sap.ai.sdk.prompt.registry;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.io.OutputStream;
7+
import java.nio.file.Files;
8+
import javax.annotation.Nonnull;
9+
import org.springframework.http.HttpInputMessage;
10+
import org.springframework.http.HttpOutputMessage;
11+
import org.springframework.http.MediaType;
12+
import org.springframework.http.converter.AbstractHttpMessageConverter;
13+
import org.springframework.http.converter.HttpMessageNotReadableException;
14+
import org.springframework.http.converter.HttpMessageNotWritableException;
15+
import org.springframework.util.StreamUtils;
16+
17+
class FileHttpMessageConverter extends AbstractHttpMessageConverter<File> {
18+
19+
FileHttpMessageConverter() {
20+
super(MediaType.APPLICATION_OCTET_STREAM);
21+
}
22+
23+
@Override
24+
protected boolean supports(@Nonnull final Class clazz) {
25+
return File.class == clazz;
26+
}
27+
28+
@Nonnull
29+
@Override
30+
protected File readInternal(
31+
@Nonnull final Class<? extends File> clazz, @Nonnull final HttpInputMessage inputMessage)
32+
throws IOException, HttpMessageNotReadableException {
33+
final var tempFile = File.createTempFile("tmp", ".bin");
34+
try (OutputStream out = Files.newOutputStream(tempFile.toPath())) {
35+
StreamUtils.copy(inputMessage.getBody(), out);
36+
}
37+
return tempFile;
38+
}
39+
40+
@Override
41+
protected void writeInternal(
42+
@Nonnull final File file, @Nonnull final HttpOutputMessage outputMessage)
43+
throws IOException, HttpMessageNotWritableException {
44+
try (InputStream in = Files.newInputStream(file.toPath())) {
45+
StreamUtils.copy(in, outputMessage.getBody());
46+
}
47+
}
48+
}

core-services/prompt-registry/src/main/java/com/sap/ai/sdk/prompt/registry/PromptClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ private static ApiClient addMixin(@Nonnull final AiCoreService service) {
6565
JacksonMixin.ResponseFormat.class)));
6666

6767
rt.setRequestFactory(new BufferingClientHttpRequestFactory(httpRequestFactory));
68-
68+
rt.getMessageConverters().add(new FileHttpMessageConverter());
6969
return new ApiClient(rt).setBasePath(destination.asHttp().getUri().toString());
7070
}
7171

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package com.sap.ai.sdk.prompt.registry;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.io.ByteArrayInputStream;
6+
import java.io.ByteArrayOutputStream;
7+
import java.io.File;
8+
import java.io.IOException;
9+
import java.io.InputStream;
10+
import java.io.OutputStream;
11+
import java.nio.file.Files;
12+
import java.nio.file.Path;
13+
import javax.annotation.Nonnull;
14+
import jdk.jfr.Description;
15+
import org.junit.jupiter.api.Test;
16+
import org.junit.jupiter.api.io.TempDir;
17+
import org.springframework.http.HttpHeaders;
18+
import org.springframework.http.HttpInputMessage;
19+
import org.springframework.http.HttpOutputMessage;
20+
21+
class FileHttpMessageConverterTest {
22+
23+
@Test
24+
void testSupports() {
25+
final var converter = new FileHttpMessageConverter();
26+
27+
assertThat(converter.supports(File.class)).isTrue();
28+
assertThat(converter.supports(String.class)).isFalse();
29+
}
30+
31+
@Test
32+
@Description("Test conversion from HttpInputMessage to File")
33+
void testReadInternal() throws IOException {
34+
final var converter = new FileHttpMessageConverter();
35+
final var messageContent = "Hello, World!".getBytes();
36+
37+
final var inputMessage =
38+
new HttpInputMessage() {
39+
@Nonnull
40+
@Override
41+
public InputStream getBody() {
42+
return new ByteArrayInputStream(messageContent);
43+
}
44+
45+
@Nonnull
46+
@Override
47+
public HttpHeaders getHeaders() {
48+
return new HttpHeaders();
49+
}
50+
};
51+
52+
final var generatedFile = converter.readInternal(File.class, inputMessage);
53+
try {
54+
assertThat(generatedFile).exists().isFile();
55+
assertThat(Files.readAllBytes(generatedFile.toPath())).isEqualTo(messageContent);
56+
} finally {
57+
Files.deleteIfExists(generatedFile.toPath());
58+
}
59+
}
60+
61+
@Test
62+
@Description("Test conversion from File to HttpOutputMessage")
63+
void testWriteInternal(@TempDir final Path tempDir) throws IOException {
64+
final var converter = new FileHttpMessageConverter();
65+
final var fileContent = "Hello, World!".getBytes();
66+
final var tempFilePath = tempDir.resolve("testFile.txt");
67+
Files.write(tempFilePath, fileContent);
68+
69+
final var outputStream = new ByteArrayOutputStream();
70+
final var outputMessage =
71+
new HttpOutputMessage() {
72+
73+
@Nonnull
74+
@Override
75+
public HttpHeaders getHeaders() {
76+
return new HttpHeaders();
77+
}
78+
79+
@Nonnull
80+
@Override
81+
public OutputStream getBody() {
82+
return outputStream;
83+
}
84+
};
85+
86+
converter.writeInternal(tempFilePath.toFile(), outputMessage);
87+
assertThat(outputStream.toByteArray()).isEqualTo(fileContent);
88+
}
89+
}

sample-code/spring-app/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,11 @@
232232
<artifactId>assertj-core</artifactId>
233233
<scope>test</scope>
234234
</dependency>
235+
<dependency>
236+
<groupId>com.fasterxml.jackson.dataformat</groupId>
237+
<artifactId>jackson-dataformat-yaml</artifactId>
238+
<scope>test</scope>
239+
</dependency>
235240
</dependencies>
236241

237242
<build>

sample-code/spring-app/src/test/java/com/sap/ai/sdk/app/controllers/PromptRegistryTest.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package com.sap.ai.sdk.app.controllers;
22

3+
import static java.nio.charset.StandardCharsets.UTF_8;
34
import static org.assertj.core.api.Assertions.assertThat;
45

6+
import com.fasterxml.jackson.databind.JsonNode;
7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
59
import com.sap.ai.sdk.prompt.registry.model.PromptTemplate;
610
import com.sap.ai.sdk.prompt.registry.model.PromptTemplateDeleteResponse;
711
import com.sap.ai.sdk.prompt.registry.model.PromptTemplateListResponse;
@@ -11,9 +15,12 @@
1115
import java.io.IOException;
1216
import java.util.List;
1317
import org.junit.jupiter.api.Test;
18+
import org.springframework.core.io.ClassPathResource;
1419

1520
public class PromptRegistryTest {
1621

22+
static final ObjectMapper YAML_MAPPER = new ObjectMapper(new YAMLFactory());
23+
1724
@Test
1825
void listTemplates() {
1926
var controller = new PromptRegistryController();
@@ -56,7 +63,12 @@ void importExportTemplate() throws IOException {
5663
PromptTemplatePostResponse template = controller.importTemplate();
5764
assertThat(template.getMessage()).contains("successful");
5865

59-
// export TODO: NOT WORKING
66+
// export
67+
final var exportedTemplate = controller.exportTemplate();
68+
69+
final var resource = new ClassPathResource("prompt-template.yaml");
70+
final JsonNode expectedYaml = YAML_MAPPER.readTree(resource.getContentAsString(UTF_8));
71+
assertThat(YAML_MAPPER.readTree(exportedTemplate)).isEqualTo(expectedYaml);
6072

6173
// cleanup
6274
List<PromptTemplateDeleteResponse> deletedTemplate = controller.deleteTemplate();

0 commit comments

Comments
 (0)