diff --git a/AppmetrS2S.Tests/AppMetrJsonSerializationTests.cs b/AppmetrS2S.Tests/AppMetrJsonSerializationTests.cs index 54fae60..3030cd7 100644 --- a/AppmetrS2S.Tests/AppMetrJsonSerializationTests.cs +++ b/AppmetrS2S.Tests/AppMetrJsonSerializationTests.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using AppmetrS2S.Actions; using AppmetrS2S.Persister; using AppmetrS2S.Serializations; @@ -17,25 +16,11 @@ public AppMetrJsonSerializationTests(ITestOutputHelper output) { _output = output; } - - [Fact] - public void SerializersShouldReturnsEqualsValues() - { - var batch = CreateBatch(50000); - - var defaultSerializer = new JavaScriptJsonSerializer(); - var cacheSerializer = new JavaScriptJsonSerializerWithCache(); - - var defaultJson = defaultSerializer.Serialize(batch); - var newtonsoftJson = cacheSerializer.Serialize(batch); - - Assert.Equal(defaultJson, newtonsoftJson); - } - + [Fact] public void SerializeServerInstall() { - var defaultSerializer = new JavaScriptJsonSerializer(); + var defaultSerializer = new BasicJsonSerializer(); var install = Events.ServerInstall("test").SetProperties(new Dictionary { {"key", "value"} @@ -52,36 +37,6 @@ public void SerializeServerInstall() Assert.Equal("value", receivedAction.GetProperties()["key"]); } - [Fact] - public void SerializersBench() - { - var batch = CreateBatch(10000); - - var defaultSerializer = new JavaScriptJsonSerializer(); - var cacheSerializer = new JavaScriptJsonSerializerWithCache(); - - defaultSerializer.Serialize(batch); - cacheSerializer.Serialize(batch); - - const int iterationsCount = 100; - - var cacheTime = Stopwatch.StartNew(); - for (var i = 0; i < iterationsCount; i++) - { - cacheSerializer.Serialize(batch); - } - cacheTime.Stop(); - - var defaultTime = Stopwatch.StartNew(); - for (var i = 0; i < iterationsCount; i++) - { - defaultSerializer.Serialize(batch); - } - defaultTime.Stop(); - - _output.WriteLine("Default: " + defaultTime.Elapsed); - _output.WriteLine("Newtonsoft: " + cacheTime.Elapsed); - } [Fact] public void SerializePayment() @@ -92,7 +47,7 @@ public void SerializePayment() }; var batch = new Batch(Guid.NewGuid().ToString(), 1, events); - var defaultSerializer = new JavaScriptJsonSerializer(); + var defaultSerializer = new BasicJsonSerializer(); var json = defaultSerializer.Serialize(batch); @@ -109,7 +64,7 @@ public void SerializeUserTime() var events = new List { e }; var batch = new Batch(Guid.NewGuid().ToString(), 1, events); - var defaultSerializer = new JavaScriptJsonSerializer(); + var defaultSerializer = new BasicJsonSerializer(); var json = defaultSerializer.Serialize(batch); @@ -122,7 +77,7 @@ public void SerializeUserTime_not_specified() var events = new List { new Event("test") }; var batch = new Batch(Guid.NewGuid().ToString(), 1, events); - var defaultSerializer = new JavaScriptJsonSerializer(); + var defaultSerializer = new BasicJsonSerializer(); var json = defaultSerializer.Serialize(batch); @@ -132,7 +87,7 @@ public void SerializeUserTime_not_specified() [Fact] public void SerializeAttachEntityAttributes() { - var defaultSerializer = new JavaScriptJsonSerializer(); + var defaultSerializer = new BasicJsonSerializer(); var attach = new AttachEntityAttributes("$serverUserId", "testId"); var events = new List { attach }; var batch = new Batch(Guid.NewGuid().ToString(), 1, events); diff --git a/AppmetrS2S.Tests/AppmetrS2S.Tests.csproj b/AppmetrS2S.Tests/AppmetrS2S.Tests.csproj index 3bee90f..80ffe4b 100644 --- a/AppmetrS2S.Tests/AppmetrS2S.Tests.csproj +++ b/AppmetrS2S.Tests/AppmetrS2S.Tests.csproj @@ -11,12 +11,13 @@ Properties AppmetrS2S.Tests AppmetrS2S.Tests - v4.5 + v4.6.1 512 ..\ true + true @@ -36,9 +37,8 @@ 4 - - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - True + + ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll diff --git a/AppmetrS2S.Tests/packages.config b/AppmetrS2S.Tests/packages.config index 0c6e5a5..d58cd35 100644 --- a/AppmetrS2S.Tests/packages.config +++ b/AppmetrS2S.Tests/packages.config @@ -1,6 +1,6 @@  - + diff --git a/AppmetrS2S/Actions/AddToPropertiesValue.cs b/AppmetrS2S/Actions/AddToPropertiesValue.cs index d2e6a11..c706a55 100644 --- a/AppmetrS2S/Actions/AddToPropertiesValue.cs +++ b/AppmetrS2S/Actions/AddToPropertiesValue.cs @@ -1,16 +1,8 @@ namespace AppmetrS2S.Actions { - #region using directives - - using System; - using System.Runtime.Serialization; - - #endregion - - [DataContract] public class AddToPropertiesValue : AppMetrAction { - public const String ACTION = "addToPropertiesValue"; + public const string ACTION = "addToPropertiesValue"; public AddToPropertiesValue() : base(ACTION) { diff --git a/AppmetrS2S/Actions/AppMetrAction.cs b/AppmetrS2S/Actions/AppMetrAction.cs index e1ce12b..789a9d1 100644 --- a/AppmetrS2S/Actions/AppMetrAction.cs +++ b/AppmetrS2S/Actions/AppMetrAction.cs @@ -1,30 +1,30 @@ -namespace AppmetrS2S.Actions +using Newtonsoft.Json; + +namespace AppmetrS2S.Actions { #region using directives using System; using System.Collections.Generic; - using System.Runtime.Serialization; #endregion - [DataContract] public abstract class AppMetrAction { - [DataMember(Name = "action")] - private String _action; + [JsonProperty("action")] + private string _action; - [DataMember(Name = "timestamp")] + [JsonProperty("timestamp")] private long _timestamp = Utils.GetNowUnixTimestamp(); - [DataMember(Name = "userTime")] + [JsonProperty("userTime")] private long? _userTime; - [DataMember(Name = "properties")] - private IDictionary _properties = new Dictionary(); + [JsonProperty("properties")] + private IDictionary _properties = new Dictionary(); - [DataMember(Name = "userId")] - private String _userId; + [JsonProperty("userId")] + private string _userId; protected AppMetrAction() { @@ -46,23 +46,23 @@ public AppMetrAction SetTimestamp(long timestamp) return this; } - public IDictionary GetProperties() + public IDictionary GetProperties() { return _properties; } - public AppMetrAction SetProperties(IDictionary properties) + public AppMetrAction SetProperties(IDictionary properties) { _properties = properties; return this; } - public String GetUserId() + public string GetUserId() { return _userId; } - public AppMetrAction SetUserId(String userId) + public AppMetrAction SetUserId(string userId) { _userId = userId; return this; @@ -71,13 +71,13 @@ public AppMetrAction SetUserId(String userId) //http://codeblog.jonskeet.uk/2011/04/05/of-memory-and-strings/ public virtual int CalcApproximateSize() { - int size = 40 + (40 * _properties.Count); //40 - Map size and 40 - each entry overhead + var size = 40 + (40 * _properties.Count); //40 - Map size and 40 - each entry overhead size += GetStringLength(_action); size += GetStringLength(Convert.ToString(_timestamp)); size += GetStringLength(_userId); - foreach (KeyValuePair pair in _properties) { + foreach (var pair in _properties) { size += GetStringLength(pair.Key); size += GetStringLength(pair.Value != null ? Convert.ToString(pair.Value) : null); //toString because sending this object via json } @@ -85,9 +85,9 @@ public virtual int CalcApproximateSize() return 8 + size + 8; //8 - object header } - protected int GetStringLength(String str) + protected int GetStringLength(string str) { - return str == null ? 0 : str.Length * 2 + 26; //24 - String object size, 16 - char[] + return str?.Length * 2 + 26 ?? 0; //24 - String object size, 16 - char[] } } } \ No newline at end of file diff --git a/AppmetrS2S/Actions/AttachEntityAttributes.cs b/AppmetrS2S/Actions/AttachEntityAttributes.cs index b2a6458..bdf7139 100644 --- a/AppmetrS2S/Actions/AttachEntityAttributes.cs +++ b/AppmetrS2S/Actions/AttachEntityAttributes.cs @@ -1,4 +1,6 @@ -namespace AppmetrS2S.Actions +using Newtonsoft.Json; + +namespace AppmetrS2S.Actions { #region using directives @@ -7,33 +9,32 @@ #endregion - [DataContract] public class AttachEntityAttributes : AppMetrAction { - public const String ACTION = "attachEntityAttributes"; + public const string ACTION = "attachEntityAttributes"; - [DataMember(Name = "entityName")] - private String _entityName; + [JsonProperty("entityName")] + private string _entityName; - [DataMember(Name = "entityValue")] - private String _entityValue; + [JsonProperty("entityValue")] + private string _entityValue; protected AttachEntityAttributes() { } - public AttachEntityAttributes(String entityName, String entityValue) : base(ACTION) + public AttachEntityAttributes(string entityName, string entityValue) : base(ACTION) { _entityName = entityName; _entityValue = entityValue; } - public String GetEntityName() + public string GetEntityName() { return _entityName; } - public String GetEntityValue() + public string GetEntityValue() { return _entityValue; } diff --git a/AppmetrS2S/Actions/AttachProperties.cs b/AppmetrS2S/Actions/AttachProperties.cs index 0526d6d..1134cfb 100644 --- a/AppmetrS2S/Actions/AttachProperties.cs +++ b/AppmetrS2S/Actions/AttachProperties.cs @@ -1,16 +1,8 @@ namespace AppmetrS2S.Actions { - #region using directives - - using System; - using System.Runtime.Serialization; - - #endregion - - [DataContract] public class AttachProperties : AppMetrAction { - public const String ACTION = "attachProperties"; + public const string ACTION = "attachProperties"; public AttachProperties() : base(ACTION) { diff --git a/AppmetrS2S/Actions/Event.cs b/AppmetrS2S/Actions/Event.cs index b409b18..ce6610b 100644 --- a/AppmetrS2S/Actions/Event.cs +++ b/AppmetrS2S/Actions/Event.cs @@ -1,19 +1,14 @@ -namespace AppmetrS2S.Actions -{ - #region using directives - - using System; - using System.Runtime.Serialization; +using Newtonsoft.Json; - #endregion - - [DataContract] +namespace AppmetrS2S.Actions +{ + public class Event : AppMetrAction { - public const String ACTION = "trackEvent"; + public const string ACTION = "trackEvent"; - [DataMember(Name = "event")] - private String _event; + [JsonProperty("event")] + private string _event; protected Event() { @@ -24,7 +19,7 @@ public Event(string eventName) : base(ACTION) _event = eventName; } - public String GetEvent() + public string GetEvent() { return _event; } diff --git a/AppmetrS2S/Actions/Events.cs b/AppmetrS2S/Actions/Events.cs index fcc6e1a..a5175c7 100644 --- a/AppmetrS2S/Actions/Events.cs +++ b/AppmetrS2S/Actions/Events.cs @@ -1,15 +1,10 @@ namespace AppmetrS2S.Actions { - #region using directives - - using System; - - #endregion - public static class Events + public static class Events { - public static Event ServerInstall(String userId) + public static Event ServerInstall(string userId) { - Event _event = new Event("server/server_install"); + var _event = new Event("server/server_install"); _event.SetUserId(userId); return _event; } diff --git a/AppmetrS2S/Actions/Payment.cs b/AppmetrS2S/Actions/Payment.cs index 210ec32..2b29624 100644 --- a/AppmetrS2S/Actions/Payment.cs +++ b/AppmetrS2S/Actions/Payment.cs @@ -1,48 +1,42 @@ -namespace AppmetrS2S.Actions -{ - #region using directives - - using System; - using System.Runtime.Serialization; +using Newtonsoft.Json; - #endregion - - [DataContract] +namespace AppmetrS2S.Actions +{ public class Payment : AppMetrAction { - public const String ACTION = "trackPayment"; + public const string ACTION = "trackPayment"; - [DataMember(Name = "orderId")] - private String _orderId; + [JsonProperty("orderId")] + private string _orderId; - [DataMember(Name = "transactionId")] - private String _transactionId; + [JsonProperty("transactionId")] + private string _transactionId; - [DataMember(Name = "processor")] - private String _processor; + [JsonProperty("processor")] + private string _processor; - [DataMember(Name = "psUserSpentCurrencyCode")] - private String _psUserSpentCurrencyCode; + [JsonProperty("psUserSpentCurrencyCode")] + private string _psUserSpentCurrencyCode; - [DataMember(Name = "psUserSpentCurrencyAmount")] - private String _psUserSpentCurrencyAmount; + [JsonProperty("psUserSpentCurrencyAmount")] + private string _psUserSpentCurrencyAmount; - [DataMember(Name = "psReceivedCurrencyCode")] - public String _psReceivedCurrencyCode; + [JsonProperty("psReceivedCurrencyCode")] + public string _psReceivedCurrencyCode; - [DataMember(Name = "psReceivedCurrencyAmount")] - public String _psReceivedCurrencyAmount; + [JsonProperty("psReceivedCurrencyAmount")] + public string _psReceivedCurrencyAmount; - [DataMember(Name = "appCurrencyCode")] - private String _appCurrencyCode; + [JsonProperty("appCurrencyCode")] + private string _appCurrencyCode; - [DataMember(Name = "appCurrencyAmount")] - private String _appCurrencyAmount; + [JsonProperty("appCurrencyAmount")] + private string _appCurrencyAmount; - [DataMember(Name = "psUserStoreCountryCode")] - public String _psUserStoreCountryCode; + [JsonProperty("psUserStoreCountryCode")] + public string _psUserStoreCountryCode; - [DataMember(Name = "isSandbox")] + [JsonProperty("isSandbox")] public bool? _isSandbox; protected Payment() : base(ACTION) @@ -50,16 +44,16 @@ protected Payment() : base(ACTION) } public Payment( - String orderId, - String transactionId, - String processor, - String psUserSpentCurrencyCode, - String psUserSpentCurrencyAmount, - String psReceivedCurrencyCode = null, - String psReceivedCurrencyAmount = null, - String appCurrencyCode = null, - String appCurrencyAmount = null, - String psUserStoreCountryCode = null, + string orderId, + string transactionId, + string processor, + string psUserSpentCurrencyCode, + string psUserSpentCurrencyAmount, + string psReceivedCurrencyCode = null, + string psReceivedCurrencyAmount = null, + string appCurrencyCode = null, + string appCurrencyAmount = null, + string psUserStoreCountryCode = null, bool? isSandbox = null ) : this() { @@ -76,52 +70,52 @@ public Payment( _isSandbox = isSandbox; } - public String GetOrderId() + public string GetOrderId() { return _orderId; } - public String GetTransactionId() + public string GetTransactionId() { return _transactionId; } - public String GetProcessor() + public string GetProcessor() { return _processor; } - public String GetPsUserSpentCurrencyCode() + public string GetPsUserSpentCurrencyCode() { return _psUserSpentCurrencyCode; } - public String GetPsUserSpentCurrencyAmount() + public string GetPsUserSpentCurrencyAmount() { return _psUserSpentCurrencyAmount; } - public String GetPsReceivedCurrencyCode() + public string GetPsReceivedCurrencyCode() { return _psReceivedCurrencyCode; } - public String GetPsReceivedCurrencyAmount() + public string GetPsReceivedCurrencyAmount() { return _psReceivedCurrencyAmount; } - public String GetAppCurrencyCode() + public string GetAppCurrencyCode() { return _appCurrencyCode; } - public String GetAppCurrencyAmount() + public string GetAppCurrencyAmount() { return _appCurrencyAmount; } - public String GetPsUserStoreCountryCode() + public string GetPsUserStoreCountryCode() { return _psUserStoreCountryCode; } diff --git a/AppmetrS2S/Actions/TrackSession.cs b/AppmetrS2S/Actions/TrackSession.cs index 745e4c7..533b4e2 100644 --- a/AppmetrS2S/Actions/TrackSession.cs +++ b/AppmetrS2S/Actions/TrackSession.cs @@ -1,16 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; - + namespace AppmetrS2S.Actions { - [DataContract] - public class TrackSession : AppMetrAction + public class TrackSession : AppMetrAction { - public const String ACTION = "trackSession"; + public const string ACTION = "trackSession"; public TrackSession() : base(ACTION) { diff --git a/AppmetrS2S/AppMetr.cs b/AppmetrS2S/AppMetr.cs index b1cdd94..0d89199 100644 --- a/AppmetrS2S/AppMetr.cs +++ b/AppmetrS2S/AppMetr.cs @@ -1,4 +1,5 @@ using AppmetrS2S.Serializations; +using Common.Logging; namespace AppmetrS2S { @@ -8,14 +9,13 @@ namespace AppmetrS2S using System.Collections.Generic; using System.Threading; using Actions; - using log4net; using Persister; #endregion public class AppMetr { - private static readonly ILog _log = LogUtils.GetLogger(typeof (AppMetr)); + private static readonly ILog _log = LogManager.GetLogger(); private readonly string _token; private readonly string _url; @@ -49,7 +49,7 @@ public AppMetr( _token = token; _url = url; _batchPersister = batchPersister ?? new MemoryBatchPersister(); - _httpRequestService = new HttpRequestService(serializer ?? new JavaScriptJsonSerializer()); + _httpRequestService = new HttpRequestService(serializer ?? new BasicJsonSerializer()); _batchPersister.SetServerId(Guid.NewGuid().ToString()); diff --git a/AppmetrS2S/AppMetrTimer.cs b/AppmetrS2S/AppMetrTimer.cs index 60d63cc..b75413f 100644 --- a/AppmetrS2S/AppMetrTimer.cs +++ b/AppmetrS2S/AppMetrTimer.cs @@ -1,16 +1,17 @@ -namespace AppmetrS2S +using Common.Logging; + +namespace AppmetrS2S { #region using directives using System; using System.Threading; - using log4net; #endregion public class AppMetrTimer { - private static readonly ILog _log = LogUtils.GetLogger(typeof (AppMetrTimer)); + private static readonly ILog _log = LogManager.GetLogger(); private readonly int _period; private readonly Action _onTimer; diff --git a/AppmetrS2S/AppmetrS2S.csproj b/AppmetrS2S/AppmetrS2S.csproj index 0852aea..c713f2d 100644 --- a/AppmetrS2S/AppmetrS2S.csproj +++ b/AppmetrS2S/AppmetrS2S.csproj @@ -1,93 +1,13 @@ - - - - - Debug - AnyCPU - {4DB6FBE6-3852-4F8C-8327-8C5A835AAD5D} - Library - Properties - AppmetrS2S - AppmetrS2S - v4.5 - 512 - ..\ - true - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - + + + + netstandard2.0;net461 + + - - ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - + \ No newline at end of file diff --git a/AppmetrS2S/HttpRequestService.cs b/AppmetrS2S/HttpRequestService.cs index 6ebb33b..5040178 100644 --- a/AppmetrS2S/HttpRequestService.cs +++ b/AppmetrS2S/HttpRequestService.cs @@ -1,26 +1,21 @@ using System.IO; using AppmetrS2S.Serializations; +using Common.Logging; +using System; +using System.Collections.Generic; +using System.IO.Compression; +using System.Net; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Json; +using System.Text; + namespace AppmetrS2S { - #region using directives - - using System; - using System.Collections.Generic; - using System.IO.Compression; - using System.Net; - using System.Runtime.Serialization; - using System.Runtime.Serialization.Json; - using System.Text; - using System.Web; - using log4net; - using Persister; - - #endregion - + using Persister; internal class HttpRequestService { - private static readonly ILog Log = LogUtils.GetLogger(typeof (HttpRequestService)); + private static readonly ILog Log = LogManager.GetLogger(); private static readonly int READ_WRITE_TIMEOUT = 10 * 60 * 1000; private static readonly int WHOLE_RQUEST_TIMEOUT = 12 * 60 * 1000; @@ -28,7 +23,7 @@ internal class HttpRequestService private const string ServerMethodName = "server.trackS2S"; private readonly IJsonSerializer _serializer; - public HttpRequestService() : this(new JavaScriptJsonSerializer()) + public HttpRequestService() : this(new BasicJsonSerializer()) { } @@ -116,7 +111,7 @@ private static String MakeQueryString(Dictionary @params) queryBuilder.Append("&"); } - queryBuilder.Append(param.Key).Append("=").Append(HttpUtility.UrlEncode(param.Value, Encoding.UTF8)); + queryBuilder.Append(param.Key).Append("=").Append(Utils.UrlEncode(param.Value, Encoding.UTF8)); } } return queryBuilder.ToString(); diff --git a/AppmetrS2S/LogUtils.cs b/AppmetrS2S/LogUtils.cs index 5ba0f03..7758179 100644 --- a/AppmetrS2S/LogUtils.cs +++ b/AppmetrS2S/LogUtils.cs @@ -1,5 +1,5 @@ using System; -using log4net; +using Common.Logging; namespace AppmetrS2S { diff --git a/AppmetrS2S/Persister/Batch.cs b/AppmetrS2S/Persister/Batch.cs index 0c27940..69e3762 100644 --- a/AppmetrS2S/Persister/Batch.cs +++ b/AppmetrS2S/Persister/Batch.cs @@ -1,4 +1,6 @@ -namespace AppmetrS2S.Persister +using Newtonsoft.Json; + +namespace AppmetrS2S.Persister { #region using directives @@ -9,35 +11,30 @@ #endregion - [DataContract] - [KnownType(typeof(AttachProperties))] - [KnownType(typeof(Event))] - [KnownType(typeof(Payment))] - [KnownType(typeof(TrackSession))] public class Batch { - [DataMember(Name = "batchId")] - private readonly Int64 _batchId; + [JsonProperty("batchId")] + private readonly long _batchId; - [DataMember(Name = "batch")] + [JsonProperty("batch")] private readonly List _batch; - [DataMember(Name = "serverId")] - private readonly String _serverId; + [JsonProperty("serverId")] + private readonly string _serverId; private Batch() { } - public Batch(String serverId, Int64 batchId, IEnumerable actionList) + public Batch(string serverId, long batchId, IEnumerable batch) { _serverId = serverId; _batchId = batchId; - _batch = new List(actionList); + _batch = new List(batch); } - public Int64 GetBatchId() + public long GetBatchId() { return _batchId; } @@ -47,9 +44,9 @@ public List GetBatch() return _batch; } - public override String ToString() + public override string ToString() { - return String.Format("Batch{{events={0}, batchId={1}, serverId={2}}", _batch.Count, _batchId, _serverId); + return string.Format("Batch{{events={0}, batchId={1}, serverId={2}}", _batch.Count, _batchId, _serverId); } } } diff --git a/AppmetrS2S/Persister/FileBatchPersister.cs b/AppmetrS2S/Persister/FileBatchPersister.cs index 97311af..90cf48f 100644 --- a/AppmetrS2S/Persister/FileBatchPersister.cs +++ b/AppmetrS2S/Persister/FileBatchPersister.cs @@ -1,4 +1,5 @@ using AppmetrS2S.Serializations; +using Common.Logging; namespace AppmetrS2S.Persister { @@ -11,13 +12,12 @@ namespace AppmetrS2S.Persister using System.Linq; using System.Threading; using Actions; - using log4net; #endregion public class FileBatchPersister : IBatchPersister { - private static readonly ILog Log = LogUtils.GetLogger(typeof(FileBatchPersister)); + private static readonly ILog Log = LogManager.GetLogger(); private readonly ReaderWriterLock _lock = new ReaderWriterLock(); @@ -31,7 +31,7 @@ public class FileBatchPersister : IBatchPersister private Int64 _lastBatchId; private String _serverId; - public FileBatchPersister(string filePath) : this(filePath, new JavaScriptJsonSerializer()) + public FileBatchPersister(string filePath) : this(filePath, new BasicJsonSerializer()) { } diff --git a/AppmetrS2S/Properties/AssemblyInfo.cs b/AppmetrS2S/Properties/AssemblyInfo.cs deleted file mode 100644 index 2039e03..0000000 --- a/AppmetrS2S/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("AppmetrS2S")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("AppmetrS2S")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("594a7c70-c6e3-427b-8eb0-4d09a66e347a")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/AppmetrS2S/Serializations/BasicJsonSerializer.cs b/AppmetrS2S/Serializations/BasicJsonSerializer.cs new file mode 100644 index 0000000..c2c1d03 --- /dev/null +++ b/AppmetrS2S/Serializations/BasicJsonSerializer.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace AppmetrS2S.Serializations +{ + public class BasicJsonSerializer : IJsonSerializer + { + private static readonly JsonSerializerSettings _serializer = new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects + }; + public string Serialize(object obj) + { + return JsonConvert.SerializeObject(obj, _serializer); + } + + public T Deserialize(string json) + { + return JsonConvert.DeserializeObject(json, _serializer); + } + } +} diff --git a/AppmetrS2S/Serializations/JavaScriptJsonSerializer.cs b/AppmetrS2S/Serializations/JavaScriptJsonSerializer.cs deleted file mode 100644 index c546cc5..0000000 --- a/AppmetrS2S/Serializations/JavaScriptJsonSerializer.cs +++ /dev/null @@ -1,185 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.Serialization; -using System.Web.Script.Serialization; -using AppmetrS2S.Actions; -using AppmetrS2S.Persister; - -namespace AppmetrS2S.Serializations -{ - public class JavaScriptJsonSerializer : IJsonSerializer - { - private static readonly JavaScriptSerializer Serializer; - - static JavaScriptJsonSerializer() - { - Serializer = new JavaScriptSerializer(); - Serializer.MaxJsonLength = 20*1024*1024; // 20 MB - Serializer.RegisterConverters(new[] {new BatchJsonConverter()}); - } - - public string Serialize(object obj) - { - var json = Serializer.Serialize(obj); - return json; - } - - public T Deserialize(string json) - { - var result = Serializer.Deserialize(json); - return result; - } - - /// - /// If you want to add new Object types for this serializer, you should add this type to , and write a little bit of code in method - /// - internal class BatchJsonConverter : JavaScriptConverter - { - private const string TypeFieldName = "___type"; - //We couldn't use __ prefix, cause this prefix are used for DataContractSerializer and Deserialize method throw Exception - - public override object Deserialize(IDictionary dictionary, Type type, - JavaScriptSerializer serializer) - { - return ConvertDictionaryToObject(dictionary, type); - } - - public override IDictionary Serialize(object obj, JavaScriptSerializer serializer) - { - if (ReferenceEquals(obj, null)) return null; - - Type objType = obj.GetType(); - if (Attribute.GetCustomAttribute(objType, typeof(DataContractAttribute)) == null) return null; - - var result = new Dictionary { { TypeFieldName, objType.AssemblyQualifiedName } }; - - ProcessFieldsAndProperties(obj, - (attribute, info) => - { - if (info.GetValue(obj) != null) result.Add(attribute.Name, info.GetValue(obj)); - }, - (attribute, info) => - { - if (info.GetValue(obj) != null) result.Add(attribute.Name, info.GetValue(obj)); - }); - - return result; - } - - public override IEnumerable SupportedTypes - { - get { return new[] { typeof(Batch), typeof(AppMetrAction) }; } - } - - private static object ConvertDictionaryToObject(IDictionary dictionary, Type type) - { - var objType = GetSerializedObjectType(dictionary); - if (objType == null) return null; - - var constructor = - objType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[0], null) ?? - objType.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new Type[0], null); - - var result = constructor.Invoke(null); - - Action action = (attribute, info) => - { - Type fieldType = info is FieldInfo - ? (info as FieldInfo).FieldType - : info is PropertyInfo ? (info as PropertyInfo).PropertyType : null; - MethodInfo setValue = info.GetType() - .GetMethod("SetValue", new[] { typeof(object), typeof(object) }); - - if (fieldType == null || setValue == null) return; - - object value = GetValue(dictionary, attribute.Name); - - if (typeof(ICollection).IsAssignableFrom(fieldType)) - { - var serializedActions = value as ArrayList; - - if (serializedActions != null) - { - var actions = (ICollection)Activator.CreateInstance(fieldType); - foreach (var val in serializedActions) - { - if (val is IDictionary) - actions.Add( - (AppMetrAction) - ConvertDictionaryToObject(val as IDictionary, - GetSerializedObjectType(dictionary))); - } - setValue.Invoke(info, new[] { result, actions }); - } - } - else - { - setValue.Invoke(info, new[] { result, value }); - } - }; - - ProcessFieldsAndProperties(result, - action, - action); - - return result; - } - - private static Type GetSerializedObjectType(IDictionary dictionary) - { - object typeName; - if (!dictionary.TryGetValue(TypeFieldName, out typeName) || !(typeName is string)) - return null; - - return Type.GetType(typeName as string); - } - - private static object GetValue(IDictionary dictionary, string key) - { - object value; - dictionary.TryGetValue(key, out value); - - return value; - } - - private static void ProcessFieldsAndProperties(object obj, - Action fieldProcessor, - Action propertiesProcessor) - { - Type objType = obj.GetType(); - - - const BindingFlags bindingFlags = - BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | - BindingFlags.NonPublic; - while (!(typeof(object) == objType)) - { - foreach (FieldInfo field in objType.GetFields(bindingFlags)) - { - var dataMemberAttribute = - (DataMemberAttribute)field.GetCustomAttribute(typeof(DataMemberAttribute)); - if (dataMemberAttribute != null) - { - fieldProcessor.Invoke(dataMemberAttribute, field); - } - } - - foreach (PropertyInfo property in objType.GetProperties(bindingFlags)) - { - var dataMemberAttribute = - (DataMemberAttribute)property.GetCustomAttribute(typeof(DataMemberAttribute)); - if (dataMemberAttribute != null) - { - propertiesProcessor.Invoke(dataMemberAttribute, property); - } - } - - objType = objType.BaseType; - } - } - } - - } -} diff --git a/AppmetrS2S/Serializations/JavaScriptJsonSerializerWithCache.cs b/AppmetrS2S/Serializations/JavaScriptJsonSerializerWithCache.cs deleted file mode 100644 index 8f7e7be..0000000 --- a/AppmetrS2S/Serializations/JavaScriptJsonSerializerWithCache.cs +++ /dev/null @@ -1,258 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.Serialization; -using System.Web.Script.Serialization; -using AppmetrS2S.Actions; -using AppmetrS2S.Persister; - -namespace AppmetrS2S.Serializations -{ - public class JavaScriptJsonSerializerWithCache : IJsonSerializer - { - private static readonly JavaScriptSerializer Serializer; - - static JavaScriptJsonSerializerWithCache() - { - Serializer = new JavaScriptSerializer(); - Serializer.MaxJsonLength = 20 * 1024 * 1024; // 20 MB - Serializer.RegisterConverters(new[] { new BatchJsonConverter() }); - } - - public string Serialize(object obj) - { - var json = Serializer.Serialize(obj); - return json; - } - - public T Deserialize(string json) - { - var result = Serializer.Deserialize(json); - return result; - } - - /// - /// If you want to add new Object types for this serializer, you should add this type to , and write a little bit of code in method - /// - internal class BatchJsonConverter : JavaScriptConverter - { - private const string TypeFieldName = "___type"; - //We couldn't use __ prefix, cause this prefix are used for DataContractSerializer and Deserialize method throw Exception - - private static readonly ConcurrentDictionary _typeDescriptions - = new ConcurrentDictionary(); - - public override object Deserialize( - IDictionary dictionary, - Type type, - JavaScriptSerializer serializer) - { - return ConvertDictionaryToObject(dictionary); - } - - public override IDictionary Serialize(object obj, JavaScriptSerializer serializer) - { - if (ReferenceEquals(obj, null)) return null; - - var objType = obj.GetType(); - var typeDescription = GetTypeDescription(objType); - if (!typeDescription.Serializable) return null; - - var result = new Dictionary { { TypeFieldName, objType.AssemblyQualifiedName } }; - - ProcessFieldsAndProperties(typeDescription, - (name, info) => - { - var value = info.GetValue(obj); - if (value == null) return; - result.Add(name, value); - }, - (name, info) => - { - var value = info.GetValue(obj); - if (value == null) return; - result.Add(name, value); - }); - - return result; - } - - public override IEnumerable SupportedTypes - { - get { return new[] { typeof(Batch), typeof(AppMetrAction) }; } - } - - private static object ConvertDictionaryToObject(IDictionary dictionary) - { - var objType = GetSerializedObjectType(dictionary); - if (objType == null) return null; - - var constructor = - objType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[0], null) ?? - objType.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new Type[0], null); - - var result = constructor.Invoke(null); - - Action action = (name, info) => - { - var fieldType = info is FieldInfo - ? (info as FieldInfo).FieldType - : info is PropertyInfo ? (info as PropertyInfo).PropertyType : null; - - var setValue = info.GetType().GetMethod("SetValue", new[] { typeof(object), typeof(object) }); - - if (fieldType == null || setValue == null) return; - - var value = GetValue(dictionary, name); - if (typeof(ICollection).IsAssignableFrom(fieldType)) - { - var serializedActions = value as ArrayList; - if (serializedActions != null) - { - var actions = (ICollection)Activator.CreateInstance(fieldType); - foreach (var val in serializedActions) - { - if (val is IDictionary) - actions.Add( - (AppMetrAction) - ConvertDictionaryToObject(val as IDictionary)); - } - setValue.Invoke(info, new[] { result, actions }); - } - } - else - { - setValue.Invoke(info, new[] { result, value }); - } - }; - - var typeDescription = GetTypeDescription(result.GetType()); - ProcessFieldsAndProperties(typeDescription, action, action); - - return result; - } - - private static Type GetSerializedObjectType(IDictionary dictionary) - { - object typeName; - if (!dictionary.TryGetValue(TypeFieldName, out typeName) || !(typeName is string)) - return null; - - return Type.GetType(typeName as string); - } - - private static object GetValue(IDictionary dictionary, string key) - { - object value; - dictionary.TryGetValue(key, out value); - - return value; - } - - private static void ProcessFieldsAndProperties(TypeDescription typeDescription, - Action fieldProcessor, - Action propertiesProcessor) - { - foreach (var field in typeDescription.Fields) - { - fieldProcessor(field.Name, field.Field); - } - - foreach (var property in typeDescription.Properities) - { - propertiesProcessor(property.Name, property.Property); - } - } - - private static TypeDescription GetTypeDescription(Type type) - { - TypeDescription result; - if (_typeDescriptions.TryGetValue(type, out result)) return result; - - const BindingFlags bindingFlags = - BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | - BindingFlags.NonPublic; - - if (Attribute.GetCustomAttribute(type, typeof (DataContractAttribute)) == null) - { - result = new TypeDescription( - false, - new SerializableField[0], - new SerializableProperty[0]); - - _typeDescriptions[type] = result; - return result; - } - - var fields = new List(); - var properties = new List(); - - var objType = type; - while (objType != null && objType != typeof(object)) - { - foreach (var field in objType.GetFields(bindingFlags)) - { - var attribute = (DataMemberAttribute)field.GetCustomAttribute(typeof(DataMemberAttribute)); - if (attribute != null) fields.Add(new SerializableField(attribute.Name, field)); - } - - foreach (var property in objType.GetProperties(bindingFlags)) - { - var attribute = (DataMemberAttribute)property.GetCustomAttribute(typeof(DataMemberAttribute)); - if (attribute != null) properties.Add(new SerializableProperty(attribute.Name, property)); - } - - objType = objType.BaseType; - } - - result = new TypeDescription( - fields.Count > 0 || properties.Count > 0, - fields.ToArray(), - properties.ToArray()); - - _typeDescriptions[type] = result; - return result; - } - } - - private struct TypeDescription - { - public readonly bool Serializable; - public readonly SerializableField[] Fields; - public readonly SerializableProperty[] Properities; - - public TypeDescription(bool serializable, SerializableField[] fields, SerializableProperty[] properities) - { - Serializable = serializable; - Fields = fields; - Properities = properities; - } - } - - private struct SerializableField - { - public readonly string Name; - public readonly FieldInfo Field; - - public SerializableField(string name, FieldInfo field) - { - Name = name; - Field = field; - } - } - - private struct SerializableProperty - { - public readonly string Name; - public readonly PropertyInfo Property; - - public SerializableProperty(string name, PropertyInfo property) - { - Name = name; - Property = property; - } - } - } -} diff --git a/AppmetrS2S/Utils.cs b/AppmetrS2S/Utils.cs index 0beb5c1..94468d3 100644 --- a/AppmetrS2S/Utils.cs +++ b/AppmetrS2S/Utils.cs @@ -1,15 +1,16 @@ using System; using System.IO; +using System.Runtime.CompilerServices; using System.Text; using AppmetrS2S.Persister; using AppmetrS2S.Serializations; -using log4net; +using Common.Logging; namespace AppmetrS2S { internal class Utils { - private static readonly ILog Log = LogUtils.GetLogger(typeof(FileBatchPersister)); + private static readonly ILog Log = LogManager.GetLogger(); public static long GetNowUnixTimestamp() { @@ -31,13 +32,13 @@ public static void WriteData(Stream stream, byte[] data) public static void WriteBatch(Stream stream, Batch batch, IJsonSerializer serializer) { - Log.DebugFormat("Starting serialize batch with id={0}", batch.GetBatchId()); + Log.TraceFormat("Starting serialize batch with id={0}", batch.GetBatchId()); var json = serializer.Serialize(batch); - Log.DebugFormat("Get bytes from serialized batch with id={0}", batch.GetBatchId()); - byte[] data = Encoding.UTF8.GetBytes(json); - Log.DebugFormat("Write bytes to stream. Batch id={0}", batch.GetBatchId()); + Log.TraceFormat("Get bytes from serialized batch with id={0}", batch.GetBatchId()); + var data = Encoding.UTF8.GetBytes(json); + Log.TraceFormat("Write bytes to stream. Batch id={0}", batch.GetBatchId()); stream.Write(data, 0, data.Length); - Log.DebugFormat("Flush stream. Batch id={0}", batch.GetBatchId()); + Log.TraceFormat("Flush stream. Batch id={0}", batch.GetBatchId()); stream.Flush(); } @@ -46,7 +47,7 @@ public static bool TryReadBatch(Stream stream, IJsonSerializer serializer, out B try { batch = serializer.Deserialize(new StreamReader(stream).ReadToEnd()); - Log.InfoFormat("Successfully read the batch {0}", batch.GetBatchId()); + Log.TraceFormat("Successfully read the batch {0}", batch.GetBatchId()); return true; } catch (Exception e) @@ -60,5 +61,97 @@ public static bool TryReadBatch(Stream stream, IJsonSerializer serializer, out B return false; } } + + public static string UrlEncode(string str, Encoding e) => + !string.IsNullOrWhiteSpace(str) + ? Encoding.ASCII.GetString(UrlEncodeToBytes(str, e)) + : null; + + private static byte[] UrlEncodeToBytes(string str, Encoding e) + { + var bytes = e.GetBytes(str); + return UrlEncode(bytes, bytes.Length); + } + + private static byte[] UrlEncode(byte[] bytes, int count) + { + var num1 = 0; + var num2 = 0; + for (var index = 0; index < count; ++index) + { + var ch = (char)bytes[index]; + if (ch == ' ') + ++num1; + else if (!IsUrlSafeChar(ch)) + ++num2; + } + if (num1 == 0 && num2 == 0) + { + if (bytes.Length == count) + return bytes; + byte[] numArray = new byte[count]; + Buffer.BlockCopy(bytes, 0, numArray, 0, count); + return numArray; + } + byte[] numArray1 = new byte[count + num2 * 2]; + int num3 = 0; + for (int index1 = 0; index1 < count; ++index1) + { + byte num4 = bytes[index1]; + char ch = (char)num4; + if (IsUrlSafeChar(ch)) + numArray1[num3++] = num4; + else if (ch == ' ') + { + numArray1[num3++] = (byte)43; + } + else + { + byte[] numArray2 = numArray1; + int index2 = num3; + int num5 = index2 + 1; + numArray2[index2] = 37; + byte[] numArray3 = numArray1; + int index3 = num5; + int num6 = index3 + 1; + int charLower1 = (int)(byte)ToCharLower((int)num4 >> 4); + numArray3[index3] = (byte)charLower1; + byte[] numArray4 = numArray1; + int index4 = num6; + num3 = index4 + 1; + int charLower2 = (int)(byte)ToCharLower((int)num4); + numArray4[index4] = (byte)charLower2; + } + } + return numArray1; + } + + public static bool IsUrlSafeChar(char ch) + { + if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || (ch >= '0' && ch <= '9' || ch == '!')) + return true; + switch (ch) + { + case '(': + case ')': + case '*': + case '-': + case '.': + case '_': + return true; + default: + return false; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static char ToCharLower(int value) + { + value &= 15; + value += 48; + if (value > 57) + value += 39; + return (char)value; + } } } \ No newline at end of file diff --git a/AppmetrS2S/packages.config b/AppmetrS2S/packages.config deleted file mode 100644 index 3a86f25..0000000 --- a/AppmetrS2S/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file