From 228ef10bfbfe279d7d09f2a7ba166db873372118 Mon Sep 17 00:00:00 2001 From: Ilayaperumal Gopinathan Date: Mon, 5 May 2025 01:38:00 +0100 Subject: [PATCH] Remove deprecated methods from Media - Remove deprecated constructor method Media(MimeType mimeType, URL url) from Media - Remove deprecated builder method data(URL url) from Media builder - Update references to use the builder and the data(URI) methods Signed-off-by: Ilayaperumal Gopinathan --- .../Neo4jChatMemoryAutoConfigurationIT.java | 2 +- .../ai/chat/memory/neo4j/Neo4jChatMemory.java | 8 +- .../ai/mistralai/MistralAiChatModelIT.java | 8 +- .../openai/chat/MessageTypeContentTests.java | 4 +- .../ai/openai/chat/OpenAiChatModelIT.java | 18 +-- .../chat/proxy/GroqWithOpenAiChatModelIT.java | 6 +- .../proxy/MistralWithOpenAiChatModelIT.java | 3 +- .../proxy/OllamaWithOpenAiChatModelIT.java | 3 +- .../VertexAiMultimodalEmbeddingModelIT.java | 2 +- .../ai/chat/client/DefaultChatClient.java | 8 +- .../chat/client/DefaultChatClientTests.java | 6 +- .../org/springframework/ai/content/Media.java | 31 ----- .../ai/document/DocumentBuilderTests.java | 17 +-- .../ai/document/DocumentTests.java | 10 +- .../springframework/ai/model/MediaTests.java | 115 +++--------------- 15 files changed, 59 insertions(+), 182 deletions(-) diff --git a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/test/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryAutoConfigurationIT.java b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/test/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryAutoConfigurationIT.java index 1a9705442..7a4448784 100644 --- a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/test/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryAutoConfigurationIT.java +++ b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/test/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryAutoConfigurationIT.java @@ -100,7 +100,7 @@ class Neo4jChatMemoryAutoConfigurationIT { .mimeType(textPlain) .data("hello".getBytes(StandardCharsets.UTF_8)) .build(), - Media.builder().data(URI.create("http://www.google.com").toURL()).mimeType(textPlain).build()); + Media.builder().data(URI.create("http://www.google.com")).mimeType(textPlain).build()); UserMessage userMessageWithMedia = UserMessage.builder().text("Message with media").media(media).build(); memory.add(sessionId, userMessageWithMedia); diff --git a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/Neo4jChatMemory.java b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/Neo4jChatMemory.java index 4a9fd7250..a2f140ad8 100644 --- a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/Neo4jChatMemory.java +++ b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/Neo4jChatMemory.java @@ -16,7 +16,6 @@ package org.springframework.ai.chat.memory.neo4j; -import java.net.MalformedURLException; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; @@ -282,12 +281,7 @@ public class Neo4jChatMemory implements ChatMemory { .id(Optional.ofNullable(mediaMap.get(MediaAttributes.ID.getValue())).map(Object::toString).orElse(null)) .mimeType(MimeType.valueOf(mediaMap.get(MediaAttributes.MIME_TYPE.getValue()).toString())); if (mediaMap.get(MediaAttributes.DATA.getValue()) instanceof String stringData) { - try { - mediaBuilder.data(URI.create(stringData).toURL()); - } - catch (MalformedURLException e) { - throw new IllegalArgumentException("Media data contains an invalid URL"); - } + mediaBuilder.data(URI.create(stringData)); } else if (mediaMap.get(MediaAttributes.DATA.getValue()).getClass().isArray()) { mediaBuilder.data(mediaMap.get(MediaAttributes.DATA.getValue())); diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatModelIT.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatModelIT.java index b3e2876f7..065696573 100644 --- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatModelIT.java +++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatModelIT.java @@ -17,7 +17,7 @@ package org.springframework.ai.mistralai; import java.io.IOException; -import java.net.URL; +import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -35,9 +35,9 @@ import reactor.core.publisher.Flux; import org.springframework.ai.chat.memory.ChatMemory; import org.springframework.ai.chat.memory.MessageWindowChatMemory; -import org.springframework.ai.chat.messages.SystemMessage; import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.messages.Message; +import org.springframework.ai.chat.messages.SystemMessage; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.chat.model.ChatResponse; @@ -296,7 +296,7 @@ class MistralAiChatModelIT { .text("Explain what do you see on this picture?") .media(List.of(Media.builder() .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .data(URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) .build())) .build(); @@ -314,7 +314,7 @@ class MistralAiChatModelIT { .text("Explain what do you see on this picture?") .media(List.of(Media.builder() .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .data(URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) .build())) .build(); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/MessageTypeContentTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/MessageTypeContentTests.java index 5a0968a49..df4a6fa8b 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/MessageTypeContentTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/MessageTypeContentTests.java @@ -127,10 +127,10 @@ public class MessageTypeContentTests { given(this.openAiApi.chatCompletionEntity(this.pomptCaptor.capture(), this.headersCaptor.capture())) .willReturn(Mockito.mock(ResponseEntity.class)); - URL mediaUrl = new URL("http://test"); + URI mediaUri = URI.create("http://test"); this.chatModel.call(new Prompt(List.of(UserMessage.builder() .text("test message") - .media(List.of(Media.builder().mimeType(MimeTypeUtils.IMAGE_JPEG).data(mediaUrl).build())) + .media(List.of(Media.builder().mimeType(MimeTypeUtils.IMAGE_JPEG).data(mediaUri).build())) .build()))); validateComplexContent(this.pomptCaptor.getValue()); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelIT.java index 37de20d9f..4c6fe05e8 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelIT.java @@ -17,7 +17,7 @@ package org.springframework.ai.openai.chat; import java.io.IOException; -import java.net.URL; +import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -49,12 +49,6 @@ import org.springframework.ai.chat.metadata.EmptyUsage; import org.springframework.ai.chat.metadata.Usage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.model.Generation; -import org.springframework.ai.model.tool.DefaultToolCallingManager; -import org.springframework.ai.model.tool.ToolCallingChatOptions; -import org.springframework.ai.model.tool.ToolCallingManager; -import org.springframework.ai.model.tool.ToolExecutionResult; -import org.springframework.ai.tool.ToolCallbacks; -import org.springframework.ai.tool.annotation.Tool; import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; @@ -63,6 +57,10 @@ import org.springframework.ai.content.Media; import org.springframework.ai.converter.BeanOutputConverter; import org.springframework.ai.converter.ListOutputConverter; import org.springframework.ai.converter.MapOutputConverter; +import org.springframework.ai.model.tool.DefaultToolCallingManager; +import org.springframework.ai.model.tool.ToolCallingChatOptions; +import org.springframework.ai.model.tool.ToolCallingManager; +import org.springframework.ai.model.tool.ToolExecutionResult; import org.springframework.ai.openai.OpenAiChatOptions; import org.springframework.ai.openai.OpenAiTestConfiguration; import org.springframework.ai.openai.api.OpenAiApi; @@ -71,6 +69,8 @@ import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.AudioPa import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.AudioParameters.Voice; import org.springframework.ai.openai.api.tool.MockWeatherService; import org.springframework.ai.openai.testutils.AbstractIT; +import org.springframework.ai.tool.ToolCallbacks; +import org.springframework.ai.tool.annotation.Tool; import org.springframework.ai.tool.function.FunctionToolCallback; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; @@ -491,7 +491,7 @@ public class OpenAiChatModelIT extends AbstractIT { .text("Explain what do you see on this picture?") .media(List.of(Media.builder() .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .data(URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) .build())) .build(); @@ -510,7 +510,7 @@ public class OpenAiChatModelIT extends AbstractIT { .text("Explain what do you see on this picture?") .media(List.of(Media.builder() .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .data(URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) .build())) .build(); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/GroqWithOpenAiChatModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/GroqWithOpenAiChatModelIT.java index ab2a1381d..cbff7f6cb 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/GroqWithOpenAiChatModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/GroqWithOpenAiChatModelIT.java @@ -17,7 +17,7 @@ package org.springframework.ai.openai.chat.proxy; import java.io.IOException; -import java.net.URL; +import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -334,7 +334,7 @@ class GroqWithOpenAiChatModelIT { .text("Explain what do you see on this picture?") .media(List.of(Media.builder() .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .data(URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) .build())) .build(); @@ -354,7 +354,7 @@ class GroqWithOpenAiChatModelIT { .text("Explain what do you see on this picture?") .media(List.of(Media.builder() .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .data(URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) .build())) .build(); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/MistralWithOpenAiChatModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/MistralWithOpenAiChatModelIT.java index 8ae57033d..95dc82ac3 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/MistralWithOpenAiChatModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/MistralWithOpenAiChatModelIT.java @@ -18,7 +18,6 @@ package org.springframework.ai.openai.chat.proxy; import java.io.IOException; import java.net.URI; -import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -341,7 +340,7 @@ class MistralWithOpenAiChatModelIT { .text("Explain what do you see on this picture?") .media(List.of(Media.builder() .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .data(URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) .build())) .build(); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/OllamaWithOpenAiChatModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/OllamaWithOpenAiChatModelIT.java index 7f3697dc5..1b0204dfb 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/OllamaWithOpenAiChatModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/OllamaWithOpenAiChatModelIT.java @@ -18,7 +18,6 @@ package org.springframework.ai.openai.chat.proxy; import java.io.IOException; import java.net.URI; -import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -385,7 +384,7 @@ class OllamaWithOpenAiChatModelIT { .text("Explain what do you see on this picture?") .media(List.of(Media.builder() .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .data(URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) .build())) .build(); diff --git a/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModelIT.java b/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModelIT.java index 09fa47676..b38fbc963 100644 --- a/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModelIT.java +++ b/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModelIT.java @@ -114,7 +114,7 @@ class VertexAiMultimodalEmbeddingModelIT { var document = Document.builder() .media(Media.builder() .mimeType(MimeTypeUtils.TEXT_PLAIN) - .data(URI.create("http://example.com/image.png").toURL()) + .data(URI.create("http://example.com/image.png")) .build()) .build(); diff --git a/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java b/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java index 2b6753281..d5a5f2de6 100644 --- a/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java +++ b/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java @@ -17,6 +17,7 @@ package org.springframework.ai.chat.client; import java.io.IOException; +import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.Charset; import java.util.ArrayList; @@ -202,7 +203,12 @@ public class DefaultChatClient implements ChatClient { public PromptUserSpec media(MimeType mimeType, URL url) { Assert.notNull(mimeType, "mimeType cannot be null"); Assert.notNull(url, "url cannot be null"); - this.media.add(Media.builder().mimeType(mimeType).data(url).build()); + try { + this.media.add(Media.builder().mimeType(mimeType).data(url.toURI()).build()); + } + catch (URISyntaxException e) { + throw new RuntimeException(e); + } return this; } diff --git a/spring-ai-client-chat/src/test/java/org/springframework/ai/chat/client/DefaultChatClientTests.java b/spring-ai-client-chat/src/test/java/org/springframework/ai/chat/client/DefaultChatClientTests.java index 30b0199e2..fd795971a 100644 --- a/spring-ai-client-chat/src/test/java/org/springframework/ai/chat/client/DefaultChatClientTests.java +++ b/spring-ai-client-chat/src/test/java/org/springframework/ai/chat/client/DefaultChatClientTests.java @@ -169,12 +169,12 @@ class DefaultChatClientTests { @Test void whenUserMediaThenReturn() throws MalformedURLException { DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); - URL mediaUrl = URI.create("http://example.com/image.png").toURL(); + URI mediaUri = URI.create("http://example.com/image.png"); spec = (DefaultChatClient.DefaultPromptUserSpec) spec - .media(Media.builder().mimeType(MimeTypeUtils.IMAGE_PNG).data(mediaUrl).build()); + .media(Media.builder().mimeType(MimeTypeUtils.IMAGE_PNG).data(mediaUri).build()); assertThat(spec.media()).hasSize(1); assertThat(spec.media().get(0).getMimeType()).isEqualTo(MimeTypeUtils.IMAGE_PNG); - assertThat(spec.media().get(0).getData()).isEqualTo(mediaUrl.toString()); + assertThat(spec.media().get(0).getData()).isEqualTo(mediaUri.toString()); } @Test diff --git a/spring-ai-commons/src/main/java/org/springframework/ai/content/Media.java b/spring-ai-commons/src/main/java/org/springframework/ai/content/Media.java index 50094592c..ea8956596 100644 --- a/spring-ai-commons/src/main/java/org/springframework/ai/content/Media.java +++ b/spring-ai-commons/src/main/java/org/springframework/ai/content/Media.java @@ -18,7 +18,6 @@ package org.springframework.ai.content; import java.io.IOException; import java.net.URI; -import java.net.URL; import org.springframework.core.io.Resource; import org.springframework.lang.Nullable; @@ -116,22 +115,6 @@ public class Media { this.name = generateDefaultName(mimeType); } - /** - * Create a new Media instance. - * @param mimeType the media MIME type - * @param url the URL for the media data - * @deprecated in favour of {@link #Media(MimeType, URI)} - */ - @Deprecated - public Media(MimeType mimeType, URL url) { - Assert.notNull(mimeType, "MimeType must not be null"); - Assert.notNull(url, "URL must not be null"); - this.mimeType = mimeType; - this.id = null; - this.data = url.toString(); - this.name = generateDefaultName(mimeType); - } - /** * Create a new Media instance. * @param mimeType the media MIME type @@ -291,20 +274,6 @@ public class Media { return this; } - /** - * Sets the media data from a URL. - * @param url the media URL, must not be null - * @return the builder instance - * @throws IllegalArgumentException if url is null - * @deprecated in favour of {@link #data(URI)} - */ - @Deprecated - public Builder data(URL url) { - Assert.notNull(url, "URL must not be null"); - this.data = url.toString(); - return this; - } - /** * Sets the ID for the media object. The ID is typically assigned by AI models * when they return a reference to previously provided media content. diff --git a/spring-ai-commons/src/test/java/org/springframework/ai/document/DocumentBuilderTests.java b/spring-ai-commons/src/test/java/org/springframework/ai/document/DocumentBuilderTests.java index 443db9bf8..cf8adaf5c 100644 --- a/spring-ai-commons/src/test/java/org/springframework/ai/document/DocumentBuilderTests.java +++ b/spring-ai-commons/src/test/java/org/springframework/ai/document/DocumentBuilderTests.java @@ -16,8 +16,7 @@ package org.springframework.ai.document; -import java.net.MalformedURLException; -import java.net.URL; +import java.net.URI; import java.util.HashMap; import java.util.Map; @@ -36,14 +35,7 @@ public class DocumentBuilderTests { private Document.Builder builder; private static Media getMedia() { - try { - URL mediaUrl1 = new URL("http://type1"); - Media media1 = new Media(MimeTypeUtils.IMAGE_JPEG, mediaUrl1); - return media1; - } - catch (MalformedURLException e) { - throw new RuntimeException(e); - } + return Media.builder().data(URI.create("http://type1")).mimeType(MimeTypeUtils.IMAGE_JPEG).build(); } @BeforeEach @@ -97,9 +89,8 @@ public class DocumentBuilderTests { } @Test - void testWithMediaSingle() throws MalformedURLException { - URL mediaUrl = new URL("http://test"); - Media media = Media.builder().mimeType(MimeTypeUtils.IMAGE_JPEG).data(mediaUrl).build(); + void testWithMediaSingle() { + Media media = Media.builder().mimeType(MimeTypeUtils.IMAGE_JPEG).data(URI.create("http://test")).build(); Document.Builder result = this.builder.media(media); diff --git a/spring-ai-commons/src/test/java/org/springframework/ai/document/DocumentTests.java b/spring-ai-commons/src/test/java/org/springframework/ai/document/DocumentTests.java index da89fc451..44fc2be54 100644 --- a/spring-ai-commons/src/test/java/org/springframework/ai/document/DocumentTests.java +++ b/spring-ai-commons/src/test/java/org/springframework/ai/document/DocumentTests.java @@ -17,6 +17,7 @@ package org.springframework.ai.document; import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; import java.util.HashMap; import java.util.Map; @@ -211,14 +212,7 @@ public class DocumentTests { } private static Media getMedia() { - try { - URL mediaUrl1 = new URL("http://type1"); - Media media1 = new Media(MimeTypeUtils.IMAGE_JPEG, mediaUrl1); - return media1; - } - catch (MalformedURLException e) { - throw new RuntimeException(e); - } + return Media.builder().mimeType(MimeTypeUtils.IMAGE_JPEG).data(URI.create("http://type1")).build(); } } diff --git a/spring-ai-model/src/test/java/org/springframework/ai/model/MediaTests.java b/spring-ai-model/src/test/java/org/springframework/ai/model/MediaTests.java index 79576f239..51da9cec7 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/model/MediaTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/model/MediaTests.java @@ -19,7 +19,6 @@ package org.springframework.ai.model; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; -import java.net.URL; import java.util.UUID; import org.junit.jupiter.api.Test; @@ -67,17 +66,17 @@ class MediaTests { } @Test - void testMediaBuilderWithURL() throws MalformedURLException { + void testMediaBuilderWithURI() throws MalformedURLException { MimeType mimeType = MimeType.valueOf("image/png"); - URL url = new URL("http://example.com/image.png"); + URI uri = URI.create("http://example.com/image.png"); String id = "123"; String name = "test-media"; - Media media = Media.builder().mimeType(mimeType).data(url).id(id).name(name).build(); + Media media = Media.builder().mimeType(mimeType).data(uri).id(id).name(name).build(); assertThat(media.getMimeType()).isEqualTo(mimeType); assertThat(media.getData()).isInstanceOf(String.class); - assertThat(media.getData()).isEqualTo(url.toString()); + assertThat(media.getData()).isEqualTo(uri.toString()); assertThat(media.getId()).isEqualTo(id); assertThat(media.getName()).isEqualTo(name); } @@ -116,10 +115,10 @@ class MediaTests { } @Test - void testMediaBuilderWithNullURL() { - assertThatThrownBy(() -> Media.builder().mimeType(MimeType.valueOf("image/png")).data((URL) null).build()) + void testMediaBuilderWithNullURI() { + assertThatThrownBy(() -> Media.builder().mimeType(MimeType.valueOf("image/png")).data((URI) null).build()) .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("URL must not be null"); + .hasMessageContaining("URI must not be null"); } @Test @@ -177,11 +176,11 @@ class MediaTests { } @Test - void testLastDataMethodWins() throws MalformedURLException { - URL url = new URL("http://example.com/image.png"); + void testLastDataMethodWins() { + URI uri = URI.create("http://example.com/image.png"); byte[] bytes = new byte[] { 1, 2, 3 }; - Media media = Media.builder().mimeType(Media.Format.IMAGE_PNG).data(url).data(bytes).build(); + Media media = Media.builder().mimeType(Media.Format.IMAGE_PNG).data(uri).data(bytes).build(); assertThat(media.getData()).isSameAs(bytes); } @@ -203,13 +202,13 @@ class MediaTests { @Test void testMediaConstructorWithUrl() throws MalformedURLException { MimeType mimeType = MimeType.valueOf("image/png"); - URL url = new URL("http://example.com/image.png"); + String url = "http://example.com/image.png"; - Media media = new Media(mimeType, url); + Media media = Media.builder().mimeType(mimeType).data(URI.create(url)).build(); assertThat(media.getMimeType()).isEqualTo(mimeType); assertThat(media.getData()).isInstanceOf(String.class); - assertThat(media.getData()).isEqualTo(url.toString()); + assertThat(media.getData()).isEqualTo(url); assertThat(media.getId()).isNull(); String name = media.getName(); assertValidMediaName(media.getName(), "png"); @@ -292,81 +291,6 @@ class MediaTests { .hasCauseInstanceOf(IOException.class); } - /// Tests to ensure two arg ctors behave identically to the builder - - @Test - void testUriConstructorMatchesBuilder() { - // Given - MimeType mimeType = MimeType.valueOf("image/png"); - URI uri = URI.create("http://example.com/image.png"); - - // When - Media mediaFromCtor = new Media(mimeType, uri); - Media mediaFromBuilder = Media.builder().mimeType(mimeType).data(uri).build(); - - // Then - verify all properties match - assertThat(mediaFromCtor.getMimeType()).isEqualTo(mediaFromBuilder.getMimeType()); - assertThat(mediaFromCtor.getData()).isEqualTo(mediaFromBuilder.getData()); - assertThat(mediaFromCtor.getId()).isEqualTo(mediaFromBuilder.getId()); - - // Verify name structure for both instances - assertValidMediaName(mediaFromCtor.getName(), "png"); - assertValidMediaName(mediaFromBuilder.getName(), "png"); - - // Data type consistency - assertThat(mediaFromCtor.getData()).isInstanceOf(String.class); - assertThat(mediaFromBuilder.getData()).isInstanceOf(String.class); - } - - @Test - void testURLConstructorMatchesBuilder() throws MalformedURLException { - // Given - MimeType mimeType = MimeType.valueOf("image/png"); - URL url = new URL("http://example.com/image.png"); - - // When - Media mediaFromCtor = new Media(mimeType, url); - Media mediaFromBuilder = Media.builder().mimeType(mimeType).data(url).build(); - - // Then - verify all properties match - assertThat(mediaFromCtor.getMimeType()).isEqualTo(mediaFromBuilder.getMimeType()); - assertThat(mediaFromCtor.getData()).isEqualTo(mediaFromBuilder.getData()); - assertThat(mediaFromCtor.getId()).isEqualTo(mediaFromBuilder.getId()); - - // Verify name structure for both instances - assertValidMediaName(mediaFromCtor.getName(), "png"); - assertValidMediaName(mediaFromBuilder.getName(), "png"); - - // Data type consistency - assertThat(mediaFromCtor.getData()).isInstanceOf(String.class); - assertThat(mediaFromBuilder.getData()).isInstanceOf(String.class); - } - - @Test - void testResourceConstructorMatchesBuilder() throws IOException { - // Given - MimeType mimeType = MimeType.valueOf("image/png"); - byte[] content = new byte[] { 1, 2, 3, 4, 5 }; - Resource resource = new ByteArrayResource(content); - - // When - Media mediaFromCtor = new Media(mimeType, resource); - Media mediaFromBuilder = Media.builder().mimeType(mimeType).data(resource).build(); - - // Then - verify all properties match - assertThat(mediaFromCtor.getMimeType()).isEqualTo(mediaFromBuilder.getMimeType()); - assertThat(mediaFromCtor.getDataAsByteArray()).isEqualTo(mediaFromBuilder.getDataAsByteArray()); - assertThat(mediaFromCtor.getId()).isEqualTo(mediaFromBuilder.getId()); - - // Verify name structure for both instances - assertValidMediaName(mediaFromCtor.getName(), "png"); - assertValidMediaName(mediaFromBuilder.getName(), "png"); - - // Data type consistency - assertThat(mediaFromCtor.getData()).isInstanceOf(byte[].class); - assertThat(mediaFromBuilder.getData()).isInstanceOf(byte[].class); - } - @Test void testUriConstructorNullValidation() { MimeType mimeType = MimeType.valueOf("image/png"); @@ -396,22 +320,23 @@ class MediaTests { MimeType mimeType = MimeType.valueOf("image/png"); // Test null mimeType - assertThatThrownBy(() -> new Media(null, new URL("http://example.com/image.png"))) + assertThatThrownBy(() -> new Media(null, URI.create("http://example.com/image.png"))) .isInstanceOf(IllegalArgumentException.class) .hasMessage("MimeType must not be null"); // Test null URL - assertThatThrownBy(() -> new Media(mimeType, (URL) null)).isInstanceOf(IllegalArgumentException.class) - .hasMessage("URL must not be null"); + assertThatThrownBy(() -> new Media(mimeType, (URI) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("URI must not be null"); // Compare with builder validation - assertThatThrownBy(() -> Media.builder().mimeType(null).data(new URL("http://example.com/image.png")).build()) + assertThatThrownBy( + () -> Media.builder().mimeType(null).data(URI.create("http://example.com/image.png")).build()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("MimeType must not be null"); - assertThatThrownBy(() -> Media.builder().mimeType(mimeType).data((URL) null).build()) + assertThatThrownBy(() -> Media.builder().mimeType(mimeType).data((URI) null).build()) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("URL must not be null"); + .hasMessage("URI must not be null"); } @Test