11package org .lognet .springboot .grpc .recovery ;
22
3- import io .grpc .Metadata ;
4- import io .grpc .Status ;
5- import io .grpc .StatusRuntimeException ;
3+ import io .grpc .*;
64import io .grpc .examples .custom .Custom ;
75import io .grpc .examples .custom .CustomServiceGrpc ;
86import io .grpc .stub .StreamObserver ;
119import org .lognet .springboot .grpc .GRpcService ;
1210import org .lognet .springboot .grpc .GrpcServerTestBase ;
1311import org .lognet .springboot .grpc .demo .DemoApp ;
12+ import org .lognet .springboot .grpc .security .*;
1413import org .mockito .Mockito ;
1514import org .springframework .boot .test .context .SpringBootTest ;
1615import org .springframework .boot .test .context .TestConfiguration ;
1716import org .springframework .boot .test .mock .mockito .SpyBean ;
1817import org .springframework .context .annotation .Import ;
18+ import org .springframework .security .authentication .dao .DaoAuthenticationProvider ;
19+ import org .springframework .security .core .userdetails .User ;
20+ import org .springframework .security .core .userdetails .UserDetailsService ;
21+ import org .springframework .security .crypto .password .NoOpPasswordEncoder ;
22+ import org .springframework .security .provisioning .InMemoryUserDetailsManager ;
1923import org .springframework .test .context .ActiveProfiles ;
2024import org .springframework .test .context .junit4 .SpringRunner ;
2125
26+ import java .util .Collections ;
2227import java .util .concurrent .CompletableFuture ;
2328import java .util .concurrent .ExecutionException ;
2429import java .util .concurrent .TimeUnit ;
3641
3742@ RunWith (SpringRunner .class )
3843@ SpringBootTest (classes = {DemoApp .class }, webEnvironment = NONE )
39- @ ActiveProfiles ({"disable-security" })
4044@ Import (GRpcRecoveryTest .Cfg .class )
4145public class GRpcRecoveryTest extends GrpcServerTestBase {
4246
4347 static class CheckedException extends Exception {
4448
4549 }
50+
4651 static class CheckedException1 extends Exception {
4752
4853 }
@@ -59,9 +64,25 @@ static class Exception1 extends RuntimeException {
5964
6065 }
6166
62- @ TestConfiguration
63- static class Cfg {
67+ private static User user1 = new User ("test1" , "test1" , Collections .EMPTY_LIST );
6468
69+ private AuthHeader .AuthHeaderBuilder user1AuthHeaderBuilder =
70+ AuthHeader .builder ().basic (user1 .getUsername (), user1 .getPassword ().getBytes ());
71+
72+ @ TestConfiguration
73+ static class Cfg extends GrpcSecurityConfigurerAdapter {
74+ @ Override
75+ public void configure (GrpcSecurity builder ) throws Exception {
76+ DaoAuthenticationProvider provider = new DaoAuthenticationProvider ();
77+ UserDetailsService users = new InMemoryUserDetailsManager (user1 );
78+ provider .setUserDetailsService (users );
79+ provider .setPasswordEncoder (NoOpPasswordEncoder .getInstance ());
80+
81+ builder
82+ .authenticationProvider (provider )
83+ .authorizeRequests ()
84+ .anyMethod ().authenticated ();
85+ }
6586
6687 @ GRpcServiceAdvice
6788 static class CustomErrorHandler {
@@ -102,6 +123,9 @@ public StreamObserver<Custom.CustomRequest> customStream(StreamObserver<Custom.C
102123 return new StreamObserver <Custom .CustomRequest >() {
103124 @ Override
104125 public void onNext (Custom .CustomRequest value ) {
126+ if ("onNext" .equalsIgnoreCase (value .getName ())) {
127+ throw new GRpcRuntimeExceptionWrapper (new CheckedException1 ());
128+ }
105129 responseObserver .onNext (Custom .CustomReply .newBuilder ().build ());
106130 }
107131
@@ -151,9 +175,24 @@ public Status handleB(ExceptionB e, GRpcExceptionScope scope) {
151175 private Cfg .CustomErrorHandler handler ;
152176
153177
178+ protected Channel getChannel () {
179+ return ClientInterceptors .intercept (super .getChannel (), new AuthClientInterceptor (user1AuthHeaderBuilder ));
180+ }
181+
182+
154183 @ Test
155- public void streamingServiceErrorHandlerTest () throws ExecutionException , InterruptedException , TimeoutException {
184+ public void parameterizedStreamingServiceErrorHandlerTest () throws ExecutionException , InterruptedException , TimeoutException {
185+ String [] phases = new String []{
186+ "onNext" , // exception will be thrown onNext
187+ "onCompleted" // exception will be thrown onCompleted
188+ };
189+ for (String errorPhase : phases ) {
190+ streamingServiceErrorHandlerTest (errorPhase );
191+ Mockito .clearInvocations (srv );
192+ }
193+ }
156194
195+ public void streamingServiceErrorHandlerTest (String errorName ) throws ExecutionException , InterruptedException , TimeoutException {
157196
158197
159198 final CompletableFuture <Throwable > errorFuture = new CompletableFuture <>();
@@ -175,20 +214,18 @@ public void onCompleted() {
175214 }
176215 };
177216
178- final StreamObserver <Custom .CustomRequest > requests = CustomServiceGrpc .newStub (getChannel ()).customStream (reply );
179- requests .onNext (Custom .CustomRequest .newBuilder ().build ());
217+ final StreamObserver <Custom .CustomRequest > requests = CustomServiceGrpc .newStub (getChannel ())
218+ .customStream (reply );
219+ requests .onNext (Custom .CustomRequest .newBuilder ().setName (errorName ).build ());
180220 requests .onCompleted ();
181221
182222
183-
184-
185-
186223 final Throwable actual = errorFuture .get (20 , TimeUnit .SECONDS );
187224 assertThat (actual , notNullValue ());
188225 assertThat (actual , isA (StatusRuntimeException .class ));
189- assertThat (((StatusRuntimeException )actual ).getStatus (), is (Status .RESOURCE_EXHAUSTED ));
226+ assertThat (((StatusRuntimeException ) actual ).getStatus (), is (Status .RESOURCE_EXHAUSTED ));
190227
191- Mockito .verify (srv ,times (1 )).handle (any (CheckedException1 .class ),any ());
228+ Mockito .verify (srv , times (1 )).handle (any (CheckedException1 .class ), any ());
192229
193230 }
194231
@@ -199,7 +236,8 @@ public void checkedExceptionHandlerTest() {
199236 .custom (any (Custom .CustomRequest .class ), any (StreamObserver .class ));
200237
201238 final StatusRuntimeException statusRuntimeException = assertThrows (StatusRuntimeException .class , () ->
202- CustomServiceGrpc .newBlockingStub (getChannel ()).custom (Custom .CustomRequest .newBuilder ().build ())
239+ CustomServiceGrpc .newBlockingStub (getChannel ())
240+ .custom (Custom .CustomRequest .newBuilder ().build ())
203241 );
204242 assertThat (statusRuntimeException .getStatus (), is (Status .OUT_OF_RANGE ));
205243
@@ -221,7 +259,8 @@ public void globalHandlerTest() {
221259 .custom (any (Custom .CustomRequest .class ), any (StreamObserver .class ));
222260
223261 final StatusRuntimeException statusRuntimeException = assertThrows (StatusRuntimeException .class , () ->
224- CustomServiceGrpc .newBlockingStub (getChannel ()).custom (Custom .CustomRequest .newBuilder ().build ())
262+ CustomServiceGrpc .newBlockingStub (getChannel ())
263+ .custom (Custom .CustomRequest .newBuilder ().build ())
225264 );
226265 assertThat (statusRuntimeException .getStatus (), is (Status .NOT_FOUND ));
227266
@@ -242,7 +281,8 @@ public void globalHandlerWithExceptionHierarchyTest() {
242281 .custom (any (Custom .CustomRequest .class ), any (StreamObserver .class ));
243282
244283 final StatusRuntimeException statusRuntimeException = assertThrows (StatusRuntimeException .class , () ->
245- CustomServiceGrpc .newBlockingStub (getChannel ()).custom (Custom .CustomRequest .newBuilder ().build ())
284+ CustomServiceGrpc .newBlockingStub (getChannel ())
285+ .custom (Custom .CustomRequest .newBuilder ().build ())
246286 );
247287 assertThat (statusRuntimeException .getStatus (), is (Status .DATA_LOSS ));
248288
@@ -263,7 +303,8 @@ public void privateHandlerHasHigherPrecedence() {
263303 .custom (any (Custom .CustomRequest .class ), any (StreamObserver .class ));
264304
265305 final StatusRuntimeException statusRuntimeException = assertThrows (StatusRuntimeException .class , () ->
266- CustomServiceGrpc .newBlockingStub (getChannel ()).custom (Custom .CustomRequest .newBuilder ().build ())
306+ CustomServiceGrpc .newBlockingStub (getChannel ())
307+ .custom (Custom .CustomRequest .newBuilder ().build ())
267308 );
268309 assertThat (statusRuntimeException .getStatus (), is (Status .FAILED_PRECONDITION ));
269310
0 commit comments