@@ -1660,7 +1660,7 @@ public void onCompleted() {
16601660
16611661 @ Test
16621662 @ SuppressWarnings ("unchecked" )
1663- public void givenRequestBodyModeGrpc_whenExtProcRespondsWithEmptyBody_thenEmptyMessageIsDelivered ()
1663+ public void givenRequestBodyModeGrpc_whenExtProcRespondsEmpty_thenEmptyMsgDelivered ()
16641664 throws Exception {
16651665 String uniqueExtProcServerName =
16661666 "extProc-emptyMsg-" + InProcessServerBuilder .generateName ();
@@ -1944,9 +1944,114 @@ public void onCompleted() {
19441944 channelManager .close ();
19451945 }
19461946
1947- // --- Category 5: Response Header Mutation ---
1947+ @ Test
1948+ @ SuppressWarnings ("unchecked" )
1949+ public void givenRequestBodyModeNone_whenSendMessageCalled_thenMessageSentDirectlyToDataPlane ()
1950+ throws Exception {
1951+ String uniqueExtProcServerName = "extProc-noneBody-" + InProcessServerBuilder .generateName ();
1952+ String uniqueDataPlaneServerName =
1953+ "dataPlane-noneBody-" + InProcessServerBuilder .generateName ();
1954+ ExternalProcessor proto = ExternalProcessor .newBuilder ()
1955+ .setGrpcService (GrpcService .newBuilder ()
1956+ .setGoogleGrpc (GrpcService .GoogleGrpc .newBuilder ()
1957+ .setTargetUri ("in-process:///" + uniqueExtProcServerName )
1958+ .addChannelCredentialsPlugin (Any .newBuilder ()
1959+ .setTypeUrl ("type.googleapis.com/envoy.extensions.grpc_service."
1960+ + "channel_credentials.insecure.v3.InsecureCredentials" )
1961+ .build ())
1962+ .build ())
1963+ .build ())
1964+ .setProcessingMode (ProcessingMode .newBuilder ()
1965+ .setRequestHeaderMode (ProcessingMode .HeaderSendMode .SKIP )
1966+ .setRequestBodyMode (ProcessingMode .BodySendMode .NONE ).build ())
1967+ .build ();
1968+ ConfigOrError <ExternalProcessorFilterConfig > configOrError =
1969+ provider .parseFilterConfig (Any .pack (proto ), filterContext );
1970+ assertThat (configOrError .errorDetail ).isNull ();
1971+ ExternalProcessorFilterConfig filterConfig = configOrError .config ;
19481972
1949- @ Test
1973+ final AtomicInteger extProcBodyCount = new AtomicInteger (0 );
1974+ ExternalProcessorGrpc .ExternalProcessorImplBase extProcImpl ;
1975+ extProcImpl = new ExternalProcessorGrpc .ExternalProcessorImplBase () {
1976+ @ Override
1977+ @ SuppressWarnings ("unchecked" )
1978+ public StreamObserver <ProcessingRequest > process (
1979+ final StreamObserver <ProcessingResponse > responseObserver ) {
1980+ ((ServerCallStreamObserver <ProcessingResponse >) responseObserver ).request (100 );
1981+ return new StreamObserver <ProcessingRequest >() {
1982+ @ Override
1983+ public void onNext (ProcessingRequest request ) {
1984+ if (request .hasRequestBody ()) {
1985+ extProcBodyCount .incrementAndGet ();
1986+ }
1987+ }
1988+
1989+ @ Override
1990+ public void onError (Throwable t ) {
1991+ }
1992+
1993+ @ Override
1994+ public void onCompleted () {
1995+ responseObserver .onCompleted ();
1996+ }
1997+ };
1998+ }
1999+ };
2000+ grpcCleanup .register (InProcessServerBuilder .forName (uniqueExtProcServerName )
2001+ .addService (extProcImpl )
2002+ .directExecutor ()
2003+ .build ().start ());
2004+
2005+ CachedChannelManager channelManager = new CachedChannelManager (config -> {
2006+ return grpcCleanup .register (
2007+ InProcessChannelBuilder .forName (uniqueExtProcServerName ).directExecutor ().build ());
2008+ });
2009+
2010+ ExternalProcessorClientInterceptor interceptor = new ExternalProcessorClientInterceptor (
2011+ filterConfig , channelManager , scheduler , FAKE_CONTEXT );
2012+
2013+ final AtomicReference <String > receivedBody = new AtomicReference <>();
2014+ final CountDownLatch dataPlaneLatch = new CountDownLatch (1 );
2015+ MutableHandlerRegistry uniqueRegistry = new MutableHandlerRegistry ();
2016+ grpcCleanup .register (InProcessServerBuilder .forName (uniqueDataPlaneServerName )
2017+ .fallbackHandlerRegistry (uniqueRegistry )
2018+ .directExecutor ()
2019+ .build ().start ());
2020+
2021+ uniqueRegistry .addService (ServerServiceDefinition .builder ("test.TestService" )
2022+ .addMethod (METHOD_SAY_HELLO , ServerCalls .asyncUnaryCall (
2023+ (request , responseObserver ) -> {
2024+ receivedBody .set (request );
2025+ responseObserver .onNext ("Hello" );
2026+ responseObserver .onCompleted ();
2027+ dataPlaneLatch .countDown ();
2028+ }))
2029+ .build ());
2030+
2031+ ManagedChannel dataPlaneChannel = grpcCleanup .register (
2032+ InProcessChannelBuilder .forName (uniqueDataPlaneServerName ).directExecutor ().build ());
2033+
2034+ CallOptions callOptions = DEFAULT_CALL_OPTIONS .withExecutor (MoreExecutors .directExecutor ());
2035+ ClientCall <String , String > proxyCall =
2036+ interceptCall (interceptor , METHOD_SAY_HELLO , callOptions , dataPlaneChannel );
2037+
2038+ proxyCall .start (new ClientCall .Listener <String >() {}, new Metadata ());
2039+ proxyCall .request (1 );
2040+ proxyCall .sendMessage ("Hello World" );
2041+ proxyCall .halfClose ();
2042+
2043+ assertThat (dataPlaneLatch .await (5 , TimeUnit .SECONDS )).isTrue ();
2044+ assertThat (receivedBody .get ()).isEqualTo ("Hello World" );
2045+ assertThat (extProcBodyCount .get ()).isEqualTo (0 );
2046+
2047+ proxyCall .cancel ("Cleanup" , null );
2048+ channelManager .close ();
2049+ }
2050+
2051+
2052+ // --- Category 5: Response Header Mutation ---
2053+
2054+ @ Test
19502055 @ SuppressWarnings ("unchecked" )
19512056 public void givenResponseHeaderModeSend_whenExtProcRespondsWithMutatedHeaders_thenSent ()
19522057 throws Exception {
@@ -2225,7 +2330,7 @@ public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
22252330 channelManager .close ();
22262331 }
22272332
2228- // --- Category 6: Body Mutation: Inbound/Response (GRPC Mode) ---
2333+ // --- Category 6: Body Mutation: Inbound/Response (GRPC Mode) ---
22292334
22302335 @ Test
22312336 @ SuppressWarnings ("unchecked" )
@@ -2545,7 +2650,7 @@ public void onClose(Status status, Metadata trailers) {
25452650
25462651 // --- Category 7: Half-Close handling ---
25472652
2548- @ Test
2653+ @ Test
25492654 @ SuppressWarnings ("unchecked" )
25502655 public void givenRequestBodyModeGrpc_whenHalfCloseCalled_thenSuperHalfCloseDeferred ()
25512656 throws Exception {
@@ -3280,7 +3385,7 @@ public void halfClose() {
32803385 channelManager .close ();
32813386 }
32823387
3283- @ Test
3388+ @ Test
32843389 @ SuppressWarnings ("unchecked" )
32853390 public void givenResponseTrailerModeSend_whenDataPlaneCloses_thenTrailersHandshakeCompleted ()
32863391 throws Exception {
@@ -3423,7 +3528,7 @@ public void onClose(Status status, Metadata trailers) {
34233528 channelManager .close ();
34243529 }
34253530
3426- // --- Category 8: Outbound Backpressure (isReady / onReady) ---
3531+ // --- Category 8: Outbound Backpressure (isReady / onReady) ---
34273532
34283533 @ Test
34293534 @ SuppressWarnings ("unchecked" )
@@ -4695,9 +4800,9 @@ public void onCompleted() {
46954800 channelManager .close ();
46964801 }
46974802
4698- // --- Category 10: Error Handling & Security ---
4803+ // --- Category 10: Error Handling & Security ---
46994804
4700- @ Test
4805+ @ Test
47014806 @ SuppressWarnings ("FutureReturnValueIgnored" )
47024807 public void givenPendingData_whenImmediateResponseReceived_thenDeliversDataBeforeStatus ()
47034808 throws Exception {
@@ -5050,7 +5155,7 @@ public void onClose(Status status, Metadata trailers) {
50505155 channelManager .close ();
50515156 }
50525157
5053- @ Test
5158+ @ Test
50545159 @ SuppressWarnings ("unchecked" )
50555160 public void givenObservabilityMode_whenDataPlaneClosed_thenSidecarCloseIsDeferred ()
50565161 throws Exception {
@@ -5473,7 +5578,7 @@ public void onCompleted() {
54735578 channelManager .close ();
54745579 }
54755580
5476- @ Test
5581+ @ Test
54775582 @ SuppressWarnings ("unchecked" )
54785583 public void givenHeaderSendModeDefault_whenProcessing_thenFollowsDefaultBehavior ()
54795584 throws Exception {
@@ -5643,7 +5748,7 @@ public void onCompleted() {
56435748
56445749 // --- Category 11: Immediate Response Handling ---
56455750
5646- @ Test
5751+ @ Test
56475752 @ SuppressWarnings ("unchecked" )
56485753 public void givenImmediateResponse_whenReceived_thenDataPlaneCallCancelled ()
56495754 throws Exception {
@@ -5978,7 +6083,7 @@ public void onCompleted() {
59786083 }
59796084 }
59806085
5981- @ Test
6086+ @ Test
59826087 @ SuppressWarnings ("unchecked" )
59836088 public void givenImmediateResponseInTrailers_whenReceived_thenDataPlaneCallStatusIsOverridden ()
59846089 throws Exception {
0 commit comments