Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ServiceFabricProviderV1] Enable customer serializer for reliable collections. #1034

Open
wants to merge 2 commits into
base: pk/vnext_servicefabric/NuPkgGeneration
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions DurableTask.ServiceFabric.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26403.7
# Visual Studio Version 16
VisualStudioVersion = 16.0.34301.259
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{501E1168-418C-4832-B88C-617735BD02C9}"
ProjectSection(SolutionItems) = preProject
Expand Down Expand Up @@ -51,6 +51,7 @@ Global
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CA924781-AE52-45FA-A817-C39C822FB782}.Debug|Any CPU.ActiveCfg = Debug|x64
{CA924781-AE52-45FA-A817-C39C822FB782}.Debug|Any CPU.Build.0 = Debug|x64
{CA924781-AE52-45FA-A817-C39C822FB782}.Debug|x64.ActiveCfg = Debug|x64
{CA924781-AE52-45FA-A817-C39C822FB782}.Debug|x64.Build.0 = Debug|x64
{CA924781-AE52-45FA-A817-C39C822FB782}.Debug|x64.Deploy.0 = Debug|x64
Expand All @@ -59,6 +60,7 @@ Global
{CA924781-AE52-45FA-A817-C39C822FB782}.Release|x64.Build.0 = Release|x64
{CA924781-AE52-45FA-A817-C39C822FB782}.Release|x64.Deploy.0 = Release|x64
{95D6C9C7-F7A0-4125-840D-1854BEC24978}.Debug|Any CPU.ActiveCfg = Debug|x64
{95D6C9C7-F7A0-4125-840D-1854BEC24978}.Debug|Any CPU.Build.0 = Debug|x64
{95D6C9C7-F7A0-4125-840D-1854BEC24978}.Debug|x64.ActiveCfg = Debug|x64
{95D6C9C7-F7A0-4125-840D-1854BEC24978}.Debug|x64.Build.0 = Debug|x64
{95D6C9C7-F7A0-4125-840D-1854BEC24978}.Release|Any CPU.ActiveCfg = Release|x64
Expand Down Expand Up @@ -170,5 +172,6 @@ Global
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EnterpriseLibraryConfigurationToolBinariesPath = packages\TransientFaultHandling.Core.5.1.1209.1\lib\NET4
SolutionGuid = {BCE9A2EE-C1D3-4F37-8500-E112D840827F}
EndGlobalSection
EndGlobal
6 changes: 3 additions & 3 deletions Test/DurableTask.ServiceFabric.Test/AssemblySetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ static string TestApplicationRootPath
{
get
{
var sourceRoot = Environment.GetEnvironmentVariable("SourceRoot") ?? string.Empty;
var applicationPath = Path.Combine(sourceRoot.Trim(), "Test", "TestFabricApplication", "TestFabricApplication");

//var sourceRoot = Environment.GetEnvironmentVariable("SourceRoot") ?? string.Empty;
//var applicationPath = Path.Combine(sourceRoot.Trim(), "Test", "TestFabricApplication", "TestFabricApplication");
var applicationPath = Path.Combine(Directory.GetCurrentDirectory(), @"..\..\..\TestFabricApplication\TestFabricApplication");
if (!Directory.Exists(applicationPath))
{
throw new Exception("Could not find test application path, define SourceRoot environment variable to the source path");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets=";ValidateMSBuildFiles">
<Import Project="..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.6.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.props" Condition="Exists('..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.6.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.props')" />
<Import Project="..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.7.6\build\Microsoft.VisualStudio.Azure.Fabric.Application.props" Condition="Exists('..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.7.6\build\Microsoft.VisualStudio.Azure.Fabric.Application.props')" />
<PropertyGroup Label="Globals">
<ProjectGuid>ca924781-ae52-45fa-a817-c39c822fb782</ProjectGuid>
<ProjectVersion>1.6</ProjectVersion>
<ProjectVersion>2.1</ProjectVersion>
<MinToolsVersion>1.5</MinToolsVersion>
<SupportedMSBuildNuGetPackageVersion>1.7.6</SupportedMSBuildNuGetPackageVersion>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
Expand Down Expand Up @@ -38,9 +39,9 @@
<ApplicationProjectTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Service Fabric Tools\Microsoft.VisualStudio.Azure.Fabric.ApplicationProject.targets</ApplicationProjectTargetsPath>
</PropertyGroup>
<Import Project="$(ApplicationProjectTargetsPath)" Condition="Exists('$(ApplicationProjectTargetsPath)')" />
<Import Project="..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.6.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.targets" Condition="Exists('..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.6.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.targets')" />
<Target Name="ValidateMSBuildFiles">
<Error Condition="!Exists('..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.6.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.props')" Text="Unable to find the '..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.6.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.props' file. Please restore the 'Microsoft.VisualStudio.Azure.Fabric.MSBuild' Nuget package" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.6.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.targets')" Text="Unable to find the '..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.6.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.targets' file. Please restore the 'Microsoft.VisualStudio.Azure.Fabric.MSBuild' Nuget package" />
<Import Project="..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.7.6\build\Microsoft.VisualStudio.Azure.Fabric.Application.targets" Condition="Exists('..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.7.6\build\Microsoft.VisualStudio.Azure.Fabric.Application.targets')" />
<Target Name="ValidateMSBuildFiles" BeforeTargets="PrepareForBuild">
<Error Condition="!Exists('..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.7.6\build\Microsoft.VisualStudio.Azure.Fabric.Application.props')" Text="Unable to find the '..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.7.6\build\Microsoft.VisualStudio.Azure.Fabric.Application.props' file. Please restore the 'Microsoft.VisualStudio.Azure.Fabric.MSBuild' Nuget package." />
<Error Condition="!Exists('..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.7.6\build\Microsoft.VisualStudio.Azure.Fabric.Application.targets')" Text="Unable to find the '..\..\..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.7.6\build\Microsoft.VisualStudio.Azure.Fabric.Application.targets' file. Please restore the 'Microsoft.VisualStudio.Azure.Fabric.MSBuild' Nuget package." />
</Target>
</Project>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.VisualStudio.Azure.Fabric.MSBuild" version="1.6.0" />
<package id="Microsoft.VisualStudio.Azure.Fabric.MSBuild" version="1.7.6" targetFramework="net40" />
</packages>
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// ----------------------------------------------------------------------------------
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------


namespace TestStatefulService
{
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
using Microsoft.ServiceFabric.Data;

internal class CustomDataContractStateSerializer<T> : IStateSerializer<T>
{
/// <summary>
/// The serializer.
/// </summary>
private readonly DataContractSerializer serializer = new DataContractSerializer(typeof(T));

/// <summary>
/// Converts byte[] to T
/// </summary>
/// <param name="binaryReader">Reader containing the serialized data.</param>
/// <returns>Deserialized version of T.</returns>
public T Read(BinaryReader binaryReader)
{
var size = binaryReader.ReadInt32();

var bytes = binaryReader.ReadBytes(size);

using (var memoryStream = new MemoryStream(bytes))
{
using (var reader = XmlDictionaryReader.CreateBinaryReader(memoryStream, XmlDictionaryReaderQuotas.Max))
using (var customReader = new CustomerXmlDictionaryReader(reader, typeof(T)))
{
return (T) this.serializer.ReadObject(customReader);
}
}
}

/// <summary>
/// Converts IEnumerable of byte[] to T
/// </summary>
/// <param name="baseValue"></param>
/// <param name="reader">Reader containing the serialized data.</param>
/// <returns>Deserialized version of T.</returns>
public T Read(T baseValue, BinaryReader reader)
{
return this.Read(reader);
}

/// <summary>
/// Converts T to byte array.
/// </summary>
/// <param name="value">T to be serialized.</param>
/// <param name="binaryWriter"></param>
/// <returns>Serialized version of T.</returns>
public void Write(T value, BinaryWriter binaryWriter)
{
using (var memoryStream = new MemoryStream())
{
using (var innerWriter = new BinaryWriter(memoryStream))
{
innerWriter.Write(int.MinValue);

using (
var binaryDictionaryWriter = XmlDictionaryWriter.CreateBinaryWriter(
memoryStream,
null,
null,
false))
{
this.serializer.WriteObject(binaryDictionaryWriter, value);
binaryDictionaryWriter.Flush();
}

var lastPosition = (int) memoryStream.Position;

memoryStream.Position = 0;

innerWriter.Write(lastPosition - sizeof(int));

memoryStream.Position = lastPosition;

binaryWriter.Write(memoryStream.GetBuffer(), 0, lastPosition);
}
}
}

/// <summary>
/// Converts T to byte array.
/// </summary>
/// <param name="newValue"></param>
/// <param name="binaryWriter">Writer to which the serialized data should be written.</param>
/// <param name="currentValue"></param>
/// <returns>Serialized version of T.</returns>
public void Write(T currentValue, T newValue, BinaryWriter binaryWriter)
{
this.Write(newValue, binaryWriter);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// ----------------------------------------------------------------------------------
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------


using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;

namespace TestStatefulService
{
internal class CustomerXmlDictionaryReader : XmlDictionaryReader
{
XmlDictionaryReader innerReader;
Type targetType;
bool isTargetV2;

static IDictionary<string, string> namespaceMapV1toV2 = new Dictionary<string, string>
{
{ "DurableTask.ServiceFabric", "DurableTask.AzureServiceFabric" },
{ "DurableTask", "DurableTask.Core" },
{ "DurableTask.History", "DurableTask.Core.History" }
};

static IDictionary<string, string> namespaceMapV2toV1 = new Dictionary<string, string>
{
{ "DurableTask.AzureServiceFabric", "DurableTask.ServiceFabric" },
{ "DurableTask.Core", "DurableTask" },
{ "DurableTask.Core.History", "DurableTask.History" }
};

public CustomerXmlDictionaryReader(XmlDictionaryReader innerReader, Type type)
{
this.innerReader = innerReader;
this.targetType = type;

this.isTargetV2 = this.targetType.Namespace == "DurableTask.AzureServiceFabric" ? true : false;
}

public override int AttributeCount => this.innerReader.AttributeCount;

public override string BaseURI => this.innerReader.BaseURI;

public override int Depth => this.innerReader.Depth;

public override bool EOF => this.innerReader.EOF;

public override bool IsEmptyElement => this.innerReader.IsEmptyElement;

public override string LocalName => this.innerReader.LocalName;

public override string NamespaceURI
{
get
{
// Alter the old namespace
UriBuilder builder = new UriBuilder(innerReader.NamespaceURI);

var segments = builder.Uri.Segments;
var mapToUse = namespaceMapV2toV1;
string last = segments.LastOrDefault();
if (isTargetV2)
{
mapToUse = namespaceMapV1toV2;
}

if (mapToUse.ContainsKey(last))
{
segments[segments.Length - 1] = mapToUse[last];
builder.Path = String.Join("", segments);
//File.AppendAllText(@"D:\git\durabletask\main\Test\TestFabricApplication\TestFabricApplication\SerializationInfo2.txt", $"OLD: {innerReader.NamespaceURI} NEW: {builder.Uri} {this.isTargetV2} {Environment.NewLine}");
return builder.Uri.ToString();
}

return innerReader.NamespaceURI;
}
}

public override XmlNameTable NameTable => this.innerReader.NameTable;

public override XmlNodeType NodeType => this.innerReader.NodeType;

public override string Prefix => this.innerReader.Prefix;

public override ReadState ReadState => this.innerReader.ReadState;

public override string Value => this.innerReader.Value;

public override string GetAttribute(int i)
{
return this.innerReader.GetAttribute(i);
}

public override string GetAttribute(string name)
{
return this.innerReader.GetAttribute(name);
}

public override string GetAttribute(string name, string namespaceURI)
{
return this.innerReader.GetAttribute(name, namespaceURI);
}

public override string LookupNamespace(string prefix)
{
return this.innerReader.LookupNamespace(prefix);
}

public override bool MoveToAttribute(string name)
{
return this.innerReader.MoveToAttribute(name);
}

public override bool MoveToAttribute(string name, string ns)
{
return this.innerReader.MoveToAttribute(name, ns);
}

public override bool MoveToElement()
{
return this.innerReader.MoveToElement();
}

public override bool MoveToFirstAttribute()
{
return this.innerReader.MoveToFirstAttribute();
}

public override bool MoveToNextAttribute()
{
return this.innerReader.MoveToNextAttribute();
}

public override bool Read()
{
return this.innerReader.Read();
}

public override bool ReadAttributeValue()
{
return this.innerReader.ReadAttributeValue();
}

public override void ResolveEntity()
{
this.innerReader.ResolveEntity();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using System.Threading;
using System.Threading.Tasks;
using DurableTask;
using DurableTask.History;
using DurableTask.ServiceFabric;
using DurableTask.Test.Orchestrations.Perf;
using Microsoft.ServiceFabric.Services.Communication.Runtime;
Expand Down Expand Up @@ -49,6 +50,8 @@ public TestStatefulService(StatefulServiceContext context) : base(context)
this.fabricProviderFactory = new FabricOrchestrationProviderFactory(this.StateManager, settings);
this.fabricProvider = this.fabricProviderFactory.CreateProvider();
this.client = new TaskHubClient(fabricProvider.OrchestrationServiceClient);

this.StateManager.TryAddStateSerializer(new CustomDataContractStateSerializer<TaskMessageItem>());
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<IsServiceFabricServiceProject>True</IsServiceFabricServiceProject>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<DebugSymbols>true</DebugSymbols>
Expand Down Expand Up @@ -113,8 +114,11 @@
<HintPath>..\..\..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.XML" />
</ItemGroup>
<ItemGroup>
<Compile Include="CustomDataContractStateSerializer.cs" />
<Compile Include="CustomerXmlDictionaryReader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Startup.cs" />
<Compile Include="TestOrchestrations\CounterException.cs" />
Expand Down
Loading