diff --git a/README.md b/README.md index f252bd76..1c1417c9 100644 --- a/README.md +++ b/README.md @@ -87,12 +87,12 @@ See [benchmarks results](https://github.com/MichaCo/CacheManager/blob/dev/Benchm * **System.Web.Caching** based (included in the Web package) * **Serialization** can now be configured. Serialization is only needed in distributed caches. If no additional serialization package is installed and configured, Binary serialization will be used (if available) +After serialization the content can be compressed The following are the currently available serialization options: * Binary (build in if the full CLR is being used) * **Json** based on the popular Newtonsoft.Json library - * **Json** with Gzip compression * **Bond** based on Microsoft.Bond supporting all three available variants - * **DataContract** based on System.Runtime.Serialization library supporting binary, Json & Json with Gzip compression + * **DataContract** based on System.Runtime.Serialization library supporting binary, Json * **Protocol Buffer** Google's protobuf. The package uses Mark's [protobuf-net](https://github.com/mgravell/protobuf-net) implementation. * **Update values with lock or transaction** for distributed caches. The interfaced provides a simple update method which internally ensures you work with the latest version. diff --git a/src/CacheManager.Core/CacheManagerConfiguration.cs b/src/CacheManager.Core/CacheManagerConfiguration.cs index 6755fb38..8776b452 100644 --- a/src/CacheManager.Core/CacheManagerConfiguration.cs +++ b/src/CacheManager.Core/CacheManagerConfiguration.cs @@ -93,6 +93,12 @@ public CacheManagerConfiguration() /// The serializer activator. public Type SerializerType { get; set; } + /// + /// Gets or sets if after serializing/before deserializing should compress/decompress the data. + /// + /// Should compress. + public bool ShouldCompress { get; set; } + /// /// Gets or sets additional arguments which should be used instantiating the serializer. /// @@ -127,4 +133,4 @@ public override string ToString() return $"{Name}: {string.Join(", ", CacheHandleConfigurations)}"; } } -} \ No newline at end of file +} diff --git a/src/CacheManager.Core/Configuration/CacheManagerSection.cs b/src/CacheManager.Core/Configuration/CacheManagerSection.cs index 582981e5..bafa75f9 100644 --- a/src/CacheManager.Core/Configuration/CacheManagerSection.cs +++ b/src/CacheManager.Core/Configuration/CacheManagerSection.cs @@ -319,6 +319,7 @@ public sealed class CacheManagerHandleCollection : ConfigurationElementCollectio private const string BackplaneNameKey = "backplaneName"; private const string BackplaneTypeKey = "backplaneType"; private const string SerializerTypeKey = "serializerType"; + private const string ShouldCompressKey = "shouldCompress"; private const string EnablePerformanceCountersKey = "enablePerformanceCounters"; private const string EnableStatisticsKey = "enableStatistics"; private const string MaxRetriesKey = "maxRetries"; @@ -385,6 +386,23 @@ public string SerializerType } } + /// + /// Gets or sets if should compress after serialization. + /// + /// The type of the serializer. + [ConfigurationProperty(ShouldCompressKey, IsRequired = false)] + public bool ShouldCompress + { + get + { + return (bool)this[ShouldCompressKey]; + } + set + { + this[ShouldCompressKey] = value; + } + } + /// /// Gets or sets a value indicating whether performance counters should be enabled. /// diff --git a/src/CacheManager.Core/Configuration/ConfigurationBuilder.cs b/src/CacheManager.Core/Configuration/ConfigurationBuilder.cs index 5d0a0dbe..be2f7c63 100644 --- a/src/CacheManager.Core/Configuration/ConfigurationBuilder.cs +++ b/src/CacheManager.Core/Configuration/ConfigurationBuilder.cs @@ -286,6 +286,8 @@ internal static CacheManagerConfiguration LoadFromSection(CacheManagerSection se cfg.BackplaneConfigurationKey = managerCfg.BackplaneName; } + cfg.ShouldCompress = managerCfg.ShouldCompress; + // build serializer if set if (!string.IsNullOrWhiteSpace(managerCfg.SerializerType)) { @@ -712,6 +714,15 @@ public ConfigurationBuilderCachePart WithRetryTimeout(int timeoutMillis) return this; } + /// + /// Adds compression after serialization + /// + public ConfigurationBuilderCachePart WithCompression() + { + Configuration.ShouldCompress = true; + return this; + } + /// /// Sets the update mode of the cache. /// If nothing is set, the default will be CacheUpdateMode.None. diff --git a/src/CacheManager.Core/ICacheManagerConfiguration.cs b/src/CacheManager.Core/ICacheManagerConfiguration.cs index 97573ce7..62751195 100644 --- a/src/CacheManager.Core/ICacheManagerConfiguration.cs +++ b/src/CacheManager.Core/ICacheManagerConfiguration.cs @@ -95,6 +95,12 @@ public interface IReadOnlyCacheManagerConfiguration /// The retry timeout. int RetryTimeout { get; } + /// + /// Gets or sets if after serializing/before deserializing should compress/decompress the data. + /// + /// Should compress. + bool ShouldCompress { get; } + /// /// Gets the factory method for a cache serializer. /// @@ -119,4 +125,4 @@ public interface IReadOnlyCacheManagerConfiguration /// CacheUpdateMode UpdateMode { get; } } -} \ No newline at end of file +} diff --git a/src/CacheManager.Core/Internal/CacheReflectionHelper.cs b/src/CacheManager.Core/Internal/CacheReflectionHelper.cs index fcbc98bf..6cdc1174 100644 --- a/src/CacheManager.Core/Internal/CacheReflectionHelper.cs +++ b/src/CacheManager.Core/Internal/CacheReflectionHelper.cs @@ -52,7 +52,8 @@ internal static ICacheSerializer CreateSerializer(ICacheManagerConfiguration con args = configuration.SerializerTypeArguments.Concat(args).ToArray(); } - return (ICacheSerializer)CreateInstance(configuration.SerializerType, args); + var serializer = (ICacheSerializer)CreateInstance(configuration.SerializerType, args); + return configuration.ShouldCompress ? new CompressionSerializer(serializer) : serializer; } return null; diff --git a/src/CacheManager.Serialization.Json/GzJsonCacheSerializer.cs b/src/CacheManager.Core/Internal/CompressionSerializer.cs similarity index 62% rename from src/CacheManager.Serialization.Json/GzJsonCacheSerializer.cs rename to src/CacheManager.Core/Internal/CompressionSerializer.cs index 6f29142a..35bbf89f 100644 --- a/src/CacheManager.Serialization.Json/GzJsonCacheSerializer.cs +++ b/src/CacheManager.Core/Internal/CompressionSerializer.cs @@ -1,50 +1,59 @@ using System; +using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; +using System.Text; +using System.Threading.Tasks; using CacheManager.Core.Utility; -using Newtonsoft.Json; -namespace CacheManager.Serialization.Json +namespace CacheManager.Core.Internal { /// - /// Implements the ICacheSerializer contract using Newtonsoft.Json and the loseless compression. + /// Wrapper for other serializer to add compression capabilities /// - public class GzJsonCacheSerializer : JsonCacheSerializer + public class CompressionSerializer : ICacheSerializer { /// - /// Initializes a new instance of the class. + /// The serializer that we used after decompression and before compression. /// - public GzJsonCacheSerializer() - : base(new JsonSerializerSettings(), new JsonSerializerSettings()) - { - } + public ICacheSerializer InternalSerializer { get; } /// - /// Initializes a new instance of the class. - /// With this overload the settings for de-/serialization can be set independently. + /// Initializes a new instance of the class. /// - /// The settings which should be used during serialization. - /// The settings which should be used during deserialization. - public GzJsonCacheSerializer(JsonSerializerSettings serializationSettings, JsonSerializerSettings deserializationSettings) - : base(serializationSettings, deserializationSettings) + /// Serializer that we used after decompression and before compression. + public CompressionSerializer(ICacheSerializer internalSerializer) + { + this.InternalSerializer = internalSerializer; + } + + /// + public CacheItem DeserializeCacheItem(byte[] value, Type valueType) + { + return InternalSerializer.DeserializeCacheItem(value, valueType); + } + + /// + public byte[] SerializeCacheItem(CacheItem value) { + return InternalSerializer.SerializeCacheItem(value); } /// - public override object Deserialize(byte[] data, Type target) + public object Deserialize(byte[] data, Type target) { Guard.NotNull(data, nameof(data)); var compressedData = Decompression(data); - return base.Deserialize(compressedData, target); + return InternalSerializer.Deserialize(compressedData, target); } /// - public override byte[] Serialize(T value) + public byte[] Serialize(T value) { Guard.NotNull(value, nameof(value)); - var data = base.Serialize(value); + var data = InternalSerializer.Serialize(value); return Compression(data); } diff --git a/src/CacheManager.Microsoft.Extensions.Configuration/MicrosoftConfigurationExtensions.cs b/src/CacheManager.Microsoft.Extensions.Configuration/MicrosoftConfigurationExtensions.cs index 16b9e564..7c8732bb 100644 --- a/src/CacheManager.Microsoft.Extensions.Configuration/MicrosoftConfigurationExtensions.cs +++ b/src/CacheManager.Microsoft.Extensions.Configuration/MicrosoftConfigurationExtensions.cs @@ -22,8 +22,8 @@ public static class MicrosoftConfigurationExtensions private const string ConfigurationName = "name"; private const string ConfigurationType = "type"; private const string ConfigurationKnownType = "knownType"; + private const string ShouldCompress = "shouldCompress"; private const string TypeJsonCacheSerializer = "CacheManager.Serialization.Json.JsonCacheSerializer, CacheManager.Serialization.Json"; - private const string TypeGzJsonCacheSerializer = "CacheManager.Serialization.Json.GzJsonCacheSerializer, CacheManager.Serialization.Json"; private const string TypeProtobufCacheSerializer = "CacheManager.Serialization.ProtoBuf.ProtoBufSerializer, CacheManager.Serialization.ProtoBuf"; private const string TypeBondCompactBinarySerializer = "CacheManager.Serialization.Bond.BondCompactBinaryCacheSerializer, CacheManager.Serialization.Bond"; private const string TypeBondFastBinarySerializer = "CacheManager.Serialization.Bond.BondFastBinaryCacheSerializer, CacheManager.Serialization.Bond"; @@ -40,6 +40,9 @@ public static class MicrosoftConfigurationExtensions private const string TypeRedisConfigurations = "CacheManager.Redis.RedisConfigurations, CacheManager.StackExchange.Redis"; private const string KnonwSerializerBinary = "binary"; private const string KnonwSerializerJson = "json"; + /// + /// absolete, available for backward compatibility + /// private const string KnonwSerializerGzJson = "gzjson"; private const string KnonwSerializerProto = "protobuf"; private const string KnonwSerializerBondCompact = "bondcompactbinary"; @@ -429,7 +432,6 @@ private static Type GetKnownLoggerFactoryType(string knownTypeName, string path) private static void GetSerializerConfiguration(CacheManagerConfiguration managerConfiguration, IConfigurationSection configuration) { var serializerSection = configuration.GetSection(SerializerSection); - if (serializerSection.GetChildren().Count() == 0) { // no serializer @@ -439,6 +441,8 @@ private static void GetSerializerConfiguration(CacheManagerConfiguration manager var knownType = serializerSection[ConfigurationKnownType]; var type = serializerSection[ConfigurationType]; + managerConfiguration.ShouldCompress = serializerSection.GetValue(ShouldCompress); + if (string.IsNullOrWhiteSpace(knownType) && string.IsNullOrWhiteSpace(type)) { throw new InvalidOperationException( @@ -447,6 +451,10 @@ private static void GetSerializerConfiguration(CacheManagerConfiguration manager if (string.IsNullOrWhiteSpace(type)) { + if (knownType.ToLowerInvariant() == KnonwSerializerGzJson) + { + managerConfiguration.ShouldCompress = true; + } managerConfiguration.SerializerType = GetKnownSerializerType(knownType, serializerSection.Path); } else @@ -473,8 +481,9 @@ private static Type GetKnownSerializerType(string knownTypeName, string path) case KnonwSerializerJson: return Type.GetType(TypeJsonCacheSerializer, true); + // KnonwSerializerGzJson is absolete, instead we will create TypeJsonCacheSerializer and add compression wrapper to it case KnonwSerializerGzJson: - return Type.GetType(TypeGzJsonCacheSerializer, true); + return Type.GetType(TypeJsonCacheSerializer, true); case KnonwSerializerProto: return Type.GetType(TypeProtobufCacheSerializer, true); diff --git a/src/CacheManager.Serialization.DataContract/DataContractConfigurationBuilderExtensions.cs b/src/CacheManager.Serialization.DataContract/DataContractConfigurationBuilderExtensions.cs index 1a839aea..2c888920 100644 --- a/src/CacheManager.Serialization.DataContract/DataContractConfigurationBuilderExtensions.cs +++ b/src/CacheManager.Serialization.DataContract/DataContractConfigurationBuilderExtensions.cs @@ -1,4 +1,5 @@ -using System.Runtime.Serialization; +using System; +using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using CacheManager.Serialization.DataContract; using static CacheManager.Core.Utility.Guard; @@ -56,17 +57,19 @@ public static ConfigurationBuilderCachePart WithDataContractJsonSerializer(this /// The configuration part. /// Settings for the serializer. /// The builder instance. + [Obsolete("Use .WithDataContractJsonSerializer().WithCompression() instead")] public static ConfigurationBuilderCachePart WithDataContractGzJsonSerializer(this ConfigurationBuilderCachePart part, DataContractJsonSerializerSettings serializerSettings = null) { NotNull(part, nameof(part)); + part.WithCompression(); if (serializerSettings == null) { - return part.WithSerializer(typeof(DataContractGzJsonCacheSerializer)); + return part.WithSerializer(typeof(DataContractJsonCacheSerializer)); } else { - return part.WithSerializer(typeof(DataContractGzJsonCacheSerializer), serializerSettings); + return part.WithSerializer(typeof(DataContractJsonCacheSerializer), serializerSettings); } } diff --git a/src/CacheManager.Serialization.DataContract/DataContractGzJsonCacheSerializer.cs b/src/CacheManager.Serialization.DataContract/DataContractGzJsonCacheSerializer.cs deleted file mode 100644 index d320ae48..00000000 --- a/src/CacheManager.Serialization.DataContract/DataContractGzJsonCacheSerializer.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.IO; -using System.IO.Compression; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Json; - -namespace CacheManager.Serialization.DataContract -{ - /// - /// This class (de)compresses the (de)serialized output of DataContractJsonCacheSerializer. - /// - public class DataContractGzJsonCacheSerializer : DataContractJsonCacheSerializer - { - /// - /// Creates instance of DataContractGzJsonCacheSerializer. - /// - public DataContractGzJsonCacheSerializer() : this(new DataContractJsonSerializerSettings()) - { - } - - /// - /// Creates instance of DataContractGzJsonCacheSerializer. - /// - /// Serializer's settings - public DataContractGzJsonCacheSerializer(DataContractJsonSerializerSettings serializerSettings = null) : base(serializerSettings) - { - } - - /// - protected override void WriteObject(XmlObjectSerializer serializer, Stream stream, object graph) - { - using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Compress, true)) - { - base.WriteObject(serializer, gzipStream, graph); - gzipStream.Flush(); - } - } - - /// - protected override object ReadObject(XmlObjectSerializer serializer, Stream stream) - { - using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress)) - { - return base.ReadObject(serializer, gzipStream); - } - } - } -} diff --git a/src/CacheManager.Serialization.Json/JsonConfigurationBuilderExtensions.cs b/src/CacheManager.Serialization.Json/JsonConfigurationBuilderExtensions.cs index 050ff630..2a03146f 100644 --- a/src/CacheManager.Serialization.Json/JsonConfigurationBuilderExtensions.cs +++ b/src/CacheManager.Serialization.Json/JsonConfigurationBuilderExtensions.cs @@ -1,4 +1,5 @@ -using CacheManager.Serialization.Json; +using System; +using CacheManager.Serialization.Json; using Newtonsoft.Json; using static CacheManager.Core.Utility.Guard; @@ -40,11 +41,12 @@ public static ConfigurationBuilderCachePart WithJsonSerializer(this Configuratio /// /// The configuration part. /// The builder instance. + [Obsolete("Use .WithJsonSerializer().WithCompression() instead")] public static ConfigurationBuilderCachePart WithGzJsonSerializer(this ConfigurationBuilderCachePart part) { NotNull(part, nameof(part)); - - return part.WithSerializer(typeof(GzJsonCacheSerializer)); + part.WithCompression(); + return part.WithSerializer(typeof(JsonCacheSerializer)); } /// @@ -54,11 +56,12 @@ public static ConfigurationBuilderCachePart WithGzJsonSerializer(this Configurat /// The settings to be used during serialization. /// The settings to be used during deserialization. /// The builder instance. + [Obsolete("Use .WithJsonSerializer().WithCompression() instead")] public static ConfigurationBuilderCachePart WithGzJsonSerializer(this ConfigurationBuilderCachePart part, JsonSerializerSettings serializationSettings, JsonSerializerSettings deserializationSettings) { NotNull(part, nameof(part)); - - return part.WithSerializer(typeof(GzJsonCacheSerializer), serializationSettings, deserializationSettings); + part.WithCompression(); + return part.WithSerializer(typeof(JsonCacheSerializer), serializationSettings, deserializationSettings); } } -} \ No newline at end of file +} diff --git a/test/CacheManager.Benchmarks/SerializationBenchmark.cs b/test/CacheManager.Benchmarks/SerializationBenchmark.cs index fc0b2e7d..1c97250c 100644 --- a/test/CacheManager.Benchmarks/SerializationBenchmark.cs +++ b/test/CacheManager.Benchmarks/SerializationBenchmark.cs @@ -18,7 +18,7 @@ public class SerializationBenchmark private Queue> _payload; private BinaryCacheSerializer _binary = new BinaryCacheSerializer(); private JsonCacheSerializer _json = new JsonCacheSerializer(); - private GzJsonCacheSerializer _jsonGz = new GzJsonCacheSerializer(); + private CompressionSerializer _jsonWithCompression = new CompressionSerializer(new JsonCacheSerializer()); private ProtoBufSerializer _proto = new Serialization.ProtoBuf.ProtoBufSerializer(); private BondCompactBinaryCacheSerializer _bondBinary = new BondCompactBinaryCacheSerializer(18000); private BondFastBinaryCacheSerializer _bondFastBinary = new BondFastBinaryCacheSerializer(18000); @@ -100,8 +100,8 @@ public void JsonGzSerializer() { ExecRun((item) => { - var data = _jsonGz.SerializeCacheItem(item); - var result = _jsonGz.DeserializeCacheItem(data, _pocoType); + var data = _jsonWithCompression.SerializeCacheItem(item); + var result = _jsonWithCompression.DeserializeCacheItem(data, _pocoType); if (result == null) { throw new Exception(); diff --git a/test/CacheManager.MSConfiguration.TypeLoad.Tests/MicrosoftConfigurationTests.cs b/test/CacheManager.MSConfiguration.TypeLoad.Tests/MicrosoftConfigurationTests.cs index 55806674..e4c59e4e 100644 --- a/test/CacheManager.MSConfiguration.TypeLoad.Tests/MicrosoftConfigurationTests.cs +++ b/test/CacheManager.MSConfiguration.TypeLoad.Tests/MicrosoftConfigurationTests.cs @@ -111,21 +111,6 @@ public void Configuration_Serializer_Json_NotReferenced() action.Should().Throw().WithMessage("*serializer type 'Json' could not be loaded*"); } - [Fact] - public void Configuration_Serializer_GzJson_NotReferenced() - { - var data = new Dictionary - { - {"cacheManagers:0:name", "name"}, - {"cacheManagers:0:handles:0:knownType", "Dictionary"}, - {"cacheManagers:0:serializer:knownType", "GzJson"} - }; - - var config = GetConfiguration(data); - Action action = () => config.GetCacheConfiguration("name"); - action.Should().Throw().WithMessage("*serializer type 'GzJson' could not be loaded*"); - } - [Fact] public void Configuration_Serializer_Protobuf_NotReferenced() { diff --git a/test/CacheManager.Tests/CacheFactoryTests.cs b/test/CacheManager.Tests/CacheFactoryTests.cs index cf0d97c8..759615bb 100644 --- a/test/CacheManager.Tests/CacheFactoryTests.cs +++ b/test/CacheManager.Tests/CacheFactoryTests.cs @@ -76,8 +76,9 @@ public void ConfigurationBuilder_ForConfiguration() var forCfg = new ConfigurationBuilder("newName", cfg); forCfg.WithDictionaryHandle().WithExpiration(ExpirationMode.Absolute, TimeSpan.FromHours(1)); - forCfg.WithGzJsonSerializer(); + forCfg.WithJsonSerializer().WithCompression(); + cfg.ShouldCompress.Should().BeTrue(); cfg.CacheHandleConfigurations.Count.Should().Be(2); cfg.Name.Should().Be("newName"); cfg.CacheHandleConfigurations.First().ExpirationMode.Should().Be(ExpirationMode.Sliding); diff --git a/test/CacheManager.Tests/MicrosoftConfigurationTests.cs b/test/CacheManager.Tests/MicrosoftConfigurationTests.cs index 241f37f1..a55de558 100644 --- a/test/CacheManager.Tests/MicrosoftConfigurationTests.cs +++ b/test/CacheManager.Tests/MicrosoftConfigurationTests.cs @@ -1009,7 +1009,31 @@ public void Configuration_Serializer_KnownType_GzJson() cache.Add("key", "value"); }; - config.SerializerType.Should().Be(typeof(Serialization.Json.GzJsonCacheSerializer)); + config.SerializerType.Should().Be(typeof(Serialization.Json.JsonCacheSerializer)); + config.ShouldCompress.Should().BeTrue(); + act.Should().NotThrow(); + } + + [Fact] + public void Configuration_Serializer_KnownType_JsonWithCompression() + { + var data = new Dictionary + { + {"cacheManagers:0:name", "name"}, + {"cacheManagers:0:handles:0:knownType", "Dictionary"}, + {"cacheManagers:0:serializer:knownType", "json"}, + {"cacheManagers:0:serializer:shouldCompress", "true"} + }; + + var config = GetConfiguration(data).GetCacheConfiguration("name"); + Action act = () => + { + var cache = new BaseCacheManager(config); + cache.Add("key", "value"); + }; + + config.SerializerType.Should().Be(typeof(Serialization.Json.JsonCacheSerializer)); + config.ShouldCompress.Should().BeTrue(); act.Should().NotThrow(); } diff --git a/test/CacheManager.Tests/SerializerTests.cs b/test/CacheManager.Tests/SerializerTests.cs index 6b091b20..02c4fd37 100644 --- a/test/CacheManager.Tests/SerializerTests.cs +++ b/test/CacheManager.Tests/SerializerTests.cs @@ -354,7 +354,7 @@ public void JsonSerializer_List() #region newtonsoft json with GZ serializer [Fact] - public void GzJsonSerializer_RespectJsonSerializerSettings() + public void WithGzJsonSerializer_RespectJsonSerializerSettings() { var serializationSettings = new JsonSerializerSettings() { @@ -369,12 +369,14 @@ public void GzJsonSerializer_RespectJsonSerializerSettings() }; var cache = CacheFactory.Build( + #pragma warning disable CS0618 // Type or member is obsolete p => p .WithGzJsonSerializer(serializationSettings, deserializationSettings) + #pragma warning restore CS0618 // Type or member is obsolete .WithHandle(typeof(SerializerTestCacheHandle))); var handle = cache.CacheHandles.ElementAt(0) as SerializerTestCacheHandle; - var serializer = handle.Serializer as JsonCacheSerializer; + var serializer = (handle.Serializer as CompressionSerializer).InternalSerializer as JsonCacheSerializer; serializer.SerializationSettings.DateFormatHandling.Should().Be(DateFormatHandling.MicrosoftDateFormat); serializer.SerializationSettings.FloatFormatHandling.Should().Be(FloatFormatHandling.String); @@ -391,10 +393,10 @@ public void GzJsonSerializer_RespectJsonSerializerSettings() [InlineData(long.MaxValue)] [InlineData("some string")] [ReplaceCulture] - public void GzJsonSerializer_Primitives(T value) + public void JsonSerializerWithCompression_Primitives(T value) { // arrange - var serializer = new GzJsonCacheSerializer(); + var serializer = new CompressionSerializer(new JsonCacheSerializer()); // act var data = serializer.Serialize(value); @@ -410,10 +412,10 @@ public void GzJsonSerializer_Primitives(T value) [InlineData(long.MaxValue)] [InlineData("some string")] [ReplaceCulture] - public void GzJsonSerializer_CacheItem_Primitives(T value) + public void JsonSerializerWithCompression_CacheItem_Primitives(T value) { // arrange - var serializer = new GzJsonCacheSerializer(); + var serializer = new CompressionSerializer(new JsonCacheSerializer()); var item = new CacheItem("key", value); // act @@ -437,10 +439,10 @@ public void GzJsonSerializer_CacheItem_Primitives(T value) [InlineData(long.MaxValue)] [InlineData("some string")] [ReplaceCulture] - public void GzJsonSerializer_CacheItemOfObject_Primitives(T value) + public void JsonSerializerWithCompression_CacheItemOfObject_Primitives(T value) { // arrange - var serializer = new GzJsonCacheSerializer(); + var serializer = new CompressionSerializer(new JsonCacheSerializer()); var item = new CacheItem("key", value); // act @@ -458,10 +460,10 @@ public void GzJsonSerializer_CacheItemOfObject_Primitives(T value) } [Fact] - public void GzJsonSerializer_Pocco() + public void JsonSerializerWithCompression_Pocco() { // arrange - var serializer = new GzJsonCacheSerializer(); + var serializer = new CompressionSerializer(new JsonCacheSerializer()); var item = SerializerPoccoSerializable.Create(); // act @@ -472,10 +474,10 @@ public void GzJsonSerializer_Pocco() } [Fact] - public void GzJsonSerializer_CacheItemWithPocco() + public void JsonSerializerWithCompression_CacheItemWithPocco() { // arrange - var serializer = new GzJsonCacheSerializer(); + var serializer = new CompressionSerializer(new JsonCacheSerializer()); var pocco = SerializerPoccoSerializable.Create(); var item = new CacheItem("key", "region", pocco, ExpirationMode.Absolute, TimeSpan.FromDays(1)); @@ -487,10 +489,10 @@ public void GzJsonSerializer_CacheItemWithPocco() } [Fact] - public void GzJsonSerializer_ObjectCacheItemWithPocco() + public void JsonSerializerWithCompression_ObjectCacheItemWithPocco() { // arrange - var serializer = new GzJsonCacheSerializer(); + var serializer = new CompressionSerializer(new JsonCacheSerializer()); var pocco = SerializerPoccoSerializable.Create(); var item = new CacheItem("key", "region", pocco, ExpirationMode.Absolute, TimeSpan.FromDays(1)); @@ -505,7 +507,7 @@ public void GzJsonSerializer_ObjectCacheItemWithPocco() public void GzJsonSerializer_CacheItemWithDerivedPocco() { // arrange - var serializer = new GzJsonCacheSerializer(); + var serializer = new CompressionSerializer(new JsonCacheSerializer()); var pocco = DerivedPocco.CreateDerived(); var item = new CacheItem("key", "region", pocco, ExpirationMode.Absolute, TimeSpan.FromDays(1)); @@ -518,10 +520,10 @@ public void GzJsonSerializer_CacheItemWithDerivedPocco() } [Fact] - public void GzJsonSerializer_List() + public void JsonSerializerWithCompression_List() { // arrange - var serializer = new GzJsonCacheSerializer(); + var serializer = new CompressionSerializer(new JsonCacheSerializer()); var items = new List() { SerializerPoccoSerializable.Create(), @@ -583,7 +585,7 @@ public void DataContractSerializer_Json_RespectSerializerSettings() } [Fact] - public void DataContractSerializer_GzJson_RespectSerializerSettings() + public void DataContractSerializer_WithDataContractGzJsonSerializer_RespectSerializerSettings() { var serializationSettings = new DataContractJsonSerializerSettings() { @@ -591,12 +593,14 @@ public void DataContractSerializer_GzJson_RespectSerializerSettings() }; var cache = CacheFactory.Build( + #pragma warning disable CS0618 // Type or member is obsolete p => p .WithDataContractGzJsonSerializer(serializationSettings) + #pragma warning restore CS0618 // Type or member is obsolete .WithHandle(typeof(SerializerTestCacheHandle))); var handle = cache.CacheHandles.ElementAt(0) as SerializerTestCacheHandle; - var serializer = handle.Serializer as DataContractGzJsonCacheSerializer; + var serializer = (handle.Serializer as CompressionSerializer).InternalSerializer as DataContractJsonCacheSerializer; serializer.SerializerSettings.KnownTypes.Should().BeEquivalentTo(new[] { typeof(string) }); @@ -1047,7 +1051,7 @@ public void DataContractJsonSerializer_FullAddGet() public void DataContractGzJsonSerializer_Primitives(T value) { // arrange - var serializer = new DataContractGzJsonCacheSerializer(); + var serializer = new CompressionSerializer(new DataContractJsonCacheSerializer()); // act var data = serializer.Serialize(value); @@ -1063,15 +1067,15 @@ public void DataContractGzJsonSerializer_Primitives(T value) [InlineData(long.MaxValue)] [InlineData("some string")] [ReplaceCulture] - public void DataContractGzJsonSerializer_CacheItem_Primitives(T value) + public void DataContractJsonSerializerWithCompressio_CacheItem_Primitives(T value) { // arrange - var serializer = new DataContractGzJsonCacheSerializer(new DataContractJsonSerializerSettings() + var serializer = new CompressionSerializer(new DataContractJsonCacheSerializer(new DataContractJsonSerializerSettings() { //DataContractJsonSerializer serializes DateTime values as Date(1231231313) instead of "2017-11-07T13:09:39.7079187Z". //So, I've changed the format to make the test pass. DateTimeFormat = new DateTimeFormat("O") - }); + })); var item = new CacheItem("key", value); // act @@ -1095,15 +1099,15 @@ public void DataContractGzJsonSerializer_CacheItem_Primitives(T value) [InlineData(long.MaxValue)] [InlineData("some string")] [ReplaceCulture] - public void DataContractGzJsonSerializer_CacheItemOfObject_Primitives(T value) + public void DataContractJsonSerializerWithCompressio_CacheItemOfObject_Primitives(T value) { // arrange - var serializer = new DataContractGzJsonCacheSerializer(new DataContractJsonSerializerSettings() + var serializer = new CompressionSerializer(new DataContractJsonCacheSerializer(new DataContractJsonSerializerSettings() { //DataContractJsonSerializer serializes DateTime values as Date(1231231313) instead of "2017-11-07T13:09:39.7079187Z". //So, I've changed the format to make the test pass. DateTimeFormat = new DateTimeFormat("O") - }); + })); var item = new CacheItem("key", value); // act @@ -1121,10 +1125,10 @@ public void DataContractGzJsonSerializer_CacheItemOfObject_Primitives(T value } [Fact] - public void DataContractGzJsonSerializer_Pocco() + public void DataContractJsonSerializerWithCompressio_Pocco() { // arrange - var serializer = new DataContractGzJsonCacheSerializer(); + var serializer = new CompressionSerializer(new DataContractJsonCacheSerializer()); var item = SerializerPoccoSerializable.Create(); // act @@ -1135,15 +1139,15 @@ public void DataContractGzJsonSerializer_Pocco() } [Fact] - public void DataContractGzJsonSerializer_CacheItemWithPocco() + public void DataContractJsonSerializerWithCompressio_CacheItemWithPocco() { // arrange - var serializer = new DataContractGzJsonCacheSerializer(new DataContractJsonSerializerSettings() + var serializer = new CompressionSerializer(new DataContractJsonCacheSerializer(new DataContractJsonSerializerSettings() { //DataContractJsonSerializer serializes DateTime values as Date(1231231313) instead of "2017-11-07T13:09:39.7079187Z". //So, I've changed the format to make the test pass. DateTimeFormat = new DateTimeFormat("O") - }); + })); var pocco = SerializerPoccoSerializable.Create(); var item = new CacheItem("key", "region", pocco, ExpirationMode.Absolute, TimeSpan.FromDays(1)); @@ -1155,10 +1159,10 @@ public void DataContractGzJsonSerializer_CacheItemWithPocco() } [Fact] - public void DataContractGzJsonSerializer_List() + public void DataContractJsonSerializerWithCompressio_List() { // arrange - var serializer = new DataContractGzJsonCacheSerializer(); + var serializer = new CompressionSerializer(new DataContractJsonCacheSerializer()); var items = new List() { SerializerPoccoSerializable.Create(), diff --git a/test/CacheManager.Tests/TestCacheManagers.cs b/test/CacheManager.Tests/TestCacheManagers.cs index 027f0aaf..cd003f75 100644 --- a/test/CacheManager.Tests/TestCacheManagers.cs +++ b/test/CacheManager.Tests/TestCacheManagers.cs @@ -619,7 +619,7 @@ public static ConfigurationBuilderCachePart TestSerializer(this ConfigurationBui break; case Serializer.GzJson: - part.WithGzJsonSerializer(); + part.WithJsonSerializer().WithCompression(); break; case Serializer.Json: @@ -643,7 +643,7 @@ public static ConfigurationBuilderCachePart TestSerializer(this ConfigurationBui break; case Serializer.DataContractGzJson: - part.WithDataContractGzJsonSerializer(); + part.WithDataContractSerializer().WithCompression(); break; case Serializer.DataContractJson: diff --git a/tools/CacheManagerCfg.xsd b/tools/CacheManagerCfg.xsd index b47bed4a..414b538a 100644 --- a/tools/CacheManagerCfg.xsd +++ b/tools/CacheManagerCfg.xsd @@ -29,6 +29,7 @@ + diff --git a/tools/cacheManager.json b/tools/cacheManager.json index ca8c02f4..96f6aa35 100644 --- a/tools/cacheManager.json +++ b/tools/cacheManager.json @@ -97,6 +97,10 @@ "type": "string", "enum": [ "Binary", "Json", "Protobuf", "GzJson", "BondCompactBinary", "BondFastBinary", "BondSimpleJson" ], "description": "Define a known serializer type instead of setting 'serializerType'. The respective library has to be installed. The default 'binary' might not be available on all platforms." + }, + "shouldCompress": { + "type": "boolean", + "description": "Define if data should be compress using gzip after serialization." } }, "additionalProperties": false @@ -108,6 +112,10 @@ "type": { "type": "string", "description": "The clr type of the serializer to be used by distributed cache handles." + }, + "shouldCompress": { + "type": "boolean", + "description": "Define if data should be compress using gzip after serialization." } }, "additionalProperties": false