3131import java .util .List ;
3232import java .util .Map ;
3333import java .util .concurrent .ConcurrentHashMap ;
34+ import lombok .Getter ;
3435import org .apache .commons .lang3 .mutable .MutableLong ;
3536import org .apache .pulsar .common .api .proto .BaseCommand ;
3637import org .apache .pulsar .common .api .raw .MessageParser ;
3738import org .apache .pulsar .common .api .raw .RawMessage ;
3839import org .apache .pulsar .common .naming .TopicName ;
40+ import org .apache .pulsar .common .util .StringInterner ;
3941import org .apache .pulsar .proxy .stats .TopicStats ;
4042import org .slf4j .Logger ;
4143import org .slf4j .LoggerFactory ;
@@ -53,27 +55,41 @@ public class ParserProxyHandler extends ChannelInboundHandlerAdapter {
5355
5456 private final int maxMessageSize ;
5557 private final ChannelId peerChannelId ;
58+ @ Getter
59+ private final Context context ;
5660 private final ProxyService service ;
5761
5862
59- /**
60- * producerid + channelid as key.
61- */
62- private static final Map <String , String > producerHashMap = new ConcurrentHashMap <>();
63+ public static class Context {
64+ /**
65+ * producerid as key.
66+ */
67+ @ Getter
68+ private final Map <Long , String > producerIdToTopicName = new ConcurrentHashMap <>();
6369
64- /**
65- * consumerid + channelid as key.
66- */
67- private static final Map <String , String > consumerHashMap = new ConcurrentHashMap <>();
70+ /**
71+ * consumerid as key.
72+ */
73+ @ Getter
74+ private final Map <Long , String > consumerIdToTopicName = new ConcurrentHashMap <>();
6875
69- public ParserProxyHandler (ProxyService service , String type , int maxMessageSize ,
76+ private Context () {
77+ }
78+ }
79+
80+ public ParserProxyHandler (Context context , ProxyService service , String type , int maxMessageSize ,
7081 ChannelId peerChannelId ) {
82+ this .context = context ;
7183 this .service = service ;
7284 this .connType = type ;
7385 this .maxMessageSize = maxMessageSize ;
7486 this .peerChannelId = peerChannelId ;
7587 }
7688
89+ public static Context createContext () {
90+ return new Context ();
91+ }
92+
7793 private void logging (Channel conn , BaseCommand .Type cmdtype , String info , List <RawMessage > messages ) {
7894
7995 if (messages != null ) {
@@ -115,64 +131,86 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) {
115131
116132 switch (cmd .getType ()) {
117133 case PRODUCER :
118- ParserProxyHandler . producerHashMap . put (cmd .getProducer ().getProducerId () + "," + ctx . channel (). id (),
119- cmd .getProducer ().getTopic () );
134+ topicName = StringInterner . intern (cmd .getProducer ().getTopic ());
135+ context . producerIdToTopicName . put ( cmd .getProducer ().getProducerId (), topicName );
120136
121137 String producerName = "" ;
122138 if (cmd .getProducer ().hasProducerName ()){
123139 producerName = cmd .getProducer ().getProducerName ();
124140 }
125141 logging (ctx .channel (), cmd .getType (), "{producer:" + producerName
126- + ",topic:" + cmd .getProducer ().getTopic () + "}" , null );
142+ + ",topic:" + topicName + "}" , null );
143+ break ;
144+ case CLOSE_PRODUCER :
145+ context .producerIdToTopicName .remove (cmd .getCloseProducer ().getProducerId ());
146+ logging (ctx .channel (), cmd .getType (), "" , null );
127147 break ;
128-
129148 case SEND :
130149 if (service .getProxyLogLevel () != 2 ) {
131150 logging (ctx .channel (), cmd .getType (), "" , null );
132151 break ;
133152 }
134- topicName = TopicName .toFullTopicName (ParserProxyHandler .producerHashMap .get (
135- cmd .getSend ().getProducerId () + "," + ctx .channel ().id ()));
136- MutableLong msgBytes = new MutableLong (0 );
137- MessageParser .parseMessage (topicName , -1L ,
138- -1L , buffer , (message ) -> {
139- messages .add (message );
140- msgBytes .add (message .getData ().readableBytes ());
141- }, maxMessageSize );
142- // update topic stats
143- TopicStats topicStats = this .service .getTopicStats ().computeIfAbsent (topicName ,
144- topic -> new TopicStats ());
145- topicStats .getMsgInRate ().recordMultipleEvents (messages .size (), msgBytes .longValue ());
146- logging (ctx .channel (), cmd .getType (), "" , messages );
153+ long producerId = cmd .getSend ().getProducerId ();
154+ String topicForProducer = context .producerIdToTopicName .get (producerId );
155+ if (topicForProducer != null ) {
156+ topicName = TopicName .toFullTopicName (topicForProducer );
157+ MutableLong msgBytes = new MutableLong (0 );
158+ MessageParser .parseMessage (topicName , -1L ,
159+ -1L , buffer , (message ) -> {
160+ messages .add (message );
161+ msgBytes .add (message .getData ().readableBytes ());
162+ }, maxMessageSize );
163+ // update topic stats
164+ TopicStats topicStats = this .service .getTopicStats ().computeIfAbsent (topicName ,
165+ topic -> new TopicStats ());
166+ topicStats .getMsgInRate ().recordMultipleEvents (messages .size (), msgBytes .longValue ());
167+ logging (ctx .channel (), cmd .getType (), "" , messages );
168+ } else {
169+ logging (ctx .channel (), cmd .getType (),
170+ "Cannot find topic name for producerId " + producerId , null );
171+ }
147172 break ;
148173
149174 case SUBSCRIBE :
150- ParserProxyHandler . consumerHashMap . put (cmd .getSubscribe ().getConsumerId () + ","
151- + ctx . channel (). id (), cmd .getSubscribe ().getTopic () );
175+ topicName = StringInterner . intern (cmd .getSubscribe ().getTopic ());
176+ context . consumerIdToTopicName . put ( cmd .getSubscribe ().getConsumerId (), topicName );
152177
153178 logging (ctx .channel (), cmd .getType (), "{consumer:" + cmd .getSubscribe ().getConsumerName ()
154- + ",topic:" + cmd .getSubscribe ().getTopic () + "}" , null );
179+ + ",topic:" + topicName + "}" , null );
180+ break ;
181+ case CLOSE_CONSUMER :
182+ context .consumerIdToTopicName .remove (cmd .getCloseConsumer ().getConsumerId ());
183+ logging (ctx .channel (), cmd .getType (), "" , null );
184+ break ;
185+ case UNSUBSCRIBE :
186+ context .consumerIdToTopicName .remove (cmd .getUnsubscribe ().getConsumerId ());
187+ logging (ctx .channel (), cmd .getType (), "" , null );
155188 break ;
156-
157189 case MESSAGE :
158190 if (service .getProxyLogLevel () != 2 ) {
159191 logging (ctx .channel (), cmd .getType (), "" , null );
160192 break ;
161193 }
162- topicName = TopicName .toFullTopicName (ParserProxyHandler .consumerHashMap .get (
163- cmd .getMessage ().getConsumerId () + "," + peerChannelId ));
164-
165- msgBytes = new MutableLong (0 );
166- MessageParser .parseMessage (topicName , -1L ,
167- -1L , buffer , (message ) -> {
168- messages .add (message );
169- msgBytes .add (message .getData ().readableBytes ());
170- }, maxMessageSize );
171- // update topic stats
172- topicStats = this .service .getTopicStats ().computeIfAbsent (topicName .toString (),
173- topic -> new TopicStats ());
174- topicStats .getMsgOutRate ().recordMultipleEvents (messages .size (), msgBytes .longValue ());
175- logging (ctx .channel (), cmd .getType (), "" , messages );
194+ long consumerId = cmd .getMessage ().getConsumerId ();
195+ String topicForConsumer = context .consumerIdToTopicName .get (consumerId );
196+ if (topicForConsumer != null ) {
197+ topicName = TopicName .toFullTopicName (topicForConsumer );
198+
199+ MutableLong msgBytes = new MutableLong (0 );
200+ MessageParser .parseMessage (topicName , -1L ,
201+ -1L , buffer , (message ) -> {
202+ messages .add (message );
203+ msgBytes .add (message .getData ().readableBytes ());
204+ }, maxMessageSize );
205+ // update topic stats
206+ TopicStats topicStats = this .service .getTopicStats ().computeIfAbsent (topicName .toString (),
207+ topic -> new TopicStats ());
208+ topicStats .getMsgOutRate ().recordMultipleEvents (messages .size (), msgBytes .longValue ());
209+ logging (ctx .channel (), cmd .getType (), "" , messages );
210+ } else {
211+ logging (ctx .channel (), cmd .getType (), "Cannot find topic name for consumerId " + consumerId ,
212+ null );
213+ }
176214 break ;
177215
178216 default :
0 commit comments