@@ -27,10 +27,22 @@ public final class QosReasons {
2727 private static final String DUE_TO_HEADER = "Qos-Due-To" ;
2828 private static final String RETRY_HINT_HEADER = "Qos-Retry-Hint" ;
2929
30+ private static final String DUE_TO_CUSTOM_HEADER_VALUE = "custom" ;
31+ private static final String RETRY_HINT_PROPAGATE_HEADER_VALUE = "propagate" ;
32+
3033 public static <T > void encodeToResponse (
3134 QosReason reason , T response , QosResponseEncodingAdapter <? super T > adapter ) {
32- reason .dueTo ().ifPresent (dueTo -> adapter .setHeader (response , DUE_TO_HEADER , dueTo .name ()));
33- reason .retryHint ().ifPresent (retryHint -> adapter .setHeader (response , RETRY_HINT_HEADER , retryHint .name ()));
35+ // Likely hot path, avoid ifPresent lambda
36+ if (reason .dueTo ().isPresent ()) {
37+ adapter .setHeader (
38+ response , DUE_TO_HEADER , toHeaderValue (reason .dueTo ().get ()));
39+ }
40+ if (reason .retryHint ().isPresent ()) {
41+ adapter .setHeader (
42+ response ,
43+ RETRY_HINT_HEADER ,
44+ toHeaderValue (reason .retryHint ().get ()));
45+ }
3446 }
3547
3648 public static <T > QosReason parseFromResponse (T response , QosResponseDecodingAdapter <? super T > adapter ) {
@@ -41,8 +53,8 @@ public static <T> QosReason parseFromResponse(T response, QosResponseDecodingAda
4153 }
4254 return QosReason .builder ()
4355 .reason (CLIENT_REASON )
44- .dueTo (maybeDueTo .flatMap (value -> parse ( DueTo . class , value ) ))
45- .retryHint (maybeRetryHint .flatMap (value -> parse ( RetryHint . class , value ) ))
56+ .dueTo (maybeDueTo .flatMap (QosReasons :: parseDueTo ))
57+ .retryHint (maybeRetryHint .flatMap (QosReasons :: parseRetryHint ))
4658 .build ();
4759 }
4860
@@ -54,12 +66,34 @@ public interface QosResponseDecodingAdapter<RESPONSE> {
5466 Optional <String > getFirstHeader (RESPONSE response , String headerName );
5567 }
5668
57- private static <T extends Enum <T >> Optional <T > parse (Class <T > type , String value ) {
58- try {
59- return Optional .of (Enum .valueOf (type , value ));
60- } catch (IllegalArgumentException ignored ) {
61- return Optional .empty ();
69+ // VisibleForTesting
70+ static Optional <DueTo > parseDueTo (String dueTo ) {
71+ if (DUE_TO_CUSTOM_HEADER_VALUE .equalsIgnoreCase (dueTo )) {
72+ return Optional .of (DueTo .CUSTOM );
73+ }
74+ return Optional .empty ();
75+ }
76+
77+ // VisibleForTesting
78+ static Optional <RetryHint > parseRetryHint (String retryHint ) {
79+ if (RETRY_HINT_PROPAGATE_HEADER_VALUE .equalsIgnoreCase (retryHint )) {
80+ return Optional .of (RetryHint .PROPAGATE );
6281 }
82+ return Optional .empty ();
83+ }
84+
85+ // VisibleForTesting
86+ static String toHeaderValue (DueTo dueTo ) {
87+ return switch (dueTo ) {
88+ case CUSTOM -> DUE_TO_CUSTOM_HEADER_VALUE ;
89+ };
90+ }
91+
92+ // VisibleForTesting
93+ static String toHeaderValue (RetryHint retryHint ) {
94+ return switch (retryHint ) {
95+ case PROPAGATE -> RETRY_HINT_PROPAGATE_HEADER_VALUE ;
96+ };
6397 }
6498
6599 private QosReasons () {}
0 commit comments