// public static methods
        public CommandRequestMessage EncryptFields(string databaseName, CommandRequestMessage unencryptedRequestMessage, CancellationToken cancellationToken)
        {
            var unencryptedCommandBytes = GetUnencryptedCommandBytes(unencryptedRequestMessage);
            var encryptedCommandBytes   = _commandFieldEncryptor.EncryptFields(databaseName, unencryptedCommandBytes, cancellationToken);

            return(CreateEncryptedRequestMessage(unencryptedRequestMessage, encryptedCommandBytes));
        }
예제 #2
0
        /// <summary>
        /// Process the data we received from the client.
        /// </summary>
        /// <param name="bytesRead"></param>
        private void ProcessReceivedData(int bytesRead)
        {
            // Encode our input string sent from the client
            this.lastChunk = Encoding.ASCII.GetString(this.Buffer, 0, bytesRead);

            // Temporary to avoid handling the telnet negotiations for now.
            // This needs to be abstracted out in to a negotation class that will parse, send and receive negotiation requests.
            if (this.Buffer.First() == 255)
            {
                return;
            }

            // If the previous chunk did not have a new line feed, then we add this message to the collection of currentData.
            // This lets us build a full message before processing it.
            if (!lastChunk.Contains("\r\n"))
            {
                // Add this to our incomplete data stash and read again.
                this.currentData.Add(lastChunk);
                return;
            }

            // This message contained at least 1 new line, so we split it and process per line.
            List <string> messages = lastChunk.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).ToList();

            foreach (string line in this.PruneReceivedMessages(messages))
            {
                CommandRequestMessage commandRequest = this.ParseMessage(line);
                this.notificationManager.Publish(commandRequest);
            }
        }
예제 #3
0
        public async Task <CommandResponseMessage> Handle(CommandRequestMessage commandMessage)
        {
            var instance = Host.CreateInstanceOfType(_methodCommandInfo.ClassType);

            if (instance == null)
            {
                throw new NoSuitableConstructorException(
                          "No suitable constructor found, make sure all your dependencies are injected");
            }

            var param = JsonConvert.DeserializeObject(commandMessage.Message,
                                                      _methodCommandInfo.MethodParameter.ParameterType);

            object result     = _methodCommandInfo.MethodInfo.Invoke(instance, new[] { param });
            object taskResult = null;

            if (_methodCommandInfo.MethodReturnType.IsGenericType &&
                _methodCommandInfo.MethodReturnType.GetGenericTypeDefinition() == typeof(Task <>))
            {
                taskResult = await((dynamic)result);
            }

            var resultJson = JsonConvert.SerializeObject(taskResult ?? result);

            return(new CommandResponseMessage(resultJson, _methodCommandInfo.MethodReturnType.ToString(),
                                              commandMessage.CorrelationId));
        }
        private void ProcessCommandRequestMessage(CommandRequestMessage originalMessage, Queue <RequestMessage> messageQueue, ConnectionId connectionId, ObjectId?serviceId, CommandMessageBinaryEncoder encoder, Stopwatch stopwatch)
        {
            var requestId   = originalMessage.RequestId;
            var operationId = EventContext.OperationId;

            var decodedMessage = encoder.ReadMessage();

            using (new CommandMessageDisposer(decodedMessage))
            {
                var type0Section  = decodedMessage.Sections.OfType <Type0CommandMessageSection>().Single();
                var command       = (BsonDocument)type0Section.Document;
                var type1Sections = decodedMessage.Sections.OfType <Type1CommandMessageSection>().ToList();
                if (type1Sections.Count > 0)
                {
                    command = new BsonDocument(command); // materialize the top level of the command RawBsonDocument
                    foreach (var type1Section in type1Sections)
                    {
                        var name  = type1Section.Identifier;
                        var items = new BsonArray(type1Section.Documents.GetBatchItems().Cast <RawBsonDocument>());
                        command[name] = items;
                    }
                }
                var commandName         = command.GetElement(0).Name;
                var databaseName        = command["$db"].AsString;
                var databaseNamespace   = new DatabaseNamespace(databaseName);
                var shouldRedactCommand = ShouldRedactCommand(command);
                if (shouldRedactCommand)
                {
                    command = new BsonDocument();
                }

                if (_startedEvent != null)
                {
                    var @event = new CommandStartedEvent(
                        commandName,
                        command,
                        databaseNamespace,
                        operationId,
                        requestId,
                        connectionId,
                        serviceId);

                    _startedEvent(@event);
                }

                if (_shouldTrackState)
                {
                    _state.TryAdd(requestId, new CommandState
                    {
                        CommandName          = commandName,
                        OperationId          = operationId,
                        Stopwatch            = stopwatch,
                        QueryNamespace       = new CollectionNamespace(databaseNamespace, "$cmd"),
                        ExpectedResponseType = decodedMessage.MoreToCome ? ExpectedResponseType.None : ExpectedResponseType.Command,
                        ShouldRedactReply    = shouldRedactCommand
                    });
                }
            }
        }
 private byte[] GetUnencryptedCommandBytes(CommandRequestMessage unencryptedRequestMessage)
 {
     using (var stream = new MemoryStream())
     {
         WriteUnencryptedRequestMessageToStream(stream, unencryptedRequestMessage);
         stream.Position = 0;
         return(CombineCommandMessageSectionsIntoSingleDocument(stream));
     }
 }
        private void WriteUnencryptedRequestMessageToStream(
            Stream stream,
            CommandRequestMessage unencryptedRequestMessage)
        {
            var clonedMessageEncoderSettings = _messageEncoderSettings.Clone();
            var encoderFactory = new BinaryMessageEncoderFactory(stream, clonedMessageEncoderSettings, compressorSource: null);
            var encoder        = encoderFactory.GetCommandRequestMessageEncoder();

            encoder.WriteMessage(unencryptedRequestMessage);
        }
        private CommandRequestMessage CreateEncryptedRequestMessage(CommandRequestMessage unencryptedRequestMessage, byte[] encryptedDocumentBytes)
        {
            var encryptedDocument         = new RawBsonDocument(encryptedDocumentBytes);
            var encryptedSections         = new[] { new Type0CommandMessageSection <RawBsonDocument>(encryptedDocument, RawBsonDocumentSerializer.Instance) };
            var unencryptedCommandMessage = unencryptedRequestMessage.WrappedMessage;
            var encryptedCommandMessage   = new CommandMessage(
                unencryptedCommandMessage.RequestId,
                unencryptedCommandMessage.ResponseTo,
                encryptedSections,
                unencryptedCommandMessage.MoreToCome);

            return(new CommandRequestMessage(encryptedCommandMessage, unencryptedRequestMessage.ShouldBeSent));
        }
예제 #8
0
        private void HandleMessage(CommandRequestMessage message)
        {
            var channel = FindChannelByServerId <SessionChannel>(message.RecipientChannel);

            if (message.WantReply)
            {
                _session.SendMessage(new ChannelSuccessMessage {
                    RecipientChannel = channel.ClientChannelId
                });
            }

            CommandOpened?.Invoke(this, new CommandRequestedArgs(channel, "exec", message.Command, _auth));
        }
예제 #9
0
        private void WriteUnencryptedRequestMessageToStream(
            Stream stream,
            CommandRequestMessage unencryptedRequestMessage)
        {
            var clonedMessageEncoderSettings = _messageEncoderSettings.Clone();

            clonedMessageEncoderSettings.Set(MessageEncoderSettingsName.MaxDocumentSize, 2097152);
            clonedMessageEncoderSettings.Set(MessageEncoderSettingsName.MaxMessageSize, 2097152 + 16384);
            var encoderFactory = new BinaryMessageEncoderFactory(stream, clonedMessageEncoderSettings, compressorSource: null);
            var encoder        = encoderFactory.GetCommandRequestMessageEncoder();

            encoder.WriteMessage(unencryptedRequestMessage);
        }
        private void MessageWasProbablySent(CommandRequestMessage message)
        {
            if (_session.Id != null)
            {
                _session.WasUsed();
            }

            var transaction = _session.CurrentTransaction;

            if (transaction != null && transaction.State == CoreTransactionState.Starting)
            {
                transaction.SetState(CoreTransactionState.InProgress);
            }
        }
        public void WriteMessage_should_delegate_to_wrapped_encoder()
        {
            var stream         = new MemoryStream();
            var subject        = CreateSubject(stream);
            var document       = new BsonDocument("x", 1);
            var sections       = new[] { new Type0CommandMessageSection <BsonDocument>(document, BsonDocumentSerializer.Instance) };
            var wrappedMessage = new CommandMessage(1, 2, sections, false);
            var message        = new CommandRequestMessage(wrappedMessage, () => true);
            var expectedBytes  = CreateMessageBytes(wrappedMessage);

            subject.WriteMessage(message);
            var result = stream.ToArray();

            result.Should().Equal(expectedBytes);
        }
        private void MessageWasProbablySent(CommandRequestMessage message)
        {
            if (_session.Id != null)
            {
                _session.WasUsed();
            }

            if (_session.IsInTransaction)
            {
                var wrappedMessage     = message.WrappedMessage;
                var type1Section       = wrappedMessage.Sections.OfType <Type1CommandMessageSection>().SingleOrDefault();
                var numberOfStatements = type1Section == null ? 1 : type1Section.Documents.ProcessedCount;
                _session.CurrentTransaction.AdvanceStatementId(numberOfStatements);
            }
        }
예제 #13
0
        public void WriteMessage_should_delegate_to_wrapped_encoder()
        {
            var textWriter     = new StringWriter();
            var subject        = CreateSubject(textWriter: textWriter);
            var document       = new BsonDocument("x", 1);
            var sections       = new[] { new Type0CommandMessageSection <BsonDocument>(document, BsonDocumentSerializer.Instance) };
            var wrappedMessage = new CommandMessage(1, 2, sections, false);
            var message        = new CommandRequestMessage(wrappedMessage, () => true);
            var expectedJson   = CreateMessageJson(wrappedMessage);

            subject.WriteMessage(message);
            var result = textWriter.ToString();

            result.Should().Be(expectedJson);
        }
예제 #14
0
        public Task <CommandResponseMessage> SendCommandAsync(CommandRequestMessage request, string queueName)
        {
            BasicProperties props         = new BasicProperties();
            var             correlationId = Guid.NewGuid().ToString();

            props.CorrelationId = correlationId;
            props.ReplyTo       = _replyQueueName;

            var tcs = new TaskCompletionSource <CommandResponseMessage>();

            CallbackMapper.TryAdd(correlationId, tcs);

            Context.CommandQueues[queueName].Enqueue(new TestBusCommandMessage(request, props));

            return(tcs.Task);
        }
        private async Task <CommandRequestMessage> AutoEncryptFieldsIfNecessaryAsync(CommandRequestMessage unencryptedRequestMessage, IConnection connection, CancellationToken cancellationToken)
        {
            if (_documentFieldEncryptor == null)
            {
                return(unencryptedRequestMessage);
            }
            else
            {
                if (connection.Description.IsMasterResult.MaxWireVersion < 8)
                {
                    throw new NotSupportedException("Auto-encryption requires a minimum MongoDB version of 4.2.");
                }

                var helper = new CommandMessageFieldEncryptor(_documentFieldEncryptor, _messageEncoderSettings);
                return(await helper.EncryptFieldsAsync(_databaseNamespace.DatabaseName, unencryptedRequestMessage, cancellationToken).ConfigureAwait(false));
            }
        }
예제 #16
0
        private void HandleMessage(CommandRequestMessage message)
        {
            var channel = FindChannelByServerId <SessionChannel>(message.RecipientChannel);

            if (message.WantReply)
            {
                _session.SendMessage(new ChannelSuccessMessage {
                    RecipientChannel = channel.ClientChannelId
                });
            }

            if (CommandOpened != null)
            {
                var args = new SessionRequestedArgs(channel, message.Command, _auth);
                CommandOpened(this, args);
            }
        }
예제 #17
0
        public async Task <T> Publish <T>(DomainCommand domainCommand, string queueName, string commandType = "")
        {
            domainCommand.TimeStamp = DateTime.Now.Ticks;
            var body           = JsonConvert.SerializeObject(domainCommand);
            var commandMessage = new CommandRequestMessage(body, domainCommand.CorrelationId, commandType);
            var task           = Sender.SendCommandAsync(commandMessage, queueName);

            if (await Task.WhenAny(task, Task.Delay(1222222222)) == task)
            {
                // Task completed within timeout.
                // Consider that the task may have faulted or been canceled.
                // We re-await the task so that any exceptions/cancellation is rethrown.
                var result = await task;

                if (result.MessageType.Contains("Exception"))
                {
                    object e = null;
                    try
                    {
                        var type = assembly.GetType(result.MessageType) ??
                                   Assembly.GetCallingAssembly().GetType(result.MessageType) ??
                                   GetTypeFromReferencedAssemblies(result.MessageType);

                        e = Activator.CreateInstance(type, result.Message);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogWarning("Invalid exception found {}", result.MessageType);
                        throw new InvalidCastException(
                                  $"an unknown exception occured (message {result.Message}), exception type was {result.MessageType}");
                    }

                    throw e as Exception;
                }

                if (string.IsNullOrEmpty(result.Message) || result.Message == "null")
                {
                    return(default(T));
                }
                var obj = JsonConvert.DeserializeObject <T>(result.Message);
                return(obj);
            }

            _logger.LogWarning("MessageID {cor} did not receive a response", domainCommand.CorrelationId);
            throw new NoResponseException("Could not get a response");
        }
        private void ProcessCommandRequestMessage(CommandRequestMessage originalMessage, Queue <RequestMessage> messageQueue, ConnectionId connectionId, CommandMessageBinaryEncoder encoder, Stopwatch stopwatch)
        {
            var requestId   = originalMessage.RequestId;
            var operationId = EventContext.OperationId;

            var decodedMessage = encoder.ReadMessage();

            using (new CommandMessageDisposer(decodedMessage))
            {
                var type0Section      = decodedMessage.Sections.OfType <Type0CommandMessageSection>().Single();
                var command           = (BsonDocument)type0Section.Document;
                var commandName       = command.GetElement(0).Name;
                var databaseName      = command["$db"].AsString;
                var databaseNamespace = new DatabaseNamespace(databaseName);
                if (__securitySensitiveCommands.Contains(commandName))
                {
                    command = new BsonDocument();
                }

                if (_startedEvent != null)
                {
                    var @event = new CommandStartedEvent(
                        commandName,
                        command,
                        databaseNamespace,
                        operationId,
                        requestId,
                        connectionId);

                    _startedEvent(@event);
                }

                if (_shouldTrackState)
                {
                    _state.TryAdd(requestId, new CommandState
                    {
                        CommandName          = commandName,
                        OperationId          = operationId,
                        Stopwatch            = stopwatch,
                        QueryNamespace       = new CollectionNamespace(databaseNamespace, "$cmd"),
                        ExpectedResponseType = ExpectedResponseType.Command
                    });
                }
            }
        }
예제 #19
0
        public async Task TestBusIntegrationTest()
        {
            TestBusContext context  = new TestBusContext();
            var            sender   = context.CreateCommandSender();
            var            receiver = context.CreateCommandReceiver("queue");

            receiver.DeclareCommandQueue();
            receiver.StartReceivingCommands((cm) =>
            {
                var message = "message2";
                return(Task.Run(() => new CommandResponseMessage(message, "", cm.CorrelationId)));
            });

            var mess   = new CommandRequestMessage("message", null);
            var result = await sender.SendCommandAsync(mess, "queue");

            Assert.AreEqual("message2", result.Message);
        }
예제 #20
0
        public Task <CommandResponseMessage> SendCommandAsync(CommandRequestMessage request, string queueName)
        {
            CheckDisposed();

            if (queueName == _replyQueueName)
            {
                _logger.LogWarning(
                    "The queuename {0} has the same same as the reply queue name, this should not happen",
                    _replyQueueName);
                throw new ArgumentException($"The queuename {queueName} is the same as the reply queue name");
            }

            var props = Channel.CreateBasicProperties();

            props.CorrelationId = Guid.NewGuid().ToString();
            props.ReplyTo       = _replyQueueName;
            props.Timestamp     = new AmqpTimestamp(DateTime.Now.Ticks);
            props.Type          = request.CommandType;
            var messageBytes = request.EncodeMessage();

            var tcs = new TaskCompletionSource <CommandResponseMessage>();

            _callbackMapper.TryAdd(props.CorrelationId, tcs);

            _logger.LogTrace("Sending command message with correlation id {id} and body {body} ", props.CorrelationId,
                             request);

            Channel.BasicPublish("",
                                 queueName,
                                 false,
                                 props,
                                 messageBytes);

            Channel.BasicConsume(_replyQueueName,
                                 true,
                                 "",
                                 false,
                                 false,
                                 null,
                                 _consumer);

            return(tcs.Task);
        }
예제 #21
0
        public async Task SendCommandAsync()
        {
            TestBusContext context = new TestBusContext();
            var            sender  = (TestCommandSender)context.CreateCommandSender();

            var generatedQueue = context.CommandQueues.First().Value;

            context.DeclareCommandQueue("queue");

            var message = new CommandRequestMessage("message", null);
            var task    = sender.SendCommandAsync(message, "queue");

            Assert.AreEqual(1, sender.CallbackMapper.Count);

            var dequeue = context.CommandQueues["queue"].Dequeue();

            generatedQueue.Enqueue(new TestBusCommandMessage(new CommandResponseMessage("message", typeof(string).FullName, null), dequeue.Props));

            var result = await task;

            Assert.AreEqual("message", result.Message);
        }
        public async Task HandleTest()
        {
            var methodCommandInfo = new MethodCommandInfo(typeof(TestClass),
                                                          typeof(TestClass).GetMethod("TestCalled"),
                                                          typeof(TestClass).GetMethod("TestCalled").GetParameters().First(),
                                                          typeof(TestClass).GetMethod("TestCalled").ReturnType,
                                                          "queue");
            var target = new CommandListener(methodCommandInfo);

            var hostMock = new Mock <IMicroserviceHost>(MockBehavior.Strict);

            hostMock.Setup(m => m.CreateInstanceOfType(typeof(TestClass))).Returns(new TestClass());

            var commandReceiverMock = new Mock <ICommandReceiver>(MockBehavior.Strict);

            commandReceiverMock.Setup(m => m.DeclareCommandQueue()).Verifiable();
            commandReceiverMock.Setup(m => m.StartReceivingCommands(target.Handle));

            var iBusContextMock = new Mock <IBusContext <IConnection> >(MockBehavior.Strict);

            iBusContextMock.Setup(m => m.CreateCommandReceiver("queue")).Returns(commandReceiverMock.Object);

            target.DeclareQueue(iBusContextMock.Object);
            target.StartListening(hostMock.Object);

            TestCommand command = new TestCommand()
            {
                Message = "message"
            };

            var message = new CommandRequestMessage(JsonConvert.SerializeObject(command), null);

            var result = await target.Handle(message);

            var objectResult = JsonConvert.DeserializeObject <TestCommand>(result.Message);

            Assert.AreEqual("Message2", objectResult.Message);
        }
        public Task<CommandResponseMessage> SendCommandAsync(CommandRequestMessage request, string queueName)
        {
            CheckDisposed();

            if (queueName == _replyQueueName)
            {
                _logger.LogWarning("The queuename {0} has the same same as the reply queue name, this should not happen", _replyQueueName);
                throw new ArgumentException($"The queuename {queueName} is the same as the reply queue name");
            }

            IBasicProperties props = Channel.CreateBasicProperties();
            props.CorrelationId = Guid.NewGuid().ToString();
            props.ReplyTo = _replyQueueName;
            props.Timestamp = new AmqpTimestamp(DateTime.Now.Ticks);
            var messageBytes = request.EncodeMessage();

            var tcs = new TaskCompletionSource<CommandResponseMessage>();
            _callbackMapper.TryAdd(props.CorrelationId, tcs);

            _logger.LogTrace("Sending command message with correlation id {id} and body {body} ", props.CorrelationId, request);

            Channel.BasicPublish(exchange: "",
                                 routingKey: queueName,
                                 mandatory: false,
                                 basicProperties: props,
                                 body: messageBytes);

            Channel.BasicConsume(queue: _replyQueueName,
                                 autoAck: true,
                                 consumerTag: "",
                                 noLocal: false,
                                 exclusive: false,
                                 arguments: null,
                                 consumer: _consumer);

            return tcs.Task;
        }
예제 #24
0
        public async Task <CommandResponseMessage> Handle(CommandRequestMessage commandMessage)
        {
            var instance = Host.CreateInstanceOfType(_methodCommandInfo.ClassType);

            if (instance == null)
            {
                _logger.LogError("No constructor found for {0}, this could be related to your dependency injection", _methodCommandInfo.ClassType.FullName);
                throw new NoSuitableConstructorException(
                          "No suitable constructor found, make sure all your dependencies are injected");
            }


            var param = JsonConvert.DeserializeObject(commandMessage.Message,
                                                      _methodCommandInfo.MethodParameter.ParameterType);

            var result = _methodCommandInfo.MethodInfo.Invoke(instance, new[] { param });

            if (result == null || result.GetType() == typeof(Task))
            {
                //throw new InvalidOperationException("Command " + _methodCommandInfo.MethodInfo.Name + " didn't return anything, make sure it returns a value or a Task<T>");
                return(new CommandResponseMessage("", "", commandMessage.CorrelationId));
            }

            object taskResult = null;

            if (_methodCommandInfo.MethodReturnType.IsGenericType &&
                _methodCommandInfo.MethodReturnType.GetGenericTypeDefinition() == typeof(Task <>))
            {
                taskResult = await(dynamic) result;
            }

            var resultJson = JsonConvert.SerializeObject(taskResult ?? result);

            return(new CommandResponseMessage(resultJson, _methodCommandInfo.MethodReturnType.ToString(),
                                              commandMessage.CorrelationId));
        }
        public async Task <CommandRequestMessage> EncryptFieldsAsync(string databaseName, CommandRequestMessage unencryptedRequestMessage, CancellationToken cancellationToken)
        {
            var unencryptedCommandBytes = GetUnencryptedCommandBytes(unencryptedRequestMessage);
            var encryptedCommandBytes   = await _commandFieldEncryptor.EncryptFieldsAsync(databaseName, unencryptedCommandBytes, cancellationToken).ConfigureAwait(false);

            return(CreateEncryptedRequestMessage(unencryptedRequestMessage, encryptedCommandBytes));
        }
        /// <summary>
        /// Writes the message.
        /// </summary>
        /// <param name="message">The message.</param>
        public void WriteMessage(CommandRequestMessage message)
        {
            var wrappedMessage = message.WrappedMessage;

            _wrappedEncoder.WriteMessage(wrappedMessage);
        }
예제 #27
0
 private Task <CommandResponseMessage> Callback(CommandRequestMessage commandmessage)
 {
     return(Task.Run(() => new CommandResponseMessage("test", typeof(string).FullName, "test")));
 }