5050 *
5151 * @author dtuchs (Dmitry Tuchs).
5252 */
53- @ SuppressWarnings ("all" )
53+ @ SuppressWarnings ({
54+ "checkstyle:ClassFanOutComplexity" ,
55+ "checkstyle:AnonInnerLength" ,
56+ "checkstyle:JavaNCSS"
57+ })
5458public class AllureGrpc implements ClientInterceptor {
5559
5660 private static final Logger LOGGER = LoggerFactory .getLogger (AllureGrpc .class );
5761 private static final String UNKNOWN = "unknown" ;
62+ private static final String JSON_SUFFIX = " (json)" ;
5863 private static final JsonFormat .Printer GRPC_TO_JSON_PRINTER = JsonFormat .printer ();
64+
5965 private final AllureLifecycle lifecycle ;
6066 private final boolean markStepFailedOnNonZeroCode ;
6167 private final boolean interceptResponseMetadata ;
@@ -67,11 +73,13 @@ public AllureGrpc() {
6773 "grpc-request.ftl" , "grpc-response.ftl" );
6874 }
6975
70- public AllureGrpc (AllureLifecycle lifecycle ,
71- boolean markStepFailedOnNonZeroCode ,
72- boolean interceptResponseMetadata ,
73- String requestTemplatePath ,
74- String responseTemplatePath ) {
76+ public AllureGrpc (
77+ final AllureLifecycle lifecycle ,
78+ final boolean markStepFailedOnNonZeroCode ,
79+ final boolean interceptResponseMetadata ,
80+ final String requestTemplatePath ,
81+ final String responseTemplatePath
82+ ) {
7583 this .lifecycle = lifecycle ;
7684 this .markStepFailedOnNonZeroCode = markStepFailedOnNonZeroCode ;
7785 this .interceptResponseMetadata = interceptResponseMetadata ;
@@ -81,9 +89,9 @@ public AllureGrpc(AllureLifecycle lifecycle,
8189
8290 @ Override
8391 public <T , R > ClientCall <T , R > interceptCall (
84- MethodDescriptor <T , R > methodDescriptor ,
85- CallOptions callOptions ,
86- Channel nextChannel
92+ final MethodDescriptor <T , R > methodDescriptor ,
93+ final CallOptions callOptions ,
94+ final Channel nextChannel
8795 ) {
8896 final AllureLifecycle current = lifecycle ;
8997 final String parent = current .getCurrentTestCaseOrStep ().orElse (null );
@@ -94,11 +102,15 @@ public <T, R> ClientCall<T, R> interceptCall(
94102 final Map <String , String > trailers = new LinkedHashMap <>();
95103
96104 final String stepName = buildStepName (nextChannel , methodDescriptor );
97- if (parent != null ) current .startStep (parent , stepUuid , new StepResult ().setName (stepName ));
98- else current .startStep (stepUuid , new StepResult ().setName (stepName ));
105+ if (parent != null ) {
106+ current .startStep (parent , stepUuid , new StepResult ().setName (stepName ));
107+ } else {
108+ current .startStep (stepUuid , new StepResult ().setName (stepName ));
109+ }
99110
100111 final StepContext <T , R > stepContext = new StepContext <>(
101- stepUuid , methodDescriptor , current , clientMessages , serverMessages , initialHeaders , trailers
112+ stepUuid , methodDescriptor , current , clientMessages ,
113+ serverMessages , initialHeaders , trailers
102114 );
103115
104116 return new ForwardingClientCall .SimpleForwardingClientCall <T , R >(
@@ -107,25 +119,35 @@ public <T, R> ClientCall<T, R> interceptCall(
107119 @ Override
108120 public void start (final Listener <R > responseListener , final Metadata requestHeaders ) {
109121 final Listener <R > forwardingListener = new ForwardingClientCallListener <R >() {
110- @ Override protected Listener <R > delegate () { return responseListener ; }
111- @ Override public void onHeaders (final Metadata headers ) {
112- handleHeaders (headers , stepContext .initialHeaders );
122+ @ Override
123+ protected Listener <R > delegate () {
124+ return responseListener ;
125+ }
126+
127+ @ Override
128+ public void onHeaders (final Metadata headers ) {
129+ handleHeaders (headers , stepContext .getInitialHeaders ());
113130 super .onHeaders (headers );
114131 }
115- @ Override public void onMessage (final R message ) {
116- handleServerMessage (message , stepContext .serverMessages );
132+
133+ @ Override
134+ public void onMessage (final R message ) {
135+ handleServerMessage (message , stepContext .getServerMessages ());
117136 super .onMessage (message );
118137 }
119- @ Override public void onClose (final io .grpc .Status status , final Metadata responseTrailers ) {
138+
139+ @ Override
140+ public void onClose (final io .grpc .Status status , final Metadata responseTrailers ) {
120141 handleClose (status , responseTrailers , stepContext );
121142 super .onClose (status , responseTrailers );
122143 }
123144 };
124145 super .start (forwardingListener , requestHeaders );
125146 }
147+
126148 @ Override
127149 public void sendMessage (final T message ) {
128- handleClientMessage (message , stepContext .clientMessages );
150+ handleClientMessage (message , stepContext .getClientMessages () );
129151 super .sendMessage (message );
130152 }
131153 };
@@ -142,34 +164,15 @@ private void addRawJsonAttachment(
142164 }
143165 final String source = UUID .randomUUID () + ".json" ;
144166 lifecycle .updateStep (stepUuid , step -> step .getAttachments ().add (
145- new Attachment ().setName (attachmentName ).setSource (source ).setType ("application/json" )
167+ new Attachment ()
168+ .setName (attachmentName )
169+ .setSource (source )
170+ .setType ("application/json" )
146171 ));
147- lifecycle .writeAttachment (source , new ByteArrayInputStream (jsonBody .getBytes (StandardCharsets .UTF_8 )));
148- }
149-
150- private static final class StepContext <T , R > {
151- final String stepUuid ;
152- final MethodDescriptor <T , R > methodDescriptor ;
153- final AllureLifecycle lifecycle ;
154- final List <String > clientMessages ;
155- final List <String > serverMessages ;
156- final Map <String , String > initialHeaders ;
157- final Map <String , String > trailers ;
158- StepContext (String stepUuid ,
159- MethodDescriptor <T , R > methodDescriptor ,
160- AllureLifecycle lifecycle ,
161- List <String > clientMessages ,
162- List <String > serverMessages ,
163- Map <String , String > initialHeaders ,
164- Map <String , String > trailers ) {
165- this .stepUuid = stepUuid ;
166- this .methodDescriptor = methodDescriptor ;
167- this .lifecycle = lifecycle ;
168- this .clientMessages = clientMessages ;
169- this .serverMessages = serverMessages ;
170- this .initialHeaders = initialHeaders ;
171- this .trailers = trailers ;
172- }
172+ lifecycle .writeAttachment (
173+ source ,
174+ new ByteArrayInputStream (jsonBody .getBytes (StandardCharsets .UTF_8 ))
175+ );
173176 }
174177
175178 private void handleClose (
@@ -179,25 +182,42 @@ private void handleClose(
179182 ) {
180183 try {
181184 if (interceptResponseMetadata && responseTrailers != null ) {
182- copyAsciiResponseMetadata (responseTrailers , stepContext .trailers );
185+ copyAsciiResponseMetadata (responseTrailers , stepContext .getTrailers () );
183186 }
184- attachRequestIfPresent (stepContext .stepUuid , stepContext .methodDescriptor ,
185- stepContext .clientMessages , stepContext .lifecycle );
186- attachResponse (stepContext .stepUuid , stepContext .serverMessages , status ,
187- stepContext .initialHeaders , stepContext .trailers , stepContext .lifecycle );
188- stepContext .lifecycle .updateStep (stepContext .stepUuid , step -> step .setStatus (convertStatus (status )));
187+ attachRequestIfPresent (
188+ stepContext .getStepUuid (),
189+ stepContext .getMethodDescriptor (),
190+ stepContext .getClientMessages (),
191+ stepContext .getLifecycle ()
192+ );
193+ attachResponse (
194+ stepContext .getStepUuid (),
195+ stepContext .getServerMessages (),
196+ status ,
197+ stepContext .getInitialHeaders (),
198+ stepContext .getTrailers (),
199+ stepContext .getLifecycle ()
200+ );
201+ stepContext .getLifecycle ().updateStep (
202+ stepContext .getStepUuid (),
203+ step -> step .setStatus (convertStatus (status ))
204+ );
189205 } catch (Throwable throwable ) {
190206 LOGGER .error ("Failed to finalize Allure step for gRPC call" , throwable );
191- stepContext .lifecycle .updateStep (stepContext .stepUuid , step -> step .setStatus (Status .BROKEN ));
207+ stepContext .getLifecycle ().updateStep (
208+ stepContext .getStepUuid (),
209+ step -> step .setStatus (Status .BROKEN )
210+ );
192211 } finally {
193- stopStepSafely (stepContext .lifecycle , stepContext .stepUuid );
212+ stopStepSafely (stepContext .getLifecycle () , stepContext .getStepUuid () );
194213 }
195214 }
196215
197216 private void handleHeaders (final Metadata headers , final Map <String , String > destination ) {
198217 try {
199- if (interceptResponseMetadata && headers != null )
218+ if (interceptResponseMetadata && headers != null ) {
200219 copyAsciiResponseMetadata (headers , destination );
220+ }
201221 } catch (Throwable throwable ) {
202222 LOGGER .warn ("Failed to capture response headers" , throwable );
203223 }
@@ -240,8 +260,15 @@ private <T, R> void attachRequestIfPresent(
240260 .create (name , methodDescriptor .getFullMethodName ())
241261 .setBody (body )
242262 .build ();
243- addRenderedAttachmentToStep (stepUuid , requestAttachment .getName (), requestAttachment , requestTemplatePath , lifecycle );
244- addRawJsonAttachment (stepUuid , name + " (json)" , body , lifecycle );
263+
264+ addRenderedAttachmentToStep (
265+ stepUuid ,
266+ requestAttachment .getName (),
267+ requestAttachment ,
268+ requestTemplatePath ,
269+ lifecycle
270+ );
271+ addRawJsonAttachment (stepUuid , name + JSON_SUFFIX , body , lifecycle );
245272 }
246273
247274 private void attachResponse (
@@ -266,17 +293,24 @@ private void attachResponse(
266293 final GrpcResponseAttachment .Builder builder = GrpcResponseAttachment .Builder
267294 .create (name )
268295 .setStatus (status .toString ());
296+
269297 if (body != null ) {
270298 builder .setBody (body );
271299 }
272300 if (!metadata .isEmpty ()) {
273301 builder .addMetadata (metadata );
274302 }
303+
275304 final GrpcResponseAttachment responseAttachment = builder .build ();
276- addRenderedAttachmentToStep (stepUuid , responseAttachment .getName (),
277- responseAttachment , responseTemplatePath , lifecycle );
305+ addRenderedAttachmentToStep (
306+ stepUuid ,
307+ responseAttachment .getName (),
308+ responseAttachment ,
309+ responseTemplatePath ,
310+ lifecycle
311+ );
278312 if (body != null ) {
279- addRawJsonAttachment (stepUuid , name + " (json)" , body , lifecycle );
313+ addRawJsonAttachment (stepUuid , name + JSON_SUFFIX , body , lifecycle );
280314 }
281315 }
282316
@@ -302,7 +336,8 @@ private static String buildStepName(
302336 final String authority = channel != null ? channel .authority () : null ;
303337 final String safeAuthority = authority != null ? authority : UNKNOWN ;
304338 final String type = toSnakeCase (methodDescriptor .getType ());
305- return "Send " + type + " gRPC request to " + safeAuthority + "/" + methodDescriptor .getFullMethodName ();
339+ return "Send " + type + " gRPC request to "
340+ + safeAuthority + "/" + methodDescriptor .getFullMethodName ();
306341 }
307342
308343 private static String toSnakeCase (final MethodDescriptor .MethodType methodType ) {
@@ -319,12 +354,16 @@ private void addRenderedAttachmentToStep(
319354 final String templatePath ,
320355 final AllureLifecycle lifecycle
321356 ) {
322- final AttachmentRenderer <AttachmentData > renderer = new FreemarkerAttachmentRenderer (templatePath );
357+ final AttachmentRenderer <AttachmentData > renderer =
358+ new FreemarkerAttachmentRenderer (templatePath );
323359 final io .qameta .allure .attachment .AttachmentContent content ;
324360 try {
325361 content = renderer .render (data );
326362 } catch (Throwable throwable ) {
327- LOGGER .warn ("Could not render attachment '{}' using template '{}'" , attachmentName , templatePath , throwable );
363+ LOGGER .warn (
364+ "Could not render attachment '{}' using template '{}'" ,
365+ attachmentName , templatePath , throwable
366+ );
328367 return ;
329368 }
330369 if (content == null || content .getContent () == null ) {
@@ -342,10 +381,17 @@ private void addRenderedAttachmentToStep(
342381 new Attachment ()
343382 .setName (attachmentName )
344383 .setSource (source )
345- .setType (content .getContentType () != null ? content .getContentType () : "text/html" )
384+ .setType (
385+ content .getContentType () != null
386+ ? content .getContentType ()
387+ : "text/html"
388+ )
346389 )
347390 );
348- lifecycle .writeAttachment (source , new ByteArrayInputStream (content .getContent ().getBytes (StandardCharsets .UTF_8 )));
391+ lifecycle .writeAttachment (
392+ source ,
393+ new ByteArrayInputStream (content .getContent ().getBytes (StandardCharsets .UTF_8 ))
394+ );
349395 }
350396
351397 private static String toJsonBody (final List <String > items ) {
@@ -359,19 +405,79 @@ private static String toJsonBody(final List<String> items) {
359405 return "[" + joined + "]" ;
360406 }
361407
362- private static void copyAsciiResponseMetadata (final Metadata source , final Map <String , String > target ) {
408+ private static void copyAsciiResponseMetadata (
409+ final Metadata source ,
410+ final Map <String , String > target
411+ ) {
363412 for (String key : source .keys ()) {
364413 if (key == null ) {
365414 continue ;
366415 }
367416 if (key .endsWith (Metadata .BINARY_HEADER_SUFFIX )) {
368417 continue ;
369418 }
370- final Metadata .Key <String > keyAscii = Metadata .Key .of (key , Metadata .ASCII_STRING_MARSHALLER );
419+ final Metadata .Key <String > keyAscii =
420+ Metadata .Key .of (key , Metadata .ASCII_STRING_MARSHALLER );
371421 final String value = source .get (keyAscii );
372422 if (value != null ) {
373423 target .put (key , value );
374424 }
375425 }
376426 }
427+
428+ private static final class StepContext <T , R > {
429+ private final String stepUuid ;
430+ private final MethodDescriptor <T , R > methodDescriptor ;
431+ private final AllureLifecycle lifecycle ;
432+ private final List <String > clientMessages ;
433+ private final List <String > serverMessages ;
434+ private final Map <String , String > initialHeaders ;
435+ private final Map <String , String > trailers ;
436+
437+ StepContext (
438+ final String stepUuid ,
439+ final MethodDescriptor <T , R > methodDescriptor ,
440+ final AllureLifecycle lifecycle ,
441+ final List <String > clientMessages ,
442+ final List <String > serverMessages ,
443+ final Map <String , String > initialHeaders ,
444+ final Map <String , String > trailers
445+ ) {
446+ this .stepUuid = stepUuid ;
447+ this .methodDescriptor = methodDescriptor ;
448+ this .lifecycle = lifecycle ;
449+ this .clientMessages = clientMessages ;
450+ this .serverMessages = serverMessages ;
451+ this .initialHeaders = initialHeaders ;
452+ this .trailers = trailers ;
453+ }
454+
455+ String getStepUuid () {
456+ return stepUuid ;
457+ }
458+
459+ MethodDescriptor <T , R > getMethodDescriptor () {
460+ return methodDescriptor ;
461+ }
462+
463+ AllureLifecycle getLifecycle () {
464+ return lifecycle ;
465+ }
466+
467+ List <String > getClientMessages () {
468+ return clientMessages ;
469+ }
470+
471+ List <String > getServerMessages () {
472+ return serverMessages ;
473+ }
474+
475+ Map <String , String > getInitialHeaders () {
476+ return initialHeaders ;
477+ }
478+
479+ Map <String , String > getTrailers () {
480+ return trailers ;
481+ }
482+ }
377483}
0 commit comments