Skip to content
Merged
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
9 changes: 0 additions & 9 deletions a2a-java-sdk-server-jakarta.iml

This file was deleted.

53 changes: 53 additions & 0 deletions grpc/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.wildfly.extras.a2a</groupId>
<artifactId>a2a-java-sdk-server-jakarta-parent</artifactId>
<version>0.2.6.Beta1-SNAPSHOT</version>
</parent>

<artifactId>a2a-java-sdk-server-jakarta-grpc</artifactId>
<packaging>jar</packaging>

<name>WildFly Extras - Java A2A SDK for Jakarta gRPC</name>
<description>Java SDK for the Agent2Agent Protocol (A2A) - SDK - Jakarta - gRPC integration</description>

<dependencies>
<!-- A2A spec-grpc dependency -->
<dependency>
<groupId>io.github.a2asdk</groupId>
<artifactId>a2a-java-sdk-transport-grpc</artifactId>
<version>${version.sdk}</version>
<scope>provided</scope>
</dependency>

<!-- Jakarta APIs needed for CDI and annotation support -->
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
<scope>provided</scope>
</dependency>

<!-- A2A server common for @PublicAgentCard and RequestHandler -->
<dependency>
<groupId>io.github.a2asdk</groupId>
<artifactId>a2a-java-sdk-server-common</artifactId>
<version>${version.sdk}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.wildfly.extras.a2a.server.apps.grpc;

import jakarta.annotation.PreDestroy;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Initialized;
import jakarta.enterprise.event.Observes;
import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;

import io.a2a.server.PublicAgentCard;
import io.a2a.server.requesthandlers.RequestHandler;
import io.a2a.spec.AgentCard;
import io.a2a.transport.grpc.handler.CallContextFactory;

/**
* Bean initializer that observes application startup events.
*
* Since CDI is not available on gRPC threads, we capture the CDI beans
* during application startup and store them statically for use by
* the WildFly gRPC subsystem.
*/
@ApplicationScoped
public class GrpcBeanInitializer {

@Inject
@PublicAgentCard
AgentCard agentCard;

@Inject
RequestHandler requestHandler;

@Inject
Instance<CallContextFactory> callContextFactory;

/**
* Observes the application startup event to eagerly initialize the gRPC cache.
*/
public void onStartup(@Observes @Initialized(ApplicationScoped.class) Object init) {
System.out.println("*** GrpcBeanInitializer.onStartup() called - ApplicationScoped initialized ***");
try {
// Cache CDI beans for gRPC threads to use since CDI is not available on those threads
CallContextFactory ccf = callContextFactory.isUnsatisfied() ? null : callContextFactory.get();
WildFlyGrpcHandler.setStaticBeans(agentCard, requestHandler, ccf);
System.out.println("*** GrpcBeanInitializer successfully cached beans: agentCard=" + agentCard + ", requestHandler=" + requestHandler + ", callContextFactory=" + ccf + " ***");
} catch (Exception e) {
System.err.println("*** GrpcBeanInitializer.onStartup() failed: " + e.getMessage());
e.printStackTrace();
}
}

@PreDestroy
public void cleanup() {
WildFlyGrpcHandler.setStaticBeans(null, null, null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.wildfly.extras.a2a.server.apps.grpc;

import io.a2a.server.requesthandlers.RequestHandler;
import io.a2a.spec.AgentCard;
import io.a2a.transport.grpc.handler.CallContextFactory;
import io.a2a.transport.grpc.handler.GrpcHandler;

/**
* WildFly gRPC Handler that uses static cache for CDI beans.
*
* The WildFly gRPC subsystem instantiates this class directly using
* reflection and the default constructor, bypassing CDI completely.
*
* Since CDI is not available on gRPC threads, we use static cache
* populated during application startup when CDI is available.
*/
public class WildFlyGrpcHandler extends GrpcHandler {

// Static cache populated during application startup by GrpcBeanInitializer
private static volatile AgentCard staticAgentCard;
private static volatile RequestHandler staticRequestHandler;
private static volatile CallContextFactory staticCallContextFactory;

public WildFlyGrpcHandler() {
// Default constructor - the only one used by WildFly gRPC subsystem
}

/**
* Called by GrpcBeanInitializer during CDI initialization to cache beans
* for use by gRPC threads where CDI is not available.
*/
static void setStaticBeans(AgentCard agentCard, RequestHandler requestHandler, CallContextFactory callContextFactory) {
staticAgentCard = agentCard;
staticRequestHandler = requestHandler;
staticCallContextFactory = callContextFactory;
}

@Override
protected RequestHandler getRequestHandler() {
if (staticRequestHandler == null) {
throw new RuntimeException("RequestHandler not available. ApplicationStartup may not have run yet.");
}
return staticRequestHandler;
}

@Override
protected AgentCard getAgentCard() {
if (staticAgentCard == null) {
throw new RuntimeException("AgentCard not available. ApplicationStartup may not have run yet.");
}
return staticAgentCard;
}

@Override
protected CallContextFactory getCallContextFactory() {
return staticCallContextFactory; // Can be null if not configured
}
}
6 changes: 6 additions & 0 deletions grpc/src/main/resources/META-INF/beans.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"
bean-discovery-mode="annotated">
</beans>
2 changes: 1 addition & 1 deletion impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<dependencies>
<dependency>
<groupId>io.github.a2asdk</groupId>
<artifactId>a2a-java-sdk-server-common</artifactId>
<artifactId>a2a-java-sdk-transport-jsonrpc</artifactId>
<exclusions>
<exclusion>
<groupId>jakarta.enterprise</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import io.a2a.server.ServerCallContext;
import io.a2a.server.auth.UnauthenticatedUser;
import io.a2a.server.auth.User;
import io.a2a.server.requesthandlers.JSONRPCHandler;
import io.a2a.server.util.async.Internal;
import io.a2a.spec.AgentCard;
import io.a2a.spec.CancelTaskRequest;
Expand All @@ -56,11 +55,12 @@
import io.a2a.spec.StreamingJSONRPCRequest;
import io.a2a.spec.TaskResubscriptionRequest;
import io.a2a.spec.UnsupportedOperationError;
import io.a2a.transport.jsonrpc.handler.JSONRPCHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Path("/")
public class A2AServerResource {
public class A2AServerResource {

private static final Logger LOGGER = LoggerFactory.getLogger(A2AServerResource.class);

Expand Down
53 changes: 52 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@
<properties>
<jboss.home>${project.build.directory}${file.separator}wildfly</jboss.home>
<version.wildfly>36.0.1.Final</version.wildfly>
<version.sdk>${project.version}</version.sdk>
<version.sdk>0.3.0.Beta1-SNAPSHOT</version.sdk>
<!-- This needs to be same version as used by the sdk -->
<version.mutiny-zero>1.1.1</version.mutiny-zero>
<!-- gRPC version matching the a2a-java-sdk -->
<version.grpc>1.73.0</version.grpc>

<version.jboss-commons-logging>1.0.0.Final</version.jboss-commons-logging>
<version.hamcrest>2.2</version.hamcrest>
Expand All @@ -58,6 +60,7 @@
<version.org.jboss.arquillian.jakarta>10.0.0.Final</version.org.jboss.arquillian.jakarta>
<version.shrinkwrap.resolvers>3.3.4</version.shrinkwrap.resolvers>
<version.rest-assured>5.5.5</version.rest-assured>
<version.wildfly.grpc>0.1.12.Final</version.wildfly.grpc>

<jboss.home>${project.build.directory}${file.separator}wildfly</jboss.home>
<arquillian.java.vm.args></arquillian.java.vm.args>
Expand Down Expand Up @@ -117,6 +120,21 @@
<artifactId>a2a-java-sdk-spec</artifactId>
<version>${version.sdk}</version>
</dependency>
<dependency>
<groupId>io.github.a2asdk</groupId>
<artifactId>a2a-java-sdk-spec-grpc</artifactId>
<version>${version.sdk}</version>
</dependency>
<dependency>
<groupId>io.github.a2asdk</groupId>
<artifactId>a2a-java-sdk-transport-grpc</artifactId>
<version>${version.sdk}</version>
</dependency>
<dependency>
<groupId>io.github.a2asdk</groupId>
<artifactId>a2a-java-sdk-transport-jsonrpc</artifactId>
<version>${version.sdk}</version>
</dependency>
<dependency>
<groupId>io.github.a2asdk</groupId>
<artifactId>a2a-tck-server</artifactId>
Expand Down Expand Up @@ -162,6 +180,37 @@
<version>${version.hamcrest}</version>
<scope>test</scope>
</dependency>
<!-- gRPC dependencies -->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${version.grpc}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${version.grpc}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<version>${version.grpc}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>${version.grpc}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>4.31.1</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>failureaccess</artifactId>
<version>1.0.2</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
Expand Down Expand Up @@ -249,9 +298,11 @@
</pluginManagement>
</build>
<modules>
<module>grpc</module>
<module>impl</module>
<module>tck</module>
<module>tests</module>
<module>tests-grpc</module>
</modules>
<profiles>
<profile>
Expand Down
Loading