18
18
use std:: { collections:: HashMap , sync:: Arc } ;
19
19
20
20
use rocketmq_common:: common:: { broker:: broker_config:: BrokerConfig , config_manager:: ConfigManager } ;
21
- use rocketmq_remoting:: protocol:: {
22
- body:: topic_info_wrapper:: topic_queue_wrapper:: TopicQueueMappingSerializeWrapper ,
23
- header:: message_operation_header:: TopicRequestHeaderTrait ,
24
- remoting_command:: RemotingCommand ,
25
- static_topic:: {
26
- topic_queue_mapping_context:: TopicQueueMappingContext ,
27
- topic_queue_mapping_detail:: TopicQueueMappingDetail ,
21
+ use rocketmq_remoting:: {
22
+ code:: response_code:: ResponseCode ,
23
+ protocol:: {
24
+ body:: topic_info_wrapper:: topic_queue_wrapper:: TopicQueueMappingSerializeWrapper ,
25
+ header:: message_operation_header:: TopicRequestHeaderTrait ,
26
+ remoting_command:: RemotingCommand ,
27
+ static_topic:: {
28
+ topic_queue_mapping_context:: TopicQueueMappingContext ,
29
+ topic_queue_mapping_detail:: TopicQueueMappingDetail ,
30
+ } ,
31
+ DataVersion , RemotingSerializable ,
28
32
} ,
29
- DataVersion ,
30
33
} ;
34
+ use tracing:: { info, warn} ;
31
35
32
36
use crate :: broker_path_config_helper:: get_topic_queue_mapping_path;
33
37
@@ -47,6 +51,35 @@ impl TopicQueueMappingManager {
47
51
}
48
52
}
49
53
54
+ pub ( crate ) fn rewrite_request_for_static_topic (
55
+ request_header : & mut impl TopicRequestHeaderTrait ,
56
+ mapping_context : & TopicQueueMappingContext ,
57
+ ) -> Option < RemotingCommand > {
58
+ mapping_context. mapping_detail . as_ref ( ) ?;
59
+
60
+ if !mapping_context. is_leader ( ) {
61
+ let mapping_detail = mapping_context. mapping_detail . as_ref ( ) . unwrap ( ) ;
62
+ return Some ( RemotingCommand :: create_response_command_with_code_remark (
63
+ ResponseCode :: NotLeaderForQueue ,
64
+ format ! (
65
+ "{}-{:?} does not exit in request process of current broker {}" ,
66
+ request_header. topic( ) ,
67
+ request_header. queue_id( ) ,
68
+ mapping_detail
69
+ . topic_queue_mapping_info
70
+ . bname
71
+ . clone( )
72
+ . unwrap_or_default( )
73
+ ) ,
74
+ ) ) ;
75
+ }
76
+ let mapping_item = mapping_context. leader_item . as_ref ( ) . unwrap ( ) ;
77
+ request_header. set_queue_id ( Some ( mapping_item. queue_id ) ) ;
78
+ None
79
+ }
80
+ }
81
+
82
+ impl TopicQueueMappingManager {
50
83
pub ( crate ) fn build_topic_queue_mapping_context (
51
84
& self ,
52
85
request_header : & impl TopicRequestHeaderTrait ,
@@ -66,13 +99,8 @@ impl TopicQueueMappingManager {
66
99
}
67
100
let topic = request_header. topic ( ) ;
68
101
69
- let mut global_id: Option < i32 > = None ;
70
- /*if let Some(header) = request_header
71
- .as_any()
72
- .downcast_ref::<TopicQueueRequestHeaderT>()
73
- {
74
- global_id = header.queue_id;
75
- }*/
102
+ let mut global_id: Option < i32 > = request_header. queue_id ( ) ;
103
+
76
104
if let Some ( mapping_detail) = self . topic_queue_mapping_table . lock ( ) . get ( & topic) {
77
105
// it is not static topic
78
106
if mapping_detail
@@ -164,41 +192,45 @@ impl TopicQueueMappingManager {
164
192
}
165
193
}
166
194
167
- pub ( crate ) fn rewrite_request_for_static_topic (
168
- & self ,
169
- _request_header : & impl TopicRequestHeaderTrait ,
170
- _mapping_context : & TopicQueueMappingContext ,
171
- ) -> Option < RemotingCommand > {
172
- //TODO
173
- None
174
- }
175
-
176
195
pub fn get_topic_queue_mapping ( & self , topic : & str ) -> Option < TopicQueueMappingDetail > {
177
196
self . topic_queue_mapping_table . lock ( ) . get ( topic) . cloned ( )
178
197
}
198
+
199
+ pub fn delete ( & self , topic : & str ) {
200
+ let old = self . topic_queue_mapping_table . lock ( ) . remove ( topic) ;
201
+ match old {
202
+ None => {
203
+ warn ! (
204
+ "delete topic queue mapping failed, static topic: {} not exists" ,
205
+ topic
206
+ )
207
+ }
208
+ Some ( value) => {
209
+ info ! (
210
+ "delete topic queue mapping OK, static topic queue mapping: {:?}" ,
211
+ value
212
+ ) ;
213
+ self . data_version . lock ( ) . next_version ( ) ;
214
+ self . persist ( ) ;
215
+ }
216
+ }
217
+ }
179
218
}
180
219
181
220
//Fully implemented will be removed
182
- #[ allow( unused_variables) ]
183
221
impl ConfigManager for TopicQueueMappingManager {
184
- fn decode0 ( & mut self , key : & [ u8 ] , body : & [ u8 ] ) {
185
- todo ! ( )
186
- }
187
-
188
- fn stop ( & mut self ) -> bool {
189
- todo ! ( )
190
- }
191
-
192
222
fn config_file_path ( & self ) -> String {
193
223
get_topic_queue_mapping_path ( self . broker_config . store_path_root_dir . as_str ( ) )
194
224
}
195
-
196
- fn encode ( & mut self ) -> String {
197
- todo ! ( )
198
- }
199
-
200
225
fn encode_pretty ( & self , pretty_format : bool ) -> String {
201
- todo ! ( )
226
+ let wrapper = TopicQueueMappingSerializeWrapper :: new (
227
+ Some ( self . topic_queue_mapping_table . lock ( ) . clone ( ) ) ,
228
+ Some ( self . data_version . lock ( ) . clone ( ) ) ,
229
+ ) ;
230
+ match pretty_format {
231
+ true => wrapper. to_json_pretty ( ) ,
232
+ false => wrapper. to_json ( ) ,
233
+ }
202
234
}
203
235
204
236
fn decode ( & self , json_string : & str ) {
@@ -219,3 +251,60 @@ impl ConfigManager for TopicQueueMappingManager {
219
251
}
220
252
}
221
253
}
254
+
255
+ #[ cfg( test) ]
256
+ mod tests {
257
+ use std:: sync:: Arc ;
258
+
259
+ use rocketmq_common:: common:: broker:: broker_config:: BrokerConfig ;
260
+
261
+ use super :: * ;
262
+
263
+ #[ test]
264
+ fn new_creates_default_manager ( ) {
265
+ let broker_config = Arc :: new ( BrokerConfig :: default ( ) ) ;
266
+ let manager = TopicQueueMappingManager :: new ( broker_config. clone ( ) ) ;
267
+
268
+ assert_eq ! ( Arc :: ptr_eq( & manager. broker_config, & broker_config) , true ) ;
269
+ assert_eq ! ( manager. data_version. lock( ) . get_state_version( ) , 0 ) ;
270
+ assert_eq ! ( manager. topic_queue_mapping_table. lock( ) . len( ) , 0 ) ;
271
+ }
272
+
273
+ #[ test]
274
+ fn get_topic_queue_mapping_returns_none_for_non_existent_topic ( ) {
275
+ let broker_config = Arc :: new ( BrokerConfig :: default ( ) ) ;
276
+ let manager = TopicQueueMappingManager :: new ( broker_config) ;
277
+
278
+ assert ! ( manager
279
+ . get_topic_queue_mapping( "non_existent_topic" )
280
+ . is_none( ) ) ;
281
+ }
282
+
283
+ #[ test]
284
+ fn get_topic_queue_mapping_returns_mapping_for_existing_topic ( ) {
285
+ let broker_config = Arc :: new ( BrokerConfig :: default ( ) ) ;
286
+ let manager = TopicQueueMappingManager :: new ( broker_config) ;
287
+ let detail = TopicQueueMappingDetail :: default ( ) ;
288
+ manager
289
+ . topic_queue_mapping_table
290
+ . lock ( )
291
+ . insert ( "existing_topic" . to_string ( ) , detail. clone ( ) ) ;
292
+
293
+ assert ! ( manager. get_topic_queue_mapping( "existing_topic" ) . is_some( ) ) ;
294
+ }
295
+
296
+ #[ test]
297
+ fn delete_removes_existing_topic ( ) {
298
+ let broker_config = Arc :: new ( BrokerConfig :: default ( ) ) ;
299
+ let manager = TopicQueueMappingManager :: new ( broker_config) ;
300
+ let detail = TopicQueueMappingDetail :: default ( ) ;
301
+ manager
302
+ . topic_queue_mapping_table
303
+ . lock ( )
304
+ . insert ( "existing_topic" . to_string ( ) , detail. clone ( ) ) ;
305
+
306
+ manager. delete ( "existing_topic" ) ;
307
+
308
+ assert ! ( manager. get_topic_queue_mapping( "existing_topic" ) . is_none( ) ) ;
309
+ }
310
+ }
0 commit comments