Skip to content

Commit c5d6dd2

Browse files
authored
fix: Validate that the primary URL specified in the AgentCard matches the URL for the preferred transport (#306)
fixes #272
1 parent 19119ab commit c5d6dd2

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

server-common/src/main/java/io/a2a/server/AgentCardValidator.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,22 @@ static void validateTransportConfiguration(AgentCard agentCard, Set<String> avai
8484
// Following the GitHub issue suggestion to use an error instead of warning
8585
throw new IllegalStateException(errorMessage);
8686
}
87+
88+
// check that the primary URL matches the URL for the preferred transport
89+
if (agentCard.additionalInterfaces() != null) {
90+
agentCard.additionalInterfaces().stream()
91+
.filter(agentInterface -> agentInterface.transport().equals(agentCard.preferredTransport()))
92+
.findFirst()
93+
.ifPresent(preferredTransportAgentInterface -> {
94+
if (!preferredTransportAgentInterface.url().equals(agentCard.url())) {
95+
LOGGER.warning(String.format(
96+
"AgentCard's URL=%s does not correspond to the URL of the preferred transport=%s.",
97+
agentCard.url(),
98+
preferredTransportAgentInterface.url()
99+
));
100+
}
101+
});
102+
}
87103
}
88104

89105
/**

server-common/src/test/java/io/a2a/server/AgentCardValidatorTest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,37 @@ void testSkipPropertiesFilterWarnings() {
229229
}
230230
}
231231

232+
@Test
233+
void testPrimaryURLMatchesPreferredTransport() {
234+
// Create a simple AgentCard (with preferred HTTP_JSON transport even though primary URL points to JSONRPC transport)
235+
AgentCard agentCard = createTestAgentCardBuilder()
236+
.preferredTransport(TransportProtocol.HTTP_JSON.asString())
237+
.additionalInterfaces(List.of(
238+
new AgentInterface(TransportProtocol.JSONRPC.asString(), "http://localhost:9999"),
239+
new AgentInterface(TransportProtocol.GRPC.asString(), "http://localhost:9000"),
240+
new AgentInterface(TransportProtocol.HTTP_JSON.asString(), "http://localhost:8000")
241+
))
242+
.build();
243+
244+
// Define available transports
245+
Set<String> availableTransports = Set.of(TransportProtocol.JSONRPC.asString(), TransportProtocol.GRPC.asString(), TransportProtocol.HTTP_JSON.asString());
246+
247+
// Capture logs
248+
Logger logger = Logger.getLogger(AgentCardValidator.class.getName());
249+
TestLogHandler testLogHandler = new TestLogHandler();
250+
logger.addHandler(testLogHandler);
251+
252+
try {
253+
AgentCardValidator.validateTransportConfiguration(agentCard, availableTransports);
254+
} finally {
255+
logger.removeHandler(testLogHandler);
256+
}
257+
258+
// Test that the warning was logged
259+
assertTrue(testLogHandler.getLogMessages().stream()
260+
.anyMatch(msg -> msg.contains("AgentCard's URL=http://localhost:9999 does not correspond to the URL of the preferred transport=http://localhost:8000.")));
261+
}
262+
232263
// A simple log handler for testing
233264
private static class TestLogHandler extends Handler {
234265
private final List<String> logMessages = new java.util.ArrayList<>();

0 commit comments

Comments
 (0)