|
15 | 15 |
|
16 | 16 | %% Supported versions of THIS lib
|
17 | 17 | -module(kpro_api_vsn).
|
18 |
| --export([range/1, kafka_09_range/1, intersect/2]). |
| 18 | +-export([range/1, kafka_09_range/1, intersect/1, intersect/2]). |
19 | 19 |
|
20 | 20 | -export_type([range/0]).
|
21 | 21 |
|
@@ -54,19 +54,76 @@ kafka_09_range(describe_groups) -> {0, 0};
|
54 | 54 | kafka_09_range(list_groups) -> {0, 0};
|
55 | 55 | kafka_09_range(_) -> false.
|
56 | 56 |
|
57 |
| -%% @doc Returns the intersection of two version ranges. |
| 57 | +%% @private Returns the intersection of two version ranges. |
58 | 58 | %% An error is raised if there is no intersection.
|
59 |
| --spec intersect(false | range(), false | range()) -> false | range(). |
60 |
| -intersect(false, _) -> false; |
61 |
| -intersect(_, false) -> false; |
62 |
| -intersect({Min1, Max1} = R1, {Min2, Max2} = R2) -> |
63 |
| - Min = max(Min1, Min2), |
64 |
| - Max = min(Max1, Max2), |
| 59 | +-spec intersect(atom(), false | range(), false | range()) -> false | range(). |
| 60 | +intersect(_API, false, _) -> false; |
| 61 | +intersect(_API, _, false) -> false; |
| 62 | +intersect(API, {Min0, Max0} = Supported, {Min1, Max1} = Received) -> |
| 63 | + {Min2, Max2} = fix_range(API, Min1, Max1), |
| 64 | + Min = max(Min0, Min2), |
| 65 | + Max = min(Max0, Max2), |
65 | 66 | case Min > Max of
|
66 |
| - true -> erlang:error({no_intersection, R1, R2}); |
| 67 | + true -> erlang:error({no_intersection, Supported, Received}); |
67 | 68 | false -> {Min, Max}
|
68 | 69 | end.
|
69 | 70 |
|
| 71 | +%% Special adjustment for received API range. |
| 72 | +%% - produce: Minimal version is in fact 3, but Kafka may respond 0. |
| 73 | +%% - fetch: Minimal version is in fact 4, but Kafka may respond 0. |
| 74 | +fix_range(produce, Min, Max) -> |
| 75 | + case Max >= 8 of |
| 76 | + true -> |
| 77 | + {max(Min, 3), Max}; |
| 78 | + false -> |
| 79 | + {Min, Max} |
| 80 | + end; |
| 81 | +fix_range(fetch, Min, Max) -> |
| 82 | + case Max >= 11 of |
| 83 | + true -> |
| 84 | + {max(Min, 4), Max}; |
| 85 | + false -> |
| 86 | + {Min, Max} |
| 87 | + end; |
| 88 | +fix_range(_API, Min, Max) -> |
| 89 | + {Min, Max}. |
| 90 | + |
| 91 | +%% @doc Return the intersection of supported version ranges and received version ranges. |
| 92 | +-spec intersect(undefined | list()) -> #{atom() => range()}. |
| 93 | +intersect(undefined) -> |
| 94 | + %% kpro_connection is configured not to query api versions (kafka-0.9) |
| 95 | + %% always use minimum supported version in this case |
| 96 | + lists:foldl( |
| 97 | + fun(API, Acc) -> |
| 98 | + case kpro_api_vsn:kafka_09_range(API) of |
| 99 | + false -> Acc; |
| 100 | + {Min, _Max} -> Acc#{API => {Min, Min}} |
| 101 | + end |
| 102 | + end, #{}, kpro_schema:all_apis()); |
| 103 | +intersect(Vsns) -> |
| 104 | + maps:fold( |
| 105 | + fun(API, {Min, Max}, Acc) -> |
| 106 | + case intersect(API, {Min, Max}) of |
| 107 | + false -> Acc; |
| 108 | + Intersection -> Acc#{API => Intersection} |
| 109 | + end |
| 110 | + end, #{}, Vsns). |
| 111 | + |
| 112 | +%% @doc Intersect received api version range with supported range. |
| 113 | +-spec intersect(kpro:api(), range()) -> range(). |
| 114 | +intersect(API, Received) -> |
| 115 | + Supported = kpro_api_vsn:range(API), |
| 116 | + try |
| 117 | + intersect(API, Supported, Received) |
| 118 | + catch |
| 119 | + error : {no_intersection, _, _} -> |
| 120 | + Reason = #{reason => incompatible_version_ranges, |
| 121 | + supported => Supported, |
| 122 | + received => Received, |
| 123 | + api => API}, |
| 124 | + erlang:error(Reason) |
| 125 | + end. |
| 126 | + |
70 | 127 | %%%_* Emacs ====================================================================
|
71 | 128 | %%% Local Variables:
|
72 | 129 | %%% allout-layout: t
|
|
0 commit comments