@@ -83,14 +83,15 @@ public class AllureGrpc implements ClientInterceptor {
8383
8484 private final AllureLifecycle lifecycle ;
8585 private final boolean markStepFailedOnNonZeroCode ;
86+ private final boolean interceptRequestMetadata ;
8687 private final boolean interceptResponseMetadata ;
8788 private final Consumer <HttpExchange .Builder > exchangeCustomizer ;
8889
8990 /**
9091 * Creates an Allure grpc with default configuration.
9192 */
9293 public AllureGrpc () {
93- this (Allure .getLifecycle (), true , false );
94+ this (Allure .getLifecycle (), true , false , false );
9495 }
9596
9697 /**
@@ -104,25 +105,72 @@ public AllureGrpc(
104105 final AllureLifecycle lifecycle ,
105106 final boolean markStepFailedOnNonZeroCode ,
106107 final boolean interceptResponseMetadata ) {
107- this (lifecycle , markStepFailedOnNonZeroCode , interceptResponseMetadata , builder -> {
108- });
108+ this (lifecycle , markStepFailedOnNonZeroCode , false , interceptResponseMetadata );
109109 }
110110
111111 /**
112112 * Creates an Allure grpc with the supplied values.
113113 *
114114 * @param lifecycle the Allure lifecycle to use
115115 * @param markStepFailedOnNonZeroCode the mark step failed on non zero code
116+ * @param interceptRequestMetadata the intercept request metadata
117+ * @param interceptResponseMetadata the intercept response metadata
118+ */
119+ public AllureGrpc (
120+ final AllureLifecycle lifecycle ,
121+ final boolean markStepFailedOnNonZeroCode ,
122+ final boolean interceptRequestMetadata ,
123+ final boolean interceptResponseMetadata ) {
124+ this (
125+ lifecycle ,
126+ markStepFailedOnNonZeroCode ,
127+ interceptRequestMetadata ,
128+ interceptResponseMetadata ,
129+ builder -> {
130+ }
131+ );
132+ }
133+
134+ /**
135+ * Creates an Allure grpc with the supplied values.
136+ *
137+ * @param lifecycle the Allure lifecycle to use
138+ * @param markStepFailedOnNonZeroCode the mark step failed on non zero code
139+ * @param interceptResponseMetadata the intercept response metadata
140+ * @param exchangeCustomizer the HTTP exchange builder customizer
141+ */
142+ public AllureGrpc (
143+ final AllureLifecycle lifecycle ,
144+ final boolean markStepFailedOnNonZeroCode ,
145+ final boolean interceptResponseMetadata ,
146+ final Consumer <HttpExchange .Builder > exchangeCustomizer ) {
147+ this (
148+ lifecycle ,
149+ markStepFailedOnNonZeroCode ,
150+ false ,
151+ interceptResponseMetadata ,
152+ exchangeCustomizer
153+ );
154+ }
155+
156+ /**
157+ * Creates an Allure grpc with the supplied values.
158+ *
159+ * @param lifecycle the Allure lifecycle to use
160+ * @param markStepFailedOnNonZeroCode the mark step failed on non zero code
161+ * @param interceptRequestMetadata the intercept request metadata
116162 * @param interceptResponseMetadata the intercept response metadata
117163 * @param exchangeCustomizer the HTTP exchange builder customizer
118164 */
119165 public AllureGrpc (
120166 final AllureLifecycle lifecycle ,
121167 final boolean markStepFailedOnNonZeroCode ,
168+ final boolean interceptRequestMetadata ,
122169 final boolean interceptResponseMetadata ,
123170 final Consumer <HttpExchange .Builder > exchangeCustomizer ) {
124171 this .lifecycle = lifecycle ;
125172 this .markStepFailedOnNonZeroCode = markStepFailedOnNonZeroCode ;
173+ this .interceptRequestMetadata = interceptRequestMetadata ;
126174 this .interceptResponseMetadata = interceptResponseMetadata ;
127175 this .exchangeCustomizer = exchangeCustomizer == null ? builder -> {
128176 } : exchangeCustomizer ;
@@ -143,6 +191,7 @@ public <T, R> ClientCall<T, R> interceptCall(
143191 final long start = System .currentTimeMillis ();
144192 final List <String > clientMessages = new ArrayList <>();
145193 final List <String > serverMessages = new ArrayList <>();
194+ final Map <String , String > capturedRequestHeaders = new LinkedHashMap <>();
146195 final Map <String , String > initialHeaders = new LinkedHashMap <>();
147196 final Map <String , String > trailers = new LinkedHashMap <>();
148197 final String authority = channel .authority ();
@@ -164,6 +213,7 @@ public <T, R> ClientCall<T, R> interceptCall(
164213 ) {
165214 @ Override
166215 public void start (final Listener <R > responseListener , final Metadata requestHeaders ) {
216+ handleRequestHeaders (requestHeaders , capturedRequestHeaders );
167217 final Listener <R > forwardingListener = new ForwardingClientCallListener <R >() {
168218 @ Override
169219 protected Listener <R > delegate () {
@@ -184,7 +234,7 @@ public void onMessage(final R message) {
184234
185235 @ Override
186236 public void onClose (final io .grpc .Status status , final Metadata responseTrailers ) {
187- handleClose (status , responseTrailers , stepContext );
237+ handleClose (status , responseTrailers , stepContext , capturedRequestHeaders );
188238 super .onClose (status , responseTrailers );
189239 }
190240 };
@@ -202,12 +252,13 @@ public void sendMessage(final T message) {
202252 private void handleClose (
203253 final io .grpc .Status status ,
204254 final Metadata responseTrailers ,
205- final StepContext <?, ?> stepContext ) {
255+ final StepContext <?, ?> stepContext ,
256+ final Map <String , String > requestHeaders ) {
206257 try {
207258 if (interceptResponseMetadata && responseTrailers != null ) {
208- copyAsciiResponseMetadata (responseTrailers , stepContext .getTrailers ());
259+ copyAsciiMetadata (responseTrailers , stepContext .getTrailers ());
209260 }
210- attachExchange (stepContext , status );
261+ attachExchange (stepContext , status , requestHeaders );
211262 stepContext .getLifecycle ().updateStep (
212263 stepContext .getStepUuid (),
213264 step -> step .setStatus (convertStatus (status ))
@@ -226,13 +277,23 @@ private void handleClose(
226277 private void handleHeaders (final Metadata headers , final Map <String , String > destination ) {
227278 try {
228279 if (interceptResponseMetadata && headers != null ) {
229- copyAsciiResponseMetadata (headers , destination );
280+ copyAsciiMetadata (headers , destination );
230281 }
231282 } catch (Throwable throwable ) {
232283 LOGGER .warn ("Failed to capture response headers" , throwable );
233284 }
234285 }
235286
287+ private void handleRequestHeaders (final Metadata headers , final Map <String , String > destination ) {
288+ try {
289+ if (interceptRequestMetadata && headers != null ) {
290+ copyAsciiMetadata (headers , destination );
291+ }
292+ } catch (Throwable throwable ) {
293+ LOGGER .warn ("Failed to capture request headers" , throwable );
294+ }
295+ }
296+
236297 private <T > void handleClientMessage (final T message , final List <String > destination ) {
237298 try {
238299 destination .add (GRPC_TO_JSON_PRINTER .print ((MessageOrBuilder ) message ));
@@ -253,10 +314,14 @@ private <R> void handleServerMessage(final R message, final List<String> destina
253314 }
254315 }
255316
256- private void attachExchange (final StepContext <?, ?> stepContext , final io .grpc .Status status ) {
317+ private void attachExchange (
318+ final StepContext <?, ?> stepContext ,
319+ final io .grpc .Status status ,
320+ final Map <String , String > requestHeaders ) {
257321 final HttpExchangeRequest request = buildRequest (
258322 stepContext .getMethodDescriptor (),
259323 stepContext .getClientMessages (),
324+ requestHeaders ,
260325 stepContext .getAuthority ()
261326 );
262327 final HttpExchangeResponse response = buildResponse (
@@ -283,6 +348,7 @@ private HttpExchange.Builder exchangeBuilder(final HttpExchangeRequest request)
283348 private HttpExchangeRequest buildRequest (
284349 final MethodDescriptor <?, ?> methodDescriptor ,
285350 final List <String > clientMessages ,
351+ final Map <String , String > requestHeaders ,
286352 final String authority ) {
287353 final HttpExchangeRequest .Builder builder = HttpExchangeRequest .builder (
288354 HTTP_METHOD ,
@@ -294,6 +360,9 @@ private HttpExchangeRequest buildRequest(
294360 if (authority != null ) {
295361 builder .addHeader (":authority" , authority );
296362 }
363+ if (interceptRequestMetadata ) {
364+ requestHeaders .forEach (builder ::addHeader );
365+ }
297366 return builder
298367 .setBody (toHttpBody (clientMessages , isRequestStreaming (methodDescriptor .getType ())))
299368 .build ();
@@ -429,9 +498,9 @@ private static boolean isResponseStreaming(final MethodDescriptor.MethodType met
429498 || methodType == MethodDescriptor .MethodType .BIDI_STREAMING ;
430499 }
431500
432- private static void copyAsciiResponseMetadata (
433- final Metadata source ,
434- final Map <String , String > target ) {
501+ private static void copyAsciiMetadata (
502+ final Metadata source ,
503+ final Map <String , String > target ) {
435504 for (String key : source .keys ()) {
436505 if (key == null ) {
437506 continue ;
0 commit comments