Пример #1
0
        protected override TReturn CallInternal <TReturn>(bool isStream, Type interfaceType, string methodName, object[] arguments)
        {
            var data = new CQRSRequestData()
            {
                ProviderType   = interfaceType.Name,
                ProviderMethod = methodName
            };

            data.AddProviderArguments(arguments);

            switch (networkType)
            {
            case NetworkType.Internal:
                data.AddClaims();
                break;

            case NetworkType.Api:
                break;

            default: throw new NotImplementedException();
            }

            var stopwatch = Stopwatch.StartNew();

            var client = new TcpClient(endpoint.AddressFamily);

            var bufferOwner = BufferArrayPool <byte> .Rent(TcpRawCommon.BufferLength);

            var              buffer                  = bufferOwner.AsMemory();
            Stream           stream                  = null;
            Stream           requestBodyStream       = null;
            FinalBlockStream requestBodyCryptoStream = null;
            Stream           responseBodyStream      = null;

            try
            {
                client.Connect(endpoint.Address, endpoint.Port);

                stream = client.GetStream();

                //Request Header
                var requestHeaderLength = TcpRawCommon.BufferHeader(buffer, data.ProviderType, contentType);
#if NETSTANDARD2_0
                stream.Write(bufferOwner, 0, requestHeaderLength);
#else
                stream.Write(buffer.Span.Slice(0, requestHeaderLength));
#endif

                requestBodyStream = new TcpRawProtocolBodyStream(stream, null, true);

                if (encryptionKey != null)
                {
                    requestBodyCryptoStream = SymmetricEncryptor.Encrypt(encryptionAlgorithm, encryptionKey, requestBodyStream, true, true);
                    ContentTypeSerializer.Serialize(contentType, requestBodyCryptoStream, data);
                    requestBodyCryptoStream.FlushFinalBlock();
                    requestBodyCryptoStream.Dispose();
                    requestBodyCryptoStream = null;
                }
                else
                {
                    ContentTypeSerializer.Serialize(contentType, requestBodyStream, data);
                    requestBodyStream.Flush();
                }

                requestBodyStream.Dispose();
                requestBodyStream = null;

                //Response Header
                var headerPosition   = 0;
                var headerLength     = 0;
                var requestHeaderEnd = false;
                while (!requestHeaderEnd)
                {
                    if (headerLength == buffer.Length)
                    {
                        throw new Exception($"{nameof(TcpRawCQRSClient)} Header Too Long");
                    }

#if NETSTANDARD2_0
                    var bytesRead = stream.Read(bufferOwner, headerPosition, buffer.Length - headerPosition);
#else
                    var bytesRead = stream.Read(buffer.Span.Slice(headerPosition, buffer.Length - headerPosition));
#endif

                    if (bytesRead == 0)
                    {
                        throw new EndOfStreamException();
                    }
                    headerLength += bytesRead;

                    requestHeaderEnd = TcpRawCommon.ReadToHeaderEnd(buffer, ref headerPosition, headerLength);
                }
                var responseHeader = TcpRawCommon.ReadHeader(buffer, headerPosition, headerLength);

                responseBodyStream = new TcpRawProtocolBodyStream(stream, responseHeader.BodyStartBuffer, false);

                if (encryptionKey != null)
                {
                    responseBodyStream = SymmetricEncryptor.Decrypt(encryptionAlgorithm, encryptionKey, responseBodyStream, false, false);
                }

                if (responseHeader.IsError)
                {
                    var responseException = ContentTypeSerializer.DeserializeException(contentType, responseBodyStream);
                    throw responseException;
                }

                stopwatch.Stop();
                _ = Log.TraceAsync($"{nameof(TcpRawCQRSClient)} Query: {interfaceType.GetNiceName()}.{data.ProviderMethod} {stopwatch.ElapsedMilliseconds}");

                if (isStream)
                {
                    return((TReturn)(object)responseBodyStream); //TODO better way to convert type???
                }
                else
                {
                    var model = ContentTypeSerializer.Deserialize <TReturn>(contentType, responseBodyStream);
                    responseBodyStream.Dispose();
                    client.Dispose();
                    return(model);
                }
            }
            catch
            {
                try
                {
                    //crypto stream can error, we want to throw the actual error
                    if (responseBodyStream != null)
                    {
                        responseBodyStream.Dispose();
                    }
                }
                catch { }
                if (requestBodyStream != null)
                {
                    requestBodyStream.Dispose();
                }
                if (requestBodyCryptoStream != null)
                {
                    requestBodyCryptoStream.Dispose();
                }
                if (stream != null)
                {
                    stream.Dispose();
                }
                client.Dispose();
                throw;
            }
            finally
            {
                BufferArrayPool <byte> .Return(bufferOwner);
            }
        }
Пример #2
0
        protected override async Task DispatchInternal(ICommand command, bool messageAwait)
        {
            var messageType     = command.GetType();
            var messageTypeName = messageType.GetNiceName();

            var messageData = System.Text.Json.JsonSerializer.Serialize(command, messageType);

            var data = new CQRSRequestData()
            {
                MessageType  = messageTypeName,
                MessageData  = messageData,
                MessageAwait = messageAwait
            };

            switch (networkType)
            {
            case NetworkType.Internal:
                data.AddClaims();
                break;

            case NetworkType.Api:
                break;

            default:
                throw new NotImplementedException();
            }

            var stopwatch = Stopwatch.StartNew();

            var client = new TcpClient(endpoint.AddressFamily);

            client.NoDelay = true;

            var bufferOwner = BufferArrayPool <byte> .Rent(TcpRawCommon.BufferLength);

            var              buffer                  = bufferOwner.AsMemory();
            Stream           stream                  = null;
            Stream           requestBodyStream       = null;
            FinalBlockStream requestBodyCryptoStream = null;
            Stream           responseBodyStream      = null;

            try
            {
                await client.ConnectAsync(endpoint.Address, endpoint.Port);

                stream = client.GetStream();

                //Request Header
                var requestHeaderLength = TcpRawCommon.BufferHeader(buffer, data.MessageType, contentType);
#if NETSTANDARD2_0
                await stream.WriteAsync(bufferOwner, 0, requestHeaderLength);
#else
                await stream.WriteAsync(buffer.Slice(0, requestHeaderLength));
#endif

                requestBodyStream = new TcpRawProtocolBodyStream(stream, null, true);

                if (encryptionKey != null)
                {
                    requestBodyCryptoStream = SymmetricEncryptor.Encrypt(encryptionAlgorithm, encryptionKey, requestBodyStream, true, true);
                    await ContentTypeSerializer.SerializeAsync(contentType, requestBodyCryptoStream, data);

#if NET5_0_OR_GREATER
                    await requestBodyCryptoStream.FlushFinalBlockAsync();
#else
                    requestBodyCryptoStream.FlushFinalBlock();
#endif
#if NETSTANDARD2_0
                    requestBodyCryptoStream.Dispose();
#else
                    await requestBodyCryptoStream.DisposeAsync();
#endif
                    requestBodyCryptoStream = null;
                }
                else
                {
                    await ContentTypeSerializer.SerializeAsync(contentType, requestBodyStream, data);

                    await requestBodyStream.FlushAsync();
                }

#if NETSTANDARD2_0
                requestBodyStream.Dispose();
#else
                await requestBodyStream.DisposeAsync();
#endif
                requestBodyStream = null;

                //Response Header
                var headerPosition   = 0;
                var headerLength     = 0;
                var requestHeaderEnd = false;
                while (!requestHeaderEnd)
                {
                    if (headerLength == buffer.Length)
                    {
                        throw new Exception($"{nameof(TcpRawCQRSClient)} Header Too Long");
                    }

#if NETSTANDARD2_0
                    var bytesRead = await stream.ReadAsync(bufferOwner, headerPosition, buffer.Length - headerPosition);
#else
                    var bytesRead = await stream.ReadAsync(buffer.Slice(headerPosition, buffer.Length - headerPosition));
#endif

                    if (bytesRead == 0)
                    {
                        throw new EndOfStreamException();
                    }
                    headerLength += bytesRead;

                    requestHeaderEnd = TcpRawCommon.ReadToHeaderEnd(buffer, ref headerPosition, headerLength);
                }
                var responseHeader = TcpRawCommon.ReadHeader(buffer, headerPosition, headerLength);

                //Response Body
                responseBodyStream = new TcpRawProtocolBodyStream(stream, responseHeader.BodyStartBuffer, false);

                if (responseHeader.IsError)
                {
                    if (encryptionKey != null)
                    {
                        responseBodyStream = SymmetricEncryptor.Decrypt(encryptionAlgorithm, encryptionKey, responseBodyStream, false, false);
                    }

                    var responseException = await ContentTypeSerializer.DeserializeExceptionAsync(contentType, responseBodyStream);

                    throw responseException;
                }

                if (responseBodyStream != null)
                {
#if NETSTANDARD2_0
                    responseBodyStream.Dispose();
#else
                    await responseBodyStream.DisposeAsync();
#endif
                }
                client.Dispose();

                stopwatch.Stop();
                _ = Log.TraceAsync($"{nameof(TcpRawCQRSClient)}Sent: {messageTypeName} {stopwatch.ElapsedMilliseconds}");
            }
            catch
            {
                if (responseBodyStream != null)
                {
#if NETSTANDARD2_0
                    responseBodyStream.Dispose();
#else
                    await responseBodyStream.DisposeAsync();
#endif
                }
                if (requestBodyStream != null)
                {
#if NETSTANDARD2_0
                    requestBodyStream.Dispose();
#else
                    await requestBodyStream.DisposeAsync();
#endif
                }
                if (stream != null)
                {
#if NETSTANDARD2_0
                    stream.Dispose();
#else
                    await stream.DisposeAsync();
#endif
                }
                client.Dispose();
                throw;
            }
            finally
            {
                BufferArrayPool <byte> .Return(bufferOwner);
            }
        }
Пример #3
0
        protected override async void Handle(TcpClient client, CancellationToken cancellationToken)
        {
            TcpRequestHeader requestHeader   = null;
            bool             responseStarted = false;

            var bufferOwner = BufferArrayPool <byte> .Rent(TcpRawCommon.BufferLength);

            var              buffer                   = bufferOwner.AsMemory();
            Stream           stream                   = null;
            Stream           requestBodyStream        = null;
            Stream           responseBodyStream       = null;
            FinalBlockStream responseBodyCryptoStream = null;

            try
            {
                stream = client.GetStream();

                //Read Request Header
                //------------------------------------------------------------------------------------------------------------
                var headerPosition   = 0;
                var headerLength     = 0;
                var requestHeaderEnd = false;
                while (!requestHeaderEnd)
                {
                    if (headerLength == buffer.Length)
                    {
                        throw new Exception($"{nameof(TcpRawCQRSServer)} Header Too Long");
                    }

#if NETSTANDARD2_0
                    var bytesRead = await stream.ReadAsync(bufferOwner, headerLength, buffer.Length - headerLength, cancellationToken);
#else
                    var bytesRead = await stream.ReadAsync(buffer.Slice(headerLength, buffer.Length - headerLength), cancellationToken);
#endif

                    if (bytesRead == 0)
                    {
                        throw new EndOfStreamException();
                    }
                    headerLength += bytesRead;

                    requestHeaderEnd = TcpRawCommon.ReadToHeaderEnd(buffer, ref headerPosition, headerLength);
                }
                requestHeader = TcpRawCommon.ReadHeader(buffer, headerPosition, headerLength);

                if (!requestHeader.ContentType.HasValue || (contentType.HasValue && requestHeader.ContentType.HasValue && requestHeader.ContentType != contentType))
                {
                    _ = Log.ErrorAsync($"{nameof(TcpRawCQRSServer)} Received Invalid Content Type {requestHeader.ContentType}");
                    throw new Exception("Invalid Content Type");
                }

                _ = Log.TraceAsync($"{nameof(TcpRawCQRSServer)} Received On {client.Client.LocalEndPoint} From {client.Client.RemoteEndPoint} {requestHeader.ProviderType}");

                //Read Request Body
                //------------------------------------------------------------------------------------------------------------

                requestBodyStream = new TcpRawProtocolBodyStream(stream, requestHeader.BodyStartBuffer, true);

                if (encryptionKey != null)
                {
                    requestBodyStream = networkType switch
                    {
                        NetworkType.Internal => SymmetricEncryptor.Decrypt(encryptionAlgorithm, encryptionKey, requestBodyStream, false, false),
                        NetworkType.Api => throw new NotSupportedException($"Encryption Not Supported for Network Type {EnumName.GetEnumName(networkType)}"),
                              _ => throw new NotImplementedException(),
                    };
                }

                var data = await ContentTypeSerializer.DeserializeAsync <CQRSRequestData>(requestHeader.ContentType.Value, requestBodyStream);

                if (data == null)
                {
                    throw new Exception("Empty request body");
                }

#if NETSTANDARD2_0
                requestBodyStream.Dispose();
#else
                await requestBodyStream.DisposeAsync();
#endif
                requestBodyStream = null;

                //Authroize
                //------------------------------------------------------------------------------------------------------------
                switch (networkType)
                {
                case NetworkType.Internal:
                    if (data.Claims != null)
                    {
                        var claimsIdentity = new ClaimsIdentity(data.Claims.Select(x => new Claim(x.Type, x.Value)), "CQRS");
                        Thread.CurrentPrincipal = new ClaimsPrincipal(claimsIdentity);
                    }
                    else
                    {
                        Thread.CurrentPrincipal = null;
                    }
                    break;

                case NetworkType.Api:
                    break;

                default:
                    throw new NotImplementedException();
                }

                //Process and Respond
                //----------------------------------------------------------------------------------------------------
                if (!String.IsNullOrWhiteSpace(data.ProviderType))
                {
                    var providerType = Discovery.GetTypeFromName(data.ProviderType);
                    var typeDetail   = TypeAnalyzer.GetTypeDetail(providerType);

                    if (!this.interfaceTypes.Contains(providerType))
                    {
                        throw new Exception($"Unhandled Provider Type {providerType.FullName}");
                    }

                    bool exposed = typeDetail.Attributes.Any(x => x is ServiceExposedAttribute attribute && (!attribute.NetworkType.HasValue || attribute.NetworkType == networkType)) &&
                                   !typeDetail.Attributes.Any(x => x is ServiceBlockedAttribute attribute && (!attribute.NetworkType.HasValue || attribute.NetworkType == networkType));
                    if (!exposed)
                    {
                        throw new Exception($"Provider {data.MessageType} is not exposed to {networkType}");
                    }

                    _ = Log.TraceAsync($"Received Call: {providerType.GetNiceName()}.{data.ProviderMethod}");

                    var result = await this.providerHandlerAsync.Invoke(providerType, data.ProviderMethod, data.ProviderArguments);

                    //Response Header
                    var responseHeaderLength = TcpRawCommon.BufferHeader(buffer, requestHeader.ProviderType, requestHeader.ContentType.Value);
#if NETSTANDARD2_0
                    await stream.WriteAsync(bufferOwner, 0, responseHeaderLength, cancellationToken);
#else
                    await stream.WriteAsync(buffer.Slice(0, responseHeaderLength), cancellationToken);
#endif

                    //Response Body
                    responseBodyStream = new TcpRawProtocolBodyStream(stream, null, true);

                    int bytesRead;
                    if (result.Stream != null)
                    {
                        if (encryptionKey != null)
                        {
                            responseBodyCryptoStream = networkType switch
                            {
                                NetworkType.Internal => SymmetricEncryptor.Encrypt(encryptionAlgorithm, encryptionKey, responseBodyStream, true, false),
                                NetworkType.Api => throw new NotSupportedException($"Encryption Not Supported for Network Type {EnumName.GetEnumName(networkType)}"),
                                      _ => throw new NotImplementedException(),
                            };

#if NETSTANDARD2_0
                            while ((bytesRead = await result.Stream.ReadAsync(bufferOwner, 0, bufferOwner.Length, cancellationToken)) > 0)
                            {
                                await responseBodyCryptoStream.WriteAsync(bufferOwner, 0, bytesRead, cancellationToken);
                            }
#else
                            while ((bytesRead = await result.Stream.ReadAsync(buffer, cancellationToken)) > 0)
                            {
                                await responseBodyCryptoStream.WriteAsync(buffer.Slice(0, bytesRead), cancellationToken);
                            }
#endif
#if NET5_0_OR_GREATER
                            await responseBodyCryptoStream.FlushFinalBlockAsync();
#else
                            responseBodyCryptoStream.FlushFinalBlock();
#endif
#if NETSTANDARD2_0
                            responseBodyCryptoStream.Dispose();
#else
                            await responseBodyCryptoStream.DisposeAsync();
#endif
                            responseBodyCryptoStream = null;
                        }
                        else
                        {
#if NETSTANDARD2_0
                            while ((bytesRead = await result.Stream.ReadAsync(bufferOwner, 0, bufferOwner.Length, cancellationToken)) > 0)
                            {
                                await responseBodyStream.WriteAsync(bufferOwner, 0, bytesRead, cancellationToken);
                            }
#else
                            while ((bytesRead = await result.Stream.ReadAsync(buffer, cancellationToken)) > 0)
                            {
                                await responseBodyStream.WriteAsync(buffer.Slice(0, bytesRead), cancellationToken);
                            }
#endif
                            await responseBodyStream.FlushAsync(cancellationToken);

#if NETSTANDARD2_0
                            responseBodyStream.Dispose();
#else
                            await responseBodyStream.DisposeAsync();
#endif
                        }

                        client.Dispose();
                        return;
                    }
                    else
                    {
                        if (encryptionKey != null)
                        {
                            responseBodyCryptoStream = networkType switch
                            {
                                NetworkType.Internal => SymmetricEncryptor.Encrypt(encryptionAlgorithm, encryptionKey, responseBodyStream, true, false),
                                NetworkType.Api => throw new NotSupportedException($"Encryption Not Supported for Network Type {EnumName.GetEnumName(networkType)}"),
                                      _ => throw new NotImplementedException(),
                            };

                            await ContentTypeSerializer.SerializeAsync(requestHeader.ContentType.Value, responseBodyCryptoStream, result.Model);

#if NET5_0_OR_GREATER
                            await responseBodyCryptoStream.FlushFinalBlockAsync();
#else
                            responseBodyCryptoStream.FlushFinalBlock();
#endif
#if NETSTANDARD2_0
                            responseBodyCryptoStream.Dispose();
#else
                            await responseBodyCryptoStream.DisposeAsync();
#endif
                            responseBodyCryptoStream = null;
                            return;
                        }
                        else
                        {
                            await ContentTypeSerializer.SerializeAsync(requestHeader.ContentType.Value, responseBodyStream, result.Model);

                            await responseBodyStream.FlushAsync(cancellationToken);

#if NETSTANDARD2_0
                            responseBodyStream.Dispose();
#else
                            await responseBodyStream.DisposeAsync();
#endif
                            return;
                        }
                    }
                }
                else if (!String.IsNullOrWhiteSpace(data.MessageType))
                {
                    var commandType = Discovery.GetTypeFromName(data.MessageType);
                    var typeDetail  = TypeAnalyzer.GetTypeDetail(commandType);

                    if (!typeDetail.Interfaces.Contains(typeof(ICommand)))
                    {
                        throw new Exception($"Type {data.MessageType} is not a command");
                    }

                    bool exposed = typeDetail.Attributes.Any(x => x is ServiceExposedAttribute attribute && (!attribute.NetworkType.HasValue || attribute.NetworkType == networkType)) &&
                                   !typeDetail.Attributes.Any(x => x is ServiceBlockedAttribute attribute && (!attribute.NetworkType.HasValue || attribute.NetworkType == networkType));
                    if (!exposed)
                    {
                        throw new Exception($"Command {data.MessageType} is not exposed to {networkType}");
                    }

                    var command = (ICommand)System.Text.Json.JsonSerializer.Deserialize(data.MessageData, commandType);

                    if (data.MessageAwait)
                    {
                        await handlerAwaitAsync(command);
                    }
                    else
                    {
                        await handlerAsync(command);
                    }

                    //Response Header
                    var responseHeaderLength = TcpRawCommon.BufferHeader(buffer, requestHeader.ProviderType, requestHeader.ContentType.Value);
#if NETSTANDARD2_0
                    await stream.WriteAsync(bufferOwner, 0, responseHeaderLength, cancellationToken);
#else
                    await stream.WriteAsync(buffer.Slice(0, responseHeaderLength), cancellationToken);
#endif

                    //Response Body Empty
                    responseBodyStream = new TcpRawProtocolBodyStream(stream, null, true);
                    await responseBodyStream.FlushAsync(cancellationToken);

#if NETSTANDARD2_0
                    responseBodyStream.Dispose();
#else
                    await responseBodyStream.DisposeAsync();
#endif
                    client.Dispose();
                    return;
                }

                throw new Exception("Invalid Request");
            }
            catch (Exception ex)
            {
                if (ex is IOException ioException)
                {
                    if (ioException.InnerException != null && ioException.InnerException is SocketException socketException)
                    {
                        if (socketException.SocketErrorCode == SocketError.ConnectionAborted)
                        {
                            if (responseBodyStream != null)
                            {
#if NETSTANDARD2_0
                                responseBodyStream.Dispose();
#else
                                await responseBodyStream.DisposeAsync();
#endif
                            }
                            if (requestBodyStream != null)
                            {
#if NETSTANDARD2_0
                                requestBodyStream.Dispose();
#else
                                await requestBodyStream.DisposeAsync();
#endif
                            }
                            if (stream != null)
                            {
#if NETSTANDARD2_0
                                stream.Dispose();
#else
                                await stream.DisposeAsync();
#endif
                            }
                            return;
                        }
                    }
                }

                _ = Log.ErrorAsync(null, ex);

                if (client.Connected && !responseStarted && requestHeader != null && requestHeader.ContentType.HasValue)
                {
                    try
                    {
                        //Response Header for Error
                        var responseHeaderLength = TcpRawCommon.BufferErrorHeader(buffer, requestHeader.ProviderType, requestHeader.ContentType.Value);
#if NETSTANDARD2_0
                        await stream.WriteAsync(bufferOwner, 0, responseHeaderLength, cancellationToken);
#else
                        await stream.WriteAsync(buffer.Slice(0, responseHeaderLength), cancellationToken);
#endif

                        //Response Body
                        responseBodyStream = new TcpRawProtocolBodyStream(stream, null, true);
                        if (encryptionKey != null)
                        {
                            responseBodyCryptoStream = networkType switch
                            {
                                NetworkType.Internal => SymmetricEncryptor.Encrypt(encryptionAlgorithm, encryptionKey, responseBodyStream, true, false),
                                NetworkType.Api => throw new NotSupportedException($"Encryption Not Supported for Network Type {EnumName.GetEnumName(networkType)}"),
                                      _ => throw new NotImplementedException(),
                            };
                            await ContentTypeSerializer.SerializeExceptionAsync(requestHeader.ContentType.Value, responseBodyCryptoStream, ex);

#if NET5_0_OR_GREATER
                            await responseBodyCryptoStream.FlushFinalBlockAsync();
#else
                            responseBodyCryptoStream.FlushFinalBlock();
#endif
#if NETSTANDARD2_0
                            responseBodyCryptoStream.Dispose();
#else
                            await responseBodyCryptoStream.DisposeAsync();
#endif
                        }
                        else
                        {
                            await ContentTypeSerializer.SerializeExceptionAsync(requestHeader.ContentType.Value, responseBodyStream, ex);

#if NETSTANDARD2_0
                            responseBodyStream.Dispose();
#else
                            await responseBodyStream.DisposeAsync();
#endif
                        }
                        client.Dispose();
                    }
                    catch (Exception ex2)
                    {
                        if (responseBodyStream != null)
                        {
#if NETSTANDARD2_0
                            responseBodyStream.Dispose();
#else
                            await responseBodyStream.DisposeAsync();
#endif
                        }
                        if (stream != null)
                        {
#if NETSTANDARD2_0
                            stream.Dispose();
#else
                            await stream.DisposeAsync();
#endif
                        }
                        client.Dispose();
                        _ = Log.ErrorAsync($"{nameof(TcpRawCQRSServer)} Error {client.Client.RemoteEndPoint}", ex2);
                    }
                    return;
                }

                if (responseBodyStream != null)
                {
#if NETSTANDARD2_0
                    responseBodyStream.Dispose();
#else
                    await responseBodyStream.DisposeAsync();
#endif
                }
                if (requestBodyStream != null)
                {
#if NETSTANDARD2_0
                    requestBodyStream.Dispose();
#else
                    await requestBodyStream.DisposeAsync();
#endif
                }
                if (stream != null)
                {
#if NETSTANDARD2_0
                    stream.Dispose();
#else
                    await stream.DisposeAsync();
#endif
                }
                client.Dispose();
            }
            finally
            {
                BufferArrayPool <byte> .Return(bufferOwner);
            }
        }
            private async Task ListeningThread(IConnection connection, Func <IEvent, Task> handlerAsync)
            {
                canceller = new CancellationTokenSource();

retry:

                try
                {
                    if (this.channel != null)
                    {
                        throw new Exception("Exchange already open");
                    }

                    this.channel = connection.CreateModel();
                    this.channel.ExchangeDeclare(this.exchange, "fanout");

                    var queueName = this.channel.QueueDeclare().QueueName;
                    this.channel.QueueBind(queueName, this.exchange, String.Empty);

                    var consumer = new AsyncEventingBasicConsumer(this.channel);

                    consumer.Received += async(sender, e) =>
                    {
                        bool isEncrypted = e.BasicProperties.Headers != null && e.BasicProperties.Headers.Keys.Contains("Encryption") == true;

                        var stopwatch = new Stopwatch();
                        stopwatch.Start();

                        var properties     = e.BasicProperties;
                        var acknowledgment = new Acknowledgement();

                        if (!isEncrypted && encryptionKey != null)
                        {
                            acknowledgment.Success      = false;
                            acknowledgment.ErrorMessage = "Encryption Required";
                        }
                        else
                        {
                            try
                            {
                                byte[] body = e.Body;
                                if (isEncrypted)
                                {
                                    body = SymmetricEncryptor.Decrypt(encryptionAlgorithm, encryptionKey, e.Body);
                                }

                                var rabbitMessage = RabbitMQCommon.Deserialize <RabbitMQEventMessage>(body);

                                if (rabbitMessage.Claims != null)
                                {
                                    var claimsIdentity = new ClaimsIdentity(rabbitMessage.Claims.Select(x => new Claim(x[0], x[1])), "CQRS");
                                    System.Threading.Thread.CurrentPrincipal = new ClaimsPrincipal(claimsIdentity);
                                }

                                await handlerAsync(rabbitMessage.Message);

                                stopwatch.Stop();

                                _ = Log.TraceAsync($"Received: {e.Exchange} {stopwatch.ElapsedMilliseconds}");

                                acknowledgment.Success = true;
                            }
                            catch (Exception ex)
                            {
                                stopwatch.Stop();

                                ex = ex.GetBaseException();

                                acknowledgment.Success      = false;
                                acknowledgment.ErrorMessage = ex.Message;

                                _ = Log.TraceAsync($"Error: Received: {e.Exchange} {acknowledgment.ErrorMessage} {stopwatch.ElapsedMilliseconds}");

                                _ = Log.ErrorAsync(null, ex);
                            }
                        }
                    };

                    this.channel.BasicConsume(queueName, false, consumer);
                }
                catch (Exception ex)
                {
                    _ = Log.ErrorAsync(ex);

                    if (!canceller.IsCancellationRequested)
                    {
                        if (channel != null)
                        {
                            channel.Close();
                            channel.Dispose();
                            channel = null;
                        }
                        await Task.Delay(retryDelay);

                        goto retry;
                    }
                }

                canceller.Dispose();
                canceller = null;

                if (channel != null)
                {
                    channel.Close();
                    channel.Dispose();
                    channel = null;
                }

                IsOpen = false;
            }
        public ICollection <TModel> DecryptModels(ICollection <TModel> models, Graph <TModel> graph, bool newCopy)
        {
            if (!this.Enabled)
            {
                return(models);
            }

            var properties = GetEncryptableProperties(typeof(TModel), this.Properties);

            if (properties.Length == 0)
            {
                return(models);
            }

            graph = new Graph <TModel>(graph);

            if (newCopy)
            {
                models = Mapper.Map <ICollection <TModel>, TModel[]>(models, graph);
            }

            foreach (TModel model in models)
            {
                foreach (var property in properties)
                {
                    if (graph.HasLocalProperty(property.Name))
                    {
                        if (property.TypeDetail.CoreType == CoreType.String)
                        {
                            string encrypted = (string)property.Getter(model);
                            if (encrypted != null)
                            {
                                try
                                {
                                    if (encrypted.Length > encryptionPrefix.Length && encrypted.Substring(0, encryptionPrefix.Length) == encryptionPrefix)
                                    {
                                        encrypted = encrypted.Substring(encryptionPrefix.Length, encrypted.Length - encryptionPrefix.Length);
                                        string plain = SymmetricEncryptor.Decrypt(encryptionAlgorithm, EncryptionKey, encrypted);
                                        property.Setter(model, plain);
                                    }
                                }
                                catch { }
                            }
                        }
                        else if (property.Type == typeof(byte[]))
                        {
                            byte[] encrypted = (byte[])property.Getter(model);
                            if (encrypted != null)
                            {
                                try
                                {
                                    byte[] plain = SymmetricEncryptor.Decrypt(encryptionAlgorithm, EncryptionKey, encrypted);
                                    property.Setter(model, plain);
                                }
                                catch { }
                            }
                        }
                    }
                }
            }

            return(models);
        }
Пример #6
0
        private void demoButton_Click(object sender, System.EventArgs e)
        {
            SymmetricEncryptor se = null;

            try
            {
                // SymmetricEncryptor-Instanz erzeugen und den eigenen Schlüssel und
                // Initialisierungsvektor übergeben
                se     = new SymmetricEncryptor(SymmetricEncryptAlgorithm.Rijndael);
                se.Key = "dfd0ß3q3ßdsäfßq3#sfjbxya<xsd-:,?";
                se.IV  = "460?-B,-7,kerkh-";

                // Einige Informationen ausgeben
                infoTextBox.AppendText("Schlüssel: " + se.Key + "\r\n");
                infoTextBox.AppendText("Initialisierungsvektor: " + se.IV + "\r\n");
                infoTextBox.AppendText("Chiffrier-Modus: " +
                                       Enum.GetName(typeof(CipherMode), se.CipherMode) + "\r\n");
                infoTextBox.AppendText("Blockgröße: " + se.BlockSize + "\r\n");
                infoTextBox.AppendText("Padding-Modus: " +
                                       Enum.GetName(typeof(PaddingMode), se.PaddingMode) + "\r\n");
                infoTextBox.AppendText("\r\n");;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }

            // Einen String verschlüsseln und wieder entschlüsseln
            string sourceString    = "Das ist ein Test-String mit Umlauten: äöü";
            string encryptedString = se.Encrypt(sourceString);
            string decryptedString = se.Decrypt(encryptedString);

            infoTextBox.AppendText("Quellstring: " + sourceString + "\r\n");
            infoTextBox.AppendText("Verschlüsselt: " + encryptedString + "\r\n");
            infoTextBox.AppendText("Entschlüsselt: " + decryptedString + "\r\n");
            infoTextBox.AppendText("\r\n");;

            // Eine Datei verschlüsseln
            string sourceFileName = Path.Combine(Application.StartupPath,
                                                 "Hitchhiker.txt");
            string destFileName = Path.Combine(Application.StartupPath,
                                               "Hitchhiker_Encrypted.txt");
            FileStream sourceStream = new FileStream(sourceFileName, FileMode.Open,
                                                     FileAccess.Read);
            FileStream destStream = new FileStream(destFileName, FileMode.Create,
                                                   FileAccess.Write);

            se.Encrypt(sourceStream, destStream);
            sourceStream.Close();
            destStream.Close();

            // Die Datei wieder entschlüsseln
            sourceFileName = Path.Combine(Application.StartupPath,
                                          "Hitchhiker_Encrypted.txt");
            destFileName = Path.Combine(Application.StartupPath,
                                        "Hitchhiker_Decrypted.txt");
            sourceStream = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read);
            destStream   = new FileStream(destFileName, FileMode.Create, FileAccess.Write);
            se.Decrypt(sourceStream, destStream);
            sourceStream.Close();
            destStream.Close();

            // MemoryStream ver- und entschlüsseln
            MemoryStream decryptedData = new MemoryStream(
                new Byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 });

            // Streamdaten ausgeben
            infoTextBox.AppendText("Originaler MemoryStream:\r\n");
            int value;

            while ((value = decryptedData.ReadByte()) > -1)
            {
                infoTextBox.AppendText(value + " ");
            }
            decryptedData.Seek(0, SeekOrigin.Begin);
            infoTextBox.AppendText("\r\n\r\n");

            // MemoryStream verschlüsseln
            MemoryStream encryptedData = new MemoryStream();

            se.Encrypt(decryptedData, encryptedData);

            // Streamdaten ausgeben
            infoTextBox.AppendText("Verschlüsselter MemoryStream:\r\n");
            encryptedData.Seek(0, SeekOrigin.Begin);
            while ((value = encryptedData.ReadByte()) > -1)
            {
                infoTextBox.AppendText(value + " ");
            }
            encryptedData.Seek(0, SeekOrigin.Begin);
            infoTextBox.AppendText("\r\n\r\n");

            // MemoryStream entschlüsseln
            decryptedData.Close();
            decryptedData = new MemoryStream();
            se.Decrypt(encryptedData, decryptedData);

            // Ergebnis ausgeben
            infoTextBox.AppendText("Entschlüsselter MemoryStream:\r\n");
            decryptedData.Seek(0, SeekOrigin.Begin);
            while ((value = decryptedData.ReadByte()) > -1)
            {
                infoTextBox.AppendText(value + " ");
            }
            infoTextBox.AppendText("\r\n\r\n");

            // Streams schließen
            encryptedData.Close();
            decryptedData.Close();
        }
Пример #7
0
            public async Task ListeningThread(string host, Func <IEvent, Task> handlerAsync)
            {
                canceller = new CancellationTokenSource();

retry:

                IConsumer <string, byte[]> consumer = null;

                try
                {
                    await KafkaCommon.AssureTopic(host, topic);

                    var consumerConfig = new ConsumerConfig();
                    consumerConfig.BootstrapServers = host;
                    consumerConfig.GroupId          = Guid.NewGuid().ToString();
                    consumerConfig.EnableAutoCommit = false;

                    consumer = new ConsumerBuilder <string, byte[]>(consumerConfig).Build();
                    consumer.Subscribe(topic);

                    for (; ;)
                    {
                        try
                        {
                            if (canceller.Token.IsCancellationRequested)
                            {
                                break;
                            }

                            var consumerResult = consumer.Consume(canceller.Token);
                            consumer.Commit(consumerResult);

                            if (consumerResult.Message.Key == KafkaCommon.MessageKey)
                            {
                                var stopwatch = new Stopwatch();
                                stopwatch.Start();

                                byte[] body = consumerResult.Message.Value;
                                if (encryptionKey != null)
                                {
                                    body = SymmetricEncryptor.Decrypt(encryptionAlgorithm, encryptionKey, body);
                                }

                                var message = KafkaCommon.Deserialize <KafkaEventMessage>(body);

                                if (message.Claims != null)
                                {
                                    var claimsIdentity = new ClaimsIdentity(message.Claims.Select(x => new Claim(x[0], x[1])), "CQRS");
                                    Thread.CurrentPrincipal = new ClaimsPrincipal(claimsIdentity);
                                }

                                await handlerAsync(message.Message);

                                stopwatch.Stop();
                                _ = Log.TraceAsync($"Received Await: {topic}  {stopwatch.ElapsedMilliseconds}");
                            }
                            else
                            {
                                _ = Log.ErrorAsync($"{nameof(KafkaServer)} unrecognized message key {consumerResult.Message.Key}");
                            }
                        }
                        catch (TaskCanceledException)
                        {
                            break;
                        }
                        catch (Exception ex)
                        {
                            _ = Log.TraceAsync($"Error: Received Await: {topic}");
                            _ = Log.ErrorAsync(ex);
                        }
                    }

                    consumer.Unsubscribe();
                }
                catch (Exception ex)
                {
                    _ = Log.ErrorAsync(ex);

                    if (consumer != null)
                    {
                        consumer.Dispose();
                    }
                    consumer = null;

                    if (!canceller.IsCancellationRequested)
                    {
                        await Task.Delay(retryDelay);

                        goto retry;
                    }
                }
                canceller.Dispose();
                canceller = null;
                if (consumer != null)
                {
                    consumer.Dispose();
                }
                IsOpen = false;
            }
Пример #8
0
            private async Task ListeningThread(string host, Func <ICommand, Task> handlerAsync, Func <ICommand, Task> handlerAwaitAsync)
            {
                canceller = new CancellationTokenSource();

retry:

                IConsumer <string, byte[]> consumer = null;

                try
                {
                    await KafkaCommon.AssureTopic(host, topic);

                    var consumerConfig = new ConsumerConfig();
                    consumerConfig.BootstrapServers = host;
                    consumerConfig.GroupId          = topic;
                    consumerConfig.EnableAutoCommit = false;

                    consumer = new ConsumerBuilder <string, byte[]>(consumerConfig).Build();
                    consumer.Subscribe(topic);

                    for (; ;)
                    {
                        Exception error         = null;
                        bool      awaitResponse = false;
                        string    ackTopic      = null;
                        string    ackKey        = null;
                        try
                        {
                            if (canceller.Token.IsCancellationRequested)
                            {
                                break;
                            }

                            var consumerResult = consumer.Consume(canceller.Token);
                            consumer.Commit(consumerResult);

                            awaitResponse = consumerResult.Message.Key == KafkaCommon.MessageWithAckKey;
                            if (awaitResponse)
                            {
                                ackTopic = Encoding.UTF8.GetString(consumerResult.Message.Headers.GetLastBytes(KafkaCommon.AckTopicHeader));
                                ackKey   = Encoding.UTF8.GetString(consumerResult.Message.Headers.GetLastBytes(KafkaCommon.AckKeyHeader));
                            }

                            if (consumerResult.Message.Key == KafkaCommon.MessageKey || awaitResponse)
                            {
                                var stopwatch = new Stopwatch();
                                stopwatch.Start();

                                byte[] body = consumerResult.Message.Value;
                                if (encryptionKey != null)
                                {
                                    body = SymmetricEncryptor.Decrypt(encryptionAlgorithm, encryptionKey, body);
                                }

                                var message = KafkaCommon.Deserialize <KafkaCommandMessage>(body);

                                if (message.Claims != null)
                                {
                                    var claimsIdentity = new ClaimsIdentity(message.Claims.Select(x => new Claim(x[0], x[1])), "CQRS");
                                    Thread.CurrentPrincipal = new ClaimsPrincipal(claimsIdentity);
                                }

                                if (awaitResponse)
                                {
                                    await handlerAwaitAsync(message.Message);
                                }
                                else
                                {
                                    await handlerAsync(message.Message);
                                }

                                stopwatch.Stop();
                                _ = Log.TraceAsync($"Received Await: {topic}  {stopwatch.ElapsedMilliseconds}");
                            }
                            else
                            {
                                _ = Log.ErrorAsync($"{nameof(KafkaServer)} unrecognized message key {consumerResult.Message.Key}");
                            }
                        }
                        catch (TaskCanceledException)
                        {
                            break;
                        }
                        catch (Exception ex)
                        {
                            _     = Log.TraceAsync($"Error: Received Await: {topic}");
                            _     = Log.ErrorAsync(ex);
                            error = ex;
                        }
                        if (awaitResponse)
                        {
                            IProducer <string, byte[]> producer = null;
                            try
                            {
                                var producerConfig = new ProducerConfig();
                                producerConfig.BootstrapServers = host;
                                producerConfig.ClientId         = clientID;

                                producer = new ProducerBuilder <string, byte[]>(producerConfig).Build();

                                var ack = new Acknowledgement()
                                {
                                    Success      = error == null,
                                    ErrorMessage = error?.Message
                                };
                                var body = KafkaCommon.Serialize(ack);
                                if (encryptionKey != null)
                                {
                                    body = SymmetricEncryptor.Encrypt(encryptionAlgorithm, encryptionKey, body);
                                }

                                await producer.ProduceAsync(ackTopic, new Message <string, byte[]>() { Key = ackKey, Value = body });
                            }

                            catch (Exception ex)
                            {
                                _ = Log.ErrorAsync(ex);
                            }
                            finally
                            {
                                if (producer != null)
                                {
                                    producer.Dispose();
                                }
                            }
                        }
                    }

                    consumer.Unsubscribe();
                }
                catch (Exception ex)
                {
                    _ = Log.ErrorAsync(ex);

                    if (consumer != null)
                    {
                        consumer.Dispose();
                    }
                    consumer = null;

                    if (!canceller.IsCancellationRequested)
                    {
                        await Task.Delay(retryDelay);

                        goto retry;
                    }
                }
                canceller.Dispose();
                canceller = null;
                if (consumer != null)
                {
                    consumer.Dispose();
                }
                IsOpen = false;
            }
Пример #9
0
        private async Task AckListeningThread()
        {
            await KafkaCommon.AssureTopic(host, ackTopic);

            var consumerConfig = new ConsumerConfig();

            consumerConfig.BootstrapServers = host;
            consumerConfig.GroupId          = ackTopic;
            consumerConfig.EnableAutoCommit = false;

            IConsumer <string, byte[]> consumer = null;

            try
            {
                consumer = new ConsumerBuilder <string, byte[]>(consumerConfig).Build();
                consumer.Subscribe(ackTopic);
                for (; ;)
                {
                    try
                    {
                        if (canceller.Token.IsCancellationRequested)
                        {
                            break;
                        }

                        var consumerResult = consumer.Consume(canceller.Token);
                        consumer.Commit(consumerResult);

                        if (!ackCallbacks.TryRemove(consumerResult.Message.Key, out Action <Acknowledgement> callback))
                        {
                            continue;
                        }

                        var response = consumerResult.Message.Value;
                        if (encryptionKey != null)
                        {
                            response = SymmetricEncryptor.Decrypt(encryptionAlgorithm, encryptionKey, response);
                        }
                        var ack = KafkaCommon.Deserialize <Acknowledgement>(response);

                        callback(ack);
                    }
                    catch (TaskCanceledException)
                    {
                        break;
                    }
                    catch { }
                }

                consumer.Unsubscribe();
                await KafkaCommon.DeleteTopic(host, ackTopic);
            }
            finally
            {
                canceller.Dispose();
                if (consumer != null)
                {
                    consumer.Dispose();
                }
            }
        }