Beispiel #1
0
        public void GivenACacheModel_WhenItsSerializedAndDeserializedWithAnySerializer_TheResultsAreTheSame()
        {
            var jsonSerializer    = new JsonContentNestedDataSerializer();
            var msgPackSerializer = new MsgPackContentNestedDataSerializer(Mock.Of <IPropertyCacheCompression>());

            var now        = DateTime.Now;
            var cacheModel = new ContentCacheDataModel
            {
                PropertyData = new Dictionary <string, PropertyData[]>
                {
                    ["propertyOne"] = new[]
                    {
                        new PropertyData
                        {
                            Culture = "en-US",
                            Segment = "test",
                            Value   = "hello world"
                        }
                    },
                    ["propertyTwo"] = new[]
                    {
                        new PropertyData
                        {
                            Culture = "en-US",
                            Segment = "test",
                            Value   = "Lorem ipsum"
                        }
                    }
                },
                CultureData = new Dictionary <string, CultureVariation>
                {
                    ["en-US"] = new CultureVariation
                    {
                        Date       = now,
                        IsDraft    = false,
                        Name       = "Home",
                        UrlSegment = "home"
                    }
                },
                UrlSegment = "home"
            };

            var content = Mock.Of <IReadOnlyContentBase>(x => x.ContentTypeId == 1);

            var json    = jsonSerializer.Serialize(content, cacheModel, false).StringData;
            var msgPack = msgPackSerializer.Serialize(content, cacheModel, false).ByteData;

            Console.WriteLine(json);
            Console.WriteLine(msgPackSerializer.ToJson(msgPack));

            var jsonContent    = jsonSerializer.Deserialize(content, json, null, false);
            var msgPackContent = msgPackSerializer.Deserialize(content, null, msgPack, false);


            CollectionAssert.AreEqual(jsonContent.CultureData.Keys, msgPackContent.CultureData.Keys);
            CollectionAssert.AreEqual(jsonContent.PropertyData.Keys, msgPackContent.PropertyData.Keys);
            CollectionAssert.AreEqual(jsonContent.CultureData.Values, msgPackContent.CultureData.Values, new CultureVariationComparer());
            CollectionAssert.AreEqual(jsonContent.PropertyData.Values, msgPackContent.PropertyData.Values, new PropertyDataComparer());
            Assert.AreEqual(jsonContent.UrlSegment, msgPackContent.UrlSegment);
        }
Beispiel #2
0
    /// <summary>
    ///     Used during serialization to compress properties
    /// </summary>
    /// <param name="content"></param>
    /// <param name="model"></param>
    /// <param name="published"></param>
    /// <remarks>
    ///     This will essentially 'double compress' property data. The MsgPack data as a whole will already be compressed
    ///     but this will go a step further and double compress property data so that it is stored in the nucache file
    ///     as compressed bytes and therefore will exist in memory as compressed bytes. That is, until the bytes are
    ///     read/decompressed as a string to be displayed on the front-end. This allows for potentially a significant
    ///     memory savings but could also affect performance of first rendering pages while decompression occurs.
    /// </remarks>
    private void Compress(IReadOnlyContentBase content, ContentCacheDataModel model, bool published)
    {
        if (model.PropertyData is null)
        {
            return;
        }

        foreach (KeyValuePair <string, PropertyData[]> propertyAliasToData in model.PropertyData)
        {
            if (_propertyOptions.IsCompressed(content, propertyAliasToData.Key, published))
            {
                foreach (PropertyData property in propertyAliasToData.Value.Where(x =>
                                                                                  x.Value != null && x.Value is string))
                {
                    if (property.Value is string propertyValue)
                    {
                        property.Value = LZ4Pickler.Pickle(Encoding.UTF8.GetBytes(propertyValue));
                    }
                }

                foreach (PropertyData property in propertyAliasToData.Value.Where(x =>
                                                                                  x.Value != null && x.Value is int intVal))
                {
                    property.Value = Convert.ToBoolean((int?)property.Value);
                }
            }
        }
    }
Beispiel #3
0
    /// <summary>
    ///     Used during deserialization to map the property data as lazy or expand the value
    /// </summary>
    /// <param name="content"></param>
    /// <param name="nestedData"></param>
    /// <param name="published"></param>
    private void Expand(IReadOnlyContentBase content, ContentCacheDataModel nestedData, bool published)
    {
        if (nestedData.PropertyData is null)
        {
            return;
        }

        foreach (KeyValuePair <string, PropertyData[]> propertyAliasToData in nestedData.PropertyData)
        {
            if (_propertyOptions.IsCompressed(content, propertyAliasToData.Key, published))
            {
                foreach (PropertyData property in propertyAliasToData.Value.Where(x => x.Value != null))
                {
                    if (property.Value is byte[] byteArrayValue)
                    {
                        property.Value = new LazyCompressedString(byteArrayValue);
                    }
                }
            }
        }
    }
Beispiel #4
0
        private ContentNuDto GetDto(IContentBase content, bool published, IContentCacheDataSerializer serializer)
        {
            // should inject these in ctor
            // BUT for the time being we decide not to support ConvertDbToXml/String
            // var propertyEditorResolver = PropertyEditorResolver.Current;
            // var dataTypeService = ApplicationContext.Current.Services.DataTypeService;
            var propertyData = new Dictionary <string, PropertyData[]>();

            foreach (IProperty prop in content.Properties)
            {
                var pdatas = new List <PropertyData>();
                foreach (IPropertyValue pvalue in prop.Values)
                {
                    // sanitize - properties should be ok but ... never knows
                    if (!prop.PropertyType.SupportsVariation(pvalue.Culture, pvalue.Segment))
                    {
                        continue;
                    }

                    // note: at service level, invariant is 'null', but here invariant becomes 'string.Empty'
                    var value = published ? pvalue.PublishedValue : pvalue.EditedValue;
                    if (value != null)
                    {
                        pdatas.Add(new PropertyData {
                            Culture = pvalue.Culture ?? string.Empty, Segment = pvalue.Segment ?? string.Empty, Value = value
                        });
                    }
                }

                propertyData[prop.Alias] = pdatas.ToArray();
            }

            var cultureData = new Dictionary <string, CultureVariation>();

            // sanitize - names should be ok but ... never knows
            if (content.ContentType.VariesByCulture())
            {
                ContentCultureInfosCollection infos = content is IContent document
                    ? published
                        ? document.PublishCultureInfos
                        : document.CultureInfos
                    : content.CultureInfos;

                // ReSharper disable once UseDeconstruction
                foreach (ContentCultureInfos cultureInfo in infos)
                {
                    var cultureIsDraft = !published && content is IContent d && d.IsCultureEdited(cultureInfo.Culture);
                    cultureData[cultureInfo.Culture] = new CultureVariation
                    {
                        Name       = cultureInfo.Name,
                        UrlSegment = content.GetUrlSegment(_shortStringHelper, _urlSegmentProviders, cultureInfo.Culture),
                        Date       = content.GetUpdateDate(cultureInfo.Culture) ?? DateTime.MinValue,
                        IsDraft    = cultureIsDraft
                    };
                }
            }

            // the dictionary that will be serialized
            var contentCacheData = new ContentCacheDataModel
            {
                PropertyData = propertyData,
                CultureData  = cultureData,
                UrlSegment   = content.GetUrlSegment(_shortStringHelper, _urlSegmentProviders)
            };

            var serialized = serializer.Serialize(ReadOnlyContentBaseAdapter.Create(content), contentCacheData, published);

            var dto = new ContentNuDto
            {
                NodeId    = content.Id,
                Published = published,
                Data      = serialized.StringData,
                RawData   = serialized.ByteData
            };

            return(dto);
        }
Beispiel #5
0
    public ContentCacheDataSerializationResult Serialize(IReadOnlyContentBase content, ContentCacheDataModel model, bool published)
    {
        Compress(content, model, published);
        var bytes = MessagePackSerializer.Serialize(model, _options);

        return(new ContentCacheDataSerializationResult(null, bytes));
    }