diff --git a/core/src/main/resources/META-INF/beans.xml b/core/src/main/resources/META-INF/beans.xml index e69de29bb..9dfae34df 100644 --- a/core/src/main/resources/META-INF/beans.xml +++ b/core/src/main/resources/META-INF/beans.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/sdk-jakarta/pom.xml b/sdk-jakarta/pom.xml index e32c6511d..91e6155b4 100644 --- a/sdk-jakarta/pom.xml +++ b/sdk-jakarta/pom.xml @@ -15,7 +15,43 @@ Java A2A SDK for Jakarta Java SDK for the Agent2Agent Protocol (A2A) - SDK - Jakarta - + + 5.1.0.Beta11 + 1.10.0.Final + + 1.2.6 + 10.0.0.Final + 3.3.4 + ${project.build.directory}${file.separator}wildfly + + 8787 + + + + + org.jboss.shrinkwrap + shrinkwrap-bom + ${version.org.jboss.shrinkwrap.shrinkwrap} + pom + import + + + org.jboss.arquillian + arquillian-bom + ${version.org.jboss.arquillian} + pom + import + + + org.wildfly.arquillian + wildfly-arquillian-bom + ${version.org.wildfly.arquillian} + pom + import + + + ${project.groupId} @@ -65,40 +101,142 @@ jakarta.ws.rs-api provided - + com.fasterxml.jackson.datatype jackson-datatype-jsr310 test - io.quarkus - quarkus-junit5 + io.rest-assured + rest-assured test - io.quarkus - quarkus-resteasy-jackson + org.jboss.arquillian.junit5 + arquillian-junit5-container test - io.quarkus - quarkus-resteasy-client-jackson + org.wildfly.arquillian + wildfly-arquillian-container-managed test - - org.jboss.resteasy - resteasy-client + + org.jboss.shrinkwrap + shrinkwrap-api test org.junit.jupiter - junit-jupiter-api + junit-jupiter test - io.rest-assured - rest-assured + org.jboss.threads + jboss-threads + 3.9.1 + test + + + org.hamcrest + hamcrest test + + + + org.wildfly.glow + wildfly-glow-arquillian-plugin + 1.4.1.Final + + + + org.wildfly + wildfly-galleon-pack + 36.0.1.Final + + + standalone.xml + + + + scan + + scan + + test-compile + + + + + org.wildfly.plugins + wildfly-maven-plugin + 5.1.3.Final + + ${project.build.directory}/glow-scan/provisioning.xml + ${jboss.home} + ${jboss.home} + + + + + + + + + + + test-provisioning + + package + + test-compile + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.3 + + + ${jboss.home} + arquillian.xml + ${arquillian.java.vm.args} + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.8.1 + + ${project.build.directory}/lib + + + + copy + generate-test-resources + + copy-dependencies + + + test + provided + + + + + + + + + debug.profile + debug + + -agentlib:jdwp=transport=dt_socket,address=*:${server.debug.port},server=y,suspend=y + + + \ No newline at end of file diff --git a/sdk-jakarta/src/main/java/io/a2a/server/apps/jakarta/A2ARequestFilter.java b/sdk-jakarta/src/main/java/io/a2a/server/apps/jakarta/A2ARequestFilter.java index 68fbb5585..59e332109 100644 --- a/sdk-jakarta/src/main/java/io/a2a/server/apps/jakarta/A2ARequestFilter.java +++ b/sdk-jakarta/src/main/java/io/a2a/server/apps/jakarta/A2ARequestFilter.java @@ -18,9 +18,13 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.ext.Provider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + @Provider @PreMatching public class A2ARequestFilter implements ContainerRequestFilter { + private static final Logger LOGGER = LoggerFactory.getLogger(A2ARequestFilter.class); @Override public void filter(ContainerRequestContext requestContext) { @@ -31,8 +35,10 @@ public void filter(ContainerRequestContext requestContext) { // ensure the request is treated as a streaming request or a non-streaming request // based on the method in the request body if (isStreamingRequest(requestBody)) { + LOGGER.debug("Handling request as streaming: {}", requestBody); putAcceptHeader(requestContext, MediaType.SERVER_SENT_EVENTS); } else if (isNonStreamingRequest(requestBody)) { + LOGGER.debug("Handling request as non-streaming: {}", requestBody); putAcceptHeader(requestContext, MediaType.APPLICATION_JSON); } // reset the entity stream diff --git a/sdk-jakarta/src/main/resources/META-INF/beans.xml b/sdk-jakarta/src/main/resources/META-INF/beans.xml index 9b2940fc2..9dfae34df 100644 --- a/sdk-jakarta/src/main/resources/META-INF/beans.xml +++ b/sdk-jakarta/src/main/resources/META-INF/beans.xml @@ -2,5 +2,5 @@ + bean-discovery-mode="all"> \ No newline at end of file diff --git a/sdk-jakarta/src/scripts/configure_logger.cli b/sdk-jakarta/src/scripts/configure_logger.cli new file mode 100644 index 000000000..a45fb245d --- /dev/null +++ b/sdk-jakarta/src/scripts/configure_logger.cli @@ -0,0 +1,2 @@ +/subsystem=logging/logger=org.jboss.weld:add(level=DEBUG) +/subsystem=logging/logger=io.a2a:add(level=DEBUG) \ No newline at end of file diff --git a/sdk-jakarta/src/test/java/io/a2a/server/apps/jakarta/JakartaA2AServerTest.java b/sdk-jakarta/src/test/java/io/a2a/server/apps/jakarta/JakartaA2AServerTest.java index 06ad61c9a..159ac79bc 100644 --- a/sdk-jakarta/src/test/java/io/a2a/server/apps/jakarta/JakartaA2AServerTest.java +++ b/sdk-jakarta/src/test/java/io/a2a/server/apps/jakarta/JakartaA2AServerTest.java @@ -1,14 +1,76 @@ package io.a2a.server.apps.jakarta; -import jakarta.inject.Inject; + import io.a2a.server.apps.common.AbstractA2AServerTest; +import io.a2a.server.apps.common.AgentCardProducer; +import io.a2a.server.apps.common.AgentExecutorProducer; import io.a2a.server.events.InMemoryQueueManager; import io.a2a.server.tasks.TaskStore; -import io.quarkus.test.junit.QuarkusTest; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import java.io.File; +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit5.container.annotation.ArquillianTest; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; -@QuarkusTest +@ArquillianTest +@ApplicationScoped public class JakartaA2AServerTest extends AbstractA2AServerTest { + + public JakartaA2AServerTest() { + super(8080); + } + + @Deployment + public static WebArchive createTestArchive() throws IOException { + final List prefixes = List.of( + "a2a-java-sdk-core", + "a2a-java-sdk-server-common", + "jackson", + "mutiny", + "slf4j", + "rest-assured", + "groovy", + "http", + "commons", + "xml-path", + "json-path", + "hamcrest" + ); + List libraries = new ArrayList<>(); + try (DirectoryStream stream = Files.newDirectoryStream(Paths.get("target").resolve("lib"))) { + for (Path file : stream) { + String fileName = file.getFileName().toString(); + if (prefixes.stream().anyMatch(fileName::startsWith)) { + libraries.add(file.toFile()); + } + } + } + WebArchive archive = ShrinkWrap.create(WebArchive.class, "ROOT.war") + .addAsLibraries(libraries.toArray(new File[libraries.size()])) + .addClass(AbstractA2AServerTest.class) + .addClass(AgentCardProducer.class) + .addClass(AgentExecutorProducer.class) + .addClass(JakartaA2AServerTest.class) + .addClass(A2ARequestFilter.class) + .addClass(A2AServerResource.class) + .addClass(RestApplication.class) + .addAsManifestResource("META-INF/beans.xml", "beans.xml") + .addAsWebInfResource("META-INF/beans.xml", "beans.xml") + .addAsWebInfResource("WEB-INF/web.xml", "web.xml"); + return archive; + } + @Inject TaskStore taskStore; diff --git a/sdk-jakarta/src/test/java/io/a2a/server/apps/jakarta/RestApplication.java b/sdk-jakarta/src/test/java/io/a2a/server/apps/jakarta/RestApplication.java new file mode 100644 index 000000000..e2fcf6af3 --- /dev/null +++ b/sdk-jakarta/src/test/java/io/a2a/server/apps/jakarta/RestApplication.java @@ -0,0 +1,8 @@ +package io.a2a.server.apps.jakarta; + +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.core.Application; + +@ApplicationPath("/") +public class RestApplication extends Application { +} diff --git a/sdk-jakarta/src/test/resources/WEB-INF/web.xml b/sdk-jakarta/src/test/resources/WEB-INF/web.xml new file mode 100644 index 000000000..2678fbc83 --- /dev/null +++ b/sdk-jakarta/src/test/resources/WEB-INF/web.xml @@ -0,0 +1,12 @@ + + + + + 30 + + + diff --git a/sdk-jakarta/src/test/resources/arquillian.xml b/sdk-jakarta/src/test/resources/arquillian.xml new file mode 100644 index 000000000..804afef5d --- /dev/null +++ b/sdk-jakarta/src/test/resources/arquillian.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + ${basedir}/target/wildfly + + ${arquillian.java.vm.args} + true + + + + diff --git a/sdk-jakarta/src/test/resources/logging.properties b/sdk-jakarta/src/test/resources/logging.properties new file mode 100644 index 000000000..17885c831 --- /dev/null +++ b/sdk-jakarta/src/test/resources/logging.properties @@ -0,0 +1,29 @@ +# +# Copyright The WildFly Authors +# SPDX-License-Identifier: Apache-2.0 +# + +# Additional logger names to configure (root logger is always configured) +loggers=sun.rmi,org.jboss.shrinkwrap,org.apache.http.wire +logger.org.jboss.shrinkwrap.level=INFO +logger.sun.rmi.level=WARNING +logger.org.apache.http.wire.level=WARN + +# Root logger level +logger.level=WARN + +# Root logger handlers +logger.handlers=FILE + +# File handler configuration +handler.FILE=org.jboss.logmanager.handlers.FileHandler +handler.FILE.properties=autoFlush,append,fileName +handler.FILE.autoFlush=true +handler.FILE.fileName=./target/test.log +handler.FILE.formatter=PATTERN +handler.FILE.append=true + +# Formatter pattern configuration +formatter.PATTERN=org.jboss.logmanager.formatters.PatternFormatter +formatter.PATTERN.properties=pattern +formatter.PATTERN.pattern=%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n diff --git a/sdk-quarkus/src/test/java/io/a2a/server/apps/quarkus/QuarkusA2AServerTest.java b/sdk-quarkus/src/test/java/io/a2a/server/apps/quarkus/QuarkusA2AServerTest.java index 4dce72cee..dab1954ba 100644 --- a/sdk-quarkus/src/test/java/io/a2a/server/apps/quarkus/QuarkusA2AServerTest.java +++ b/sdk-quarkus/src/test/java/io/a2a/server/apps/quarkus/QuarkusA2AServerTest.java @@ -16,6 +16,10 @@ public class QuarkusA2AServerTest extends AbstractA2AServerTest { @Inject InMemoryQueueManager queueManager; + public QuarkusA2AServerTest() { + super(8081); + } + @Override protected TaskStore getTaskStore() { return taskStore; diff --git a/sdk-server-common/src/main/java/io/a2a/server/events/EventQueue.java b/sdk-server-common/src/main/java/io/a2a/server/events/EventQueue.java index 6a41901ca..c73292a09 100644 --- a/sdk-server-common/src/main/java/io/a2a/server/events/EventQueue.java +++ b/sdk-server-common/src/main/java/io/a2a/server/events/EventQueue.java @@ -20,8 +20,6 @@ public abstract class EventQueue implements AutoCloseable { // TODO decide on a capacity private static final int queueSize = 1000; - private final EventQueue parent; - private final BlockingQueue queue = new LinkedBlockingDeque<>(); private final Semaphore semaphore = new Semaphore(queueSize, true); private volatile boolean closed = false; @@ -34,10 +32,10 @@ protected EventQueue() { protected EventQueue(EventQueue parent) { LOGGER.trace("Creating {}, parent: {}", this, parent); - this.parent = parent; } public static EventQueue create() { + return new MainQueue(); } diff --git a/tests/server-common/src/test/java/io/a2a/server/apps/common/AbstractA2AServerTest.java b/tests/server-common/src/test/java/io/a2a/server/apps/common/AbstractA2AServerTest.java index ac7bf5c5d..0992a157f 100644 --- a/tests/server-common/src/test/java/io/a2a/server/apps/common/AbstractA2AServerTest.java +++ b/tests/server-common/src/test/java/io/a2a/server/apps/common/AbstractA2AServerTest.java @@ -103,6 +103,12 @@ public abstract class AbstractA2AServerTest { .parts(new TextPart("test message")) .build(); + private final int serverPort; + + protected AbstractA2AServerTest(int serverPort) { + this.serverPort = serverPort; + } + @Test public void testGetTaskSuccess() { testGetTask(); @@ -222,7 +228,8 @@ public void testCancelTaskNotFound() { .then() .statusCode(200) .extract() - .as(CancelTaskResponse.class); + .as(CancelTaskResponse.class) + ; assertEquals(request.getId(), response.getId()); assertNull(response.getResult()); // this should be an instance of UnsupportedOperationError, see https://github.com/a2aproject/a2a-java/issues/23 @@ -853,7 +860,8 @@ private CompletableFuture>> initialiseStreamingReque // Create the request HttpRequest.Builder builder = HttpRequest.newBuilder() - .uri(URI.create("http://localhost:8081/")) + .uri(URI.create("http://localhost:" + serverPort + + "/")) .POST(HttpRequest.BodyPublishers.ofString(Utils.OBJECT_MAPPER.writeValueAsString(request))) .header("Content-Type", "application/json"); if (mediaType != null) { diff --git a/tests/server-common/src/test/resources/META-INF/beans.xml b/tests/server-common/src/test/resources/META-INF/beans.xml index e69de29bb..9dfae34df 100644 --- a/tests/server-common/src/test/resources/META-INF/beans.xml +++ b/tests/server-common/src/test/resources/META-INF/beans.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file