@@ -237,19 +237,20 @@ public boolean isClosed() {
237237
238238 @ Override
239239 public <T > T sendAndReceive (final CommandMessage message , final Decoder <T > decoder , final SessionContext sessionContext ) {
240- CommandEventSender commandEventSender = new CommandEventSender (message );
241-
242240 ByteBufferBsonOutput bsonOutput = new ByteBufferBsonOutput (this );
241+ LazyCommandDocument lazyCommandDocument = new LazyCommandDocument (message , bsonOutput );
242+ CommandEventSender commandEventSender = new CommandEventSender (message , lazyCommandDocument );
243+
243244 try {
244245 message .encode (bsonOutput , sessionContext );
245- commandEventSender .sendStartedEvent (bsonOutput );
246+ commandEventSender .sendStartedEvent ();
246247 } catch (RuntimeException e ) {
247248 bsonOutput .close ();
248249 throw e ;
249250 }
250251
251252 try {
252- sendCommandMessage (message , commandEventSender , bsonOutput , sessionContext );
253+ sendCommandMessage (message , lazyCommandDocument , bsonOutput , sessionContext );
253254 if (message .isResponseExpected ()) {
254255 return receiveCommandMessageResponse (message , decoder , commandEventSender , sessionContext );
255256 } else {
@@ -262,10 +263,10 @@ public <T> T sendAndReceive(final CommandMessage message, final Decoder<T> decod
262263 }
263264 }
264265
265- private void sendCommandMessage (final CommandMessage message , final CommandEventSender commandEventSender ,
266+ private void sendCommandMessage (final CommandMessage message , final LazyCommandDocument lazyCommandDocument ,
266267 final ByteBufferBsonOutput bsonOutput , final SessionContext sessionContext ) {
267268 try {
268- if (sendCompressor == null || SECURITY_SENSITIVE_COMMANDS .contains (commandEventSender . getCommandName ())) {
269+ if (sendCompressor == null || SECURITY_SENSITIVE_COMMANDS .contains (lazyCommandDocument . getName ())) {
269270 sendMessage (bsonOutput .getByteBuffers (), message .getId ());
270271 } else {
271272 CompressedMessage compressedMessage = new CompressedMessage (message .getOpCode (), bsonOutput .getByteBuffers (),
@@ -318,10 +319,11 @@ public <T> void sendAndReceiveAsync(final CommandMessage message, final Decoder<
318319
319320 try {
320321 message .encode (bsonOutput , sessionContext );
321- CommandEventSender commandEventSender = new CommandEventSender (message );
322- commandEventSender .sendStartedEvent (bsonOutput );
322+ LazyCommandDocument lazyCommandDocument = new LazyCommandDocument (message , bsonOutput );
323+ CommandEventSender commandEventSender = new CommandEventSender (message , lazyCommandDocument );
324+ commandEventSender .sendStartedEvent ();
323325
324- if (sendCompressor == null || SECURITY_SENSITIVE_COMMANDS .contains (commandEventSender . getCommandName ())) {
326+ if (sendCompressor == null || SECURITY_SENSITIVE_COMMANDS .contains (lazyCommandDocument . getName ())) {
325327 sendCommandMessageAsync (message .getId (), decoder , sessionContext , callback , bsonOutput , commandEventSender ,
326328 message .isResponseExpected ());
327329 } else {
@@ -657,60 +659,79 @@ public void onResult(final ByteBuf result, final Throwable t) {
657659 private class CommandEventSender {
658660 private final long startTimeNanos ;
659661 private final CommandMessage message ;
660- private String commandName ;
662+ private final LazyCommandDocument lazyCommandDocument ;
661663
662- CommandEventSender (final CommandMessage message ) {
664+ CommandEventSender (final CommandMessage message , final LazyCommandDocument lazyCommandDocument ) {
663665 this .startTimeNanos = System .nanoTime ();
664666 this .message = message ;
667+ this .lazyCommandDocument = lazyCommandDocument ;
665668 }
666669
667- // Call after sendStartedEvent. Returns null unless there's either a command listener or a sendCompress configured. Otherwise,
668- // there's no need to compute the command name
669- public String getCommandName () {
670- if (commandName == null ) {
671- throw new MongoInternalException ("Attempting to use the command name when it has not been determined" );
672- }
673- return commandName ;
674- }
675-
676- public void sendStartedEvent (final ByteBufferBsonOutput bsonOutput ) {
677- if ((commandListener != null || sendCompressor != null ) && opened ()) {
678-
679- BsonDocument commandDocument = message .getCommandDocument (bsonOutput );
680- commandName = commandDocument .getFirstKey ();
681-
682- BsonDocument commandDocumentForEvent = (SECURITY_SENSITIVE_COMMANDS .contains (commandName ))
683- ? new BsonDocument () : commandDocument ;
684- sendCommandStartedEvent (message , new MongoNamespace (message .getCollectionName ()).getDatabaseName (), commandName ,
685- commandDocumentForEvent , getDescription (), commandListener );
670+ public void sendStartedEvent () {
671+ if (commandListener != null && opened ()) {
672+ BsonDocument commandDocumentForEvent = (SECURITY_SENSITIVE_COMMANDS .contains (lazyCommandDocument .getName ()))
673+ ? new BsonDocument () : lazyCommandDocument .getDocument ();
674+ sendCommandStartedEvent (message , new MongoNamespace (message .getCollectionName ()).getDatabaseName (),
675+ lazyCommandDocument .getName (), commandDocumentForEvent , getDescription (), commandListener );
686676 }
687677 }
688678
689679 public void sendFailedEvent (final Throwable t ) {
690680 if (commandListener != null && opened ()) {
691681 Throwable commandEventException = t ;
692- if (t instanceof MongoCommandException && (SECURITY_SENSITIVE_COMMANDS .contains (commandName ))) {
682+ if (t instanceof MongoCommandException && (SECURITY_SENSITIVE_COMMANDS .contains (lazyCommandDocument . getName () ))) {
693683 commandEventException = new MongoCommandException (new BsonDocument (), description .getServerAddress ());
694684 }
695- sendCommandFailedEvent (message , commandName , description , startTimeNanos , commandEventException , commandListener );
685+ sendCommandFailedEvent (message , lazyCommandDocument .getName (), description , startTimeNanos , commandEventException ,
686+ commandListener );
696687 }
697688 }
698689
699690 public void sendSucceededEvent (final ResponseBuffers responseBuffers ) {
700691 if (commandListener != null && opened ()) {
701- BsonDocument responseDocumentForEvent = (SECURITY_SENSITIVE_COMMANDS .contains (commandName ))
702- ? new BsonDocument ()
703- : getResponseDocument (responseBuffers , message .getId (),
692+ BsonDocument responseDocumentForEvent = (SECURITY_SENSITIVE_COMMANDS .contains (lazyCommandDocument . getName () ))
693+ ? new BsonDocument ()
694+ : getResponseDocument (responseBuffers , message .getId (),
704695 new RawBsonDocumentCodec ());
705- sendCommandSucceededEvent (message , commandName , responseDocumentForEvent , description , startTimeNanos , commandListener );
696+ sendCommandSucceededEvent (message , lazyCommandDocument .getName (), responseDocumentForEvent , description ,
697+ startTimeNanos , commandListener );
706698 }
707699 }
708700
709701 public void sendSucceededEventForOneWayCommand () {
710702 if (commandListener != null && opened ()) {
711703 BsonDocument responseDocumentForEvent = new BsonDocument ("ok" , new BsonInt32 (1 ));
712- sendCommandSucceededEvent (message , commandName , responseDocumentForEvent , description , startTimeNanos , commandListener );
704+ sendCommandSucceededEvent (message , lazyCommandDocument .getName (), responseDocumentForEvent , description ,
705+ startTimeNanos , commandListener );
706+ }
707+ }
708+ }
709+
710+ // Lazily determine the command document and command name, since they're only needed if either a command listener or compression
711+ // is enabled
712+ private static final class LazyCommandDocument {
713+ private final CommandMessage commandMessage ;
714+ private final ByteBufferBsonOutput bsonOutput ;
715+ private BsonDocument commandDocument ;
716+ private String commandName ;
717+
718+ private LazyCommandDocument (final CommandMessage commandMessage , final ByteBufferBsonOutput bsonOutput ) {
719+ this .commandMessage = commandMessage ;
720+ this .bsonOutput = bsonOutput ;
721+ }
722+
723+ public String getName () {
724+ if (commandName == null ) {
725+ commandName = getDocument ().getFirstKey ();
726+ }
727+ return commandName ;
728+ }
729+
730+ private BsonDocument getDocument () {
731+ if (commandDocument == null ) {
732+ commandDocument = commandMessage .getCommandDocument (bsonOutput );
713733 }
734+ return commandDocument ;
714735 }
715736 }
716737}
0 commit comments