Skip to content

Commit

Permalink
Updates and corrections to Serialization guide.
Browse files Browse the repository at this point in the history
  • Loading branch information
houseofcat committed Apr 29, 2024
1 parent 6c70429 commit 88e7a8e
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 39 deletions.
107 changes: 71 additions & 36 deletions guides/rabbitmq/Serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,27 @@ You can configure your own, or use one of the provided `IserializationProviders`
to help simplify code. Here we use the `JsonProvider` to take `<TIn> input` and
serialize the object to `byte[]`.
```csharp
using HouseofCat.RabbitMQ;
using HouseofCat.RabbitMQ.Pools;
using HouseofCat.Serialization;
using HouseofCat.Utilities;

var rabbitOptions = JsonFileReader.ReadFileAsync<RabbitOptions>("SampleRabbitOptions.json");
var rabbitOptions = await JsonFileReader.ReadFileAsync<RabbitOptions>("SampleRabbitOptions.json");
var channelPool = new ChannelPool(rabbitOptions);
var jsonProvider = new JsonProvider();

var channelHost = await channelPool.GetChannelAsync();
var channel = channelHost.GetChannel();

var properties = channel.CreateBasicProperties();
var properties = channelHost.Channel.CreateBasicProperties();
properties.DeliveryMode = 2;

var data = jsonProvider.Serialize(input);
var myClass = new { Name = "MyName", Value = 42 };
var body = jsonProvider.Serialize(myClass);

var error = false;
try
{
channel.BasicPublish("MyExchange", "MyRoutingKey", properties, data);
channelHost.Channel.BasicPublish("MyExchange", "MyRoutingKey", false, properties, body);
}
catch (Exception ex)
{
Expand All @@ -63,27 +66,30 @@ await channelPool.ReturnChannelAsync(channelHost, error);
### Serialize And Compress
An example showing JsonSerialization and GzipCompression.
```csharp
using HouseofCat.Serialization;
using HouseofCat.Compression;
using HouseofCat.RabbitMQ;
using HouseofCat.RabbitMQ.Pools;
using HouseofCat.Serialization;
using HouseofCat.Utilities;

var rabbitOptions = JsonFileReader.ReadFileAsync<RabbitOptions>("SampleRabbitOptions.json");
var rabbitOptions = await JsonFileReader.ReadFileAsync<RabbitOptions>("SampleRabbitOptions.json");
var channelPool = new ChannelPool(rabbitOptions);
var jsonProvider = new JsonProvider();
var gzipProvider = new GzipProvider();

var channelHost = await channelPool.GetChannelAsync();
var channel = channelHost.GetChannel();

var properties = channel.CreateBasicProperties();
var properties = channelHost.Channel.CreateBasicProperties();
properties.DeliveryMode = 2;

var dataAsJson = jsonProvider.Serialize(input);
var compressedJson = gzipProvider.Compress(dataAsJson);
var myClass = new { Name = "MyName", Value = 42 };
var myClassAsJson = jsonProvider.Serialize(myClass);
var body = gzipProvider.Compress(myClassAsJson);

var error = false;
try
{
channel.BasicPublish("MyExchange", "MyRoutingKey", properties, compressedJson);
channelHost.Channel.BasicPublish("MyExchange", "MyRoutingKey", false, properties, body);
}
catch (Exception ex)
{
Expand All @@ -97,10 +103,15 @@ await channelPool.ReturnChannelAsync(channelHost, error);
### Serialize, Compression, And Encrypt
An example showing JsonSerialization, Gzip compression, and AesGcm 256 bit encryption.
```csharp
using HouseofCat.Serialization;
using HouseofCat.Compression;
using HouseofCat.Encryption;
using HouseofCat.Hashing;
using HouseofCat.RabbitMQ;
using HouseofCat.RabbitMQ.Pools;
using HouseofCat.Serialization;
using HouseofCat.Utilities;

var rabbitOptions = JsonFileReader.ReadFileAsync<RabbitOptions>("SampleRabbitOptions.json");
var rabbitOptions = await JsonFileReader.ReadFileAsync<RabbitOptions>("SampleRabbitOptions.json");
var channelPool = new ChannelPool(rabbitOptions);
var jsonProvider = new JsonProvider();
var gzipProvider = new GzipProvider();
Expand All @@ -110,19 +121,18 @@ var aes256Key = argonProvider.GetHashKey("MySuperSecretPassword", "MySaltySaltSa
var aesProvider = new AesGcmEncryptionProvider(aes256Key);

var channelHost = await channelPool.GetChannelAsync();
var channel = channelHost.GetChannel();

var properties = channel.CreateBasicProperties();
var properties = channelHost.Channel.CreateBasicProperties();
properties.DeliveryMode = 2;

var dataAsJson = jsonProvider.Serialize(input);
var compressedJson = gzipProvider.Compress(dataAsJson);
var encryptedCompressedJson = aesProvider.Encrypt(encryptedCompressedJson);
var myClass = new { Name = "MyName", Value = 42 };
var myClassAsJson = jsonProvider.Serialize(myClass);
var compressedJson = gzipProvider.Compress(myClassAsJson);
var body = aesProvider.Encrypt(compressedJson);
var error = false;

try
{
channel.BasicPublish("MyExchange", "MyRoutingKey", properties, compressedJson);
channelHost.Channel.BasicPublish("MyExchange", "MyRoutingKey", false, properties, compressedJson);
}
catch (Exception ex)
{
Expand All @@ -136,54 +146,79 @@ await channelPool.ReturnChannelAsync(channelHost, error);
### DataTransfomer Alternative #1
You can also use the `DataTransformer` to simplify the process of serialization, compression, and/or encryption.
```csharp
using HouseofCat.Compression;
using HouseofCat.Data;
using HouseofCat.Encryption;
using HouseofCat.Hashing;
using HouseofCat.Serialization;

var hashingProvider = new ArgonHashingProvider();
var hashKey = hashingProvider.GetHashKey(Passphrase, Salt, 32);
var hashKey = hashingProvider.GetHashKey("PasswordMcPassword", "SaltySaltSalt", 32);

var dataTransformer = new DataTransformer(
new JsonProvider(),
new AesGcmEncryptionProvider(hashKey),
new GzipProvider());

var data = dataTransformer.Serialize(input)
var myClass = new { Name = "MyName", Value = 42 };
var data = dataTransformer.Serialize(myClass);
```

### DataTransfomer Alternative #2
You can also use the `DataTransformer` to simplify the process of serialization, compression, and/or encryption.
This constructor assumes you want to use Json, Gzip, and AesGcm 256 bit encryption.
```csharp
var hashingProvider = new ArgonHashingProvider();
var hashKey = hashingProvider.GetHashKey(Passphrase, Salt, 32);
using HouseofCat.Data;

// Json, Gzip, and AesGcm 256 bit encryption.
_middleware = new DataTransformer(Passphrase, Salt, 32);
var transformer = new DataTransformer("PasswordMcPassword", "SaltySaltSalt", 32);

// Json and Gzip only.
_middleware = new DataTransformer();
// var transformer = new DataTransformer();
_serializedData = _middleware.Serialize(input)
var myClass = new { Name = "MyName", Value = 42 };
var body = transformer.Serialize(myClass);
```

### Deserializing
This is kind of simple. You want to deserialize, decompress, and decrypt your `byte[]` back into your object
in the opposite manner you performed the serialization, compression, and encryption.
```csharp
var dataAsJson = jsonProvider.Serialize(input);
using HouseofCat.Compression;
using HouseofCat.Encryption;
using HouseofCat.Hashing;
using HouseofCat.Serialization;

var jsonProvider = new JsonProvider();
var gzipProvider = new GzipProvider();
var argonProvider = new ArgonHashingProvider();

var aes256Key = argonProvider.GetHashKey("MySuperSecretPassword", "MySaltySaltSalt", size: 32);
var aesProvider = new AesGcmEncryptionProvider(aes256Key);

// Making encrypted compressed json.
var myClass = new MyClass { Name = "MyName", Value = 42 };
var dataAsJson = jsonProvider.Serialize(myClass);
var compressedJson = gzipProvider.Compress(dataAsJson);
var encryptedCompressedJson = aesProvider.Encrypt(encryptedCompressedJson);
var encryptedCompressedJson = aesProvider.Encrypt(compressedJson);

...

// Decrypting and decompressing json into your object.
var decryptedCompressedJson = aesProvider.Decrypt(encryptedCompressedJson);
var decompressedJson = gzipProvider.Decompress(decryptedCompressedJson);
var myObject = _jsonProvider.Deserialize<TOut>(decompressedJson);
var myObject = jsonProvider.Deserialize<MyClass>(decompressedJson);
```

### Deserializing With DataTransformer
```csharp
// Json, Gzip, and AesGcm 256 bit encryption.
var dataTransformer = new DataTransformer(Passphrase, Salt, 32);
using HouseofCat.Data;

var transformer = new DataTransformer("PasswordMcPassword", "SaltySaltSalt", 32);

var data = dataTransformer.Serialize(input)
// Make encrypted and compressed json from object.
var myClass = new MyClass { Name = "MyName", Value = 42 };
var body = transformer.Serialize(myClass);

var myObject = dataTransformer.Deserialize<TOut>(data);
// Get object from encrypted compressed json.
var myObject = transformer.Deserialize<MyClass>(body);
```
21 changes: 18 additions & 3 deletions src/HouseofCat.Data/DataTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using HouseofCat.Utilities.Errors;
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;

namespace HouseofCat.Data;
Expand Down Expand Up @@ -57,6 +58,7 @@ public DataTransformer(
/// <typeparam name="TOut"></typeparam>
/// <param name="data"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Task<TOut> DeserializeAsync<TOut>(ReadOnlyMemory<byte> data)
{
if (_encryptionProvider is not null && _compressionProvider is not null)
Expand All @@ -82,6 +84,7 @@ public Task<TOut> DeserializeAsync<TOut>(ReadOnlyMemory<byte> data)
/// <typeparam name="TOut"></typeparam>
/// <param name="data"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TOut Deserialize<TOut>(ReadOnlyMemory<byte> data)
{
if (_encryptionProvider is not null && _compressionProvider is not null)
Expand All @@ -100,6 +103,7 @@ public TOut Deserialize<TOut>(ReadOnlyMemory<byte> data)
return _serializationProvider.Deserialize<TOut>(data);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TOut DecryptDecompressDeserialize<TOut>(ReadOnlyMemory<byte> data)
{
var decryptedData = _encryptionProvider.Decrypt(data);
Expand All @@ -108,6 +112,7 @@ public TOut DecryptDecompressDeserialize<TOut>(ReadOnlyMemory<byte> data)
return _serializationProvider.Deserialize<TOut>(decompressedData);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public async Task<TOut> DecryptDecompressDeserializeAsync<TOut>(ReadOnlyMemory<byte> data)
{
var memoryStream = _encryptionProvider.DecryptToStream(data);
Expand All @@ -124,13 +129,15 @@ public async Task<TOut> DecryptDecompressDeserializeAsync<TOut>(ReadOnlyMemory<b
.ConfigureAwait(false);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TOut DecryptDeserialize<TOut>(ReadOnlyMemory<byte> data)
{
var decryptedData = _encryptionProvider.Decrypt(data);

return _serializationProvider.Deserialize<TOut>(decryptedData);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public async Task<TOut> DecryptDeserializeAsync<TOut>(ReadOnlyMemory<byte> data)
{
var memoryStream = _encryptionProvider.DecryptToStream(data);
Expand All @@ -141,13 +148,15 @@ public async Task<TOut> DecryptDeserializeAsync<TOut>(ReadOnlyMemory<byte> data)
.ConfigureAwait(false);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TOut DecompressDeserialize<TOut>(ReadOnlyMemory<byte> data)
{
var decompressedData = _compressionProvider.Decompress(data);

return _serializationProvider.Deserialize<TOut>(decompressedData);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public async Task<TOut> DecompressDeserializeAsync<TOut>(ReadOnlyMemory<byte> data)
{
var memoryStream = _compressionProvider.DecompressToStream(data);
Expand All @@ -158,6 +167,7 @@ public async Task<TOut> DecompressDeserializeAsync<TOut>(ReadOnlyMemory<byte> da
.ConfigureAwait(false);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlyMemory<byte> Serialize<TIn>(TIn input)
{
if (_encryptionProvider is not null && _compressionProvider is not null)
Expand All @@ -176,6 +186,7 @@ public ReadOnlyMemory<byte> Serialize<TIn>(TIn input)
return _serializationProvider.Serialize(input);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public async Task<ReadOnlyMemory<byte>> SerializeAsync<TIn>(TIn input)
{
if (_encryptionProvider is not null && _compressionProvider is not null)
Expand All @@ -194,6 +205,7 @@ public async Task<ReadOnlyMemory<byte>> SerializeAsync<TIn>(TIn input)
return _serializationProvider.Serialize(input);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public async Task<ReadOnlyMemory<byte>> SerializeCompressEncryptAsync<TIn>(TIn input)
{
var memoryStream = new MemoryStream();
Expand All @@ -218,6 +230,7 @@ await _serializationProvider
return encryptionStream.ToArray();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlyMemory<byte> SerializeCompressEncrypt<TIn>(TIn input)
{
return _encryptionProvider
Expand All @@ -226,6 +239,7 @@ public ReadOnlyMemory<byte> SerializeCompressEncrypt<TIn>(TIn input)
.Serialize(input)));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public async Task<ReadOnlyMemory<byte>> SerializeEncryptAsync<TIn>(TIn input)
{
using var memoryStream = new MemoryStream();
Expand All @@ -244,13 +258,15 @@ await _serializationProvider
return compressionStream.ToArray();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlyMemory<byte> SerializeEncrypt<TIn>(TIn input)
{
return _encryptionProvider
.Encrypt(_serializationProvider
.Serialize(input));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public async Task<ReadOnlyMemory<byte>> SerializeCompressAsync<TIn>(TIn input)
{
using var memoryStream = new MemoryStream();
Expand All @@ -267,10 +283,9 @@ public async Task<ReadOnlyMemory<byte>> SerializeCompressAsync<TIn>(TIn input)
return compressionStream.ToArray();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlyMemory<byte> SerializeCompress<TIn>(TIn input)
{
return _compressionProvider
.Compress(_serializationProvider
.Serialize(input));
return _compressionProvider.Compress(_serializationProvider.Serialize(input));
}
}
Loading

0 comments on commit 88e7a8e

Please sign in to comment.