You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2016/09/16 15:08:41 UTC
[1/5] ignite git commit: IGNITE-3199 .NET: Add ASP.NET Session-State
Store Provider
Repository: ignite
Updated Branches:
refs/heads/master dddf6ba0f -> 77a9aaca1
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/IgniteSessionStateItemCollection.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/IgniteSessionStateItemCollection.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/IgniteSessionStateItemCollection.cs
new file mode 100644
index 0000000..d1ba5da
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/IgniteSessionStateItemCollection.cs
@@ -0,0 +1,534 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 Apache.Ignite.AspNet.Impl
+{
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Collections.Specialized;
+ using System.Diagnostics;
+ using System.Diagnostics.CodeAnalysis;
+ using System.IO;
+ using System.Linq;
+ using System.Runtime.Serialization.Formatters.Binary;
+ using System.Web.SessionState;
+ using Apache.Ignite.Core.Binary;
+ using Apache.Ignite.Core.Impl.Common;
+
+ /// <summary>
+ /// Binarizable key-value collection with dirty item tracking.
+ /// </summary>
+ internal class IgniteSessionStateItemCollection : ISessionStateItemCollection
+ {
+ /** */
+ private readonly Dictionary<string, int> _dict;
+
+ /** */
+ private readonly List<Entry> _list;
+
+ /** Indicates where this is a new collection, not a deserialized old one. */
+ private readonly bool _isNew;
+
+ /** Removed keys. Hash set because keys can be removed multiple times. */
+ private HashSet<string> _removedKeys;
+
+ /** Indicates that entire collection is dirty and can't be written as a diff. */
+ private bool _dirtyAll;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="IgniteSessionStateItemCollection"/> class.
+ /// </summary>
+ /// <param name="reader">The binary reader.</param>
+ internal IgniteSessionStateItemCollection(IBinaryRawReader reader)
+ {
+ Debug.Assert(reader != null);
+
+ var count = reader.ReadInt();
+
+ _dict = new Dictionary<string, int>(count);
+ _list = new List<Entry>(count);
+
+ for (var i = 0; i < count; i++)
+ {
+ var key = reader.ReadString();
+
+ var valBytes = reader.ReadByteArray();
+
+ if (valBytes != null)
+ {
+ var entry = new Entry(key, true, valBytes);
+
+ _dict[key] = _list.Count;
+
+ _list.Add(entry);
+ }
+ else
+ AddRemovedKey(key);
+ }
+
+ _isNew = false;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="IgniteSessionStateItemCollection"/> class.
+ /// </summary>
+ public IgniteSessionStateItemCollection()
+ {
+ _dict = new Dictionary<string, int>();
+ _list = new List<Entry>();
+ _isNew = true;
+ }
+
+ /** <inheritdoc /> */
+ [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0",
+ Justification = "Validation is present.")]
+ public void CopyTo(Array array, int index)
+ {
+ IgniteArgumentCheck.NotNull(array, "array");
+ IgniteArgumentCheck.Ensure(Count + index < array.Length, "array",
+ "The number of elements in the source collection is greater than the available space " +
+ "from specified index to the end of the array.");
+
+ // This should return only keys.
+ foreach (var entry in _list)
+ array.SetValue(entry.Key, index++);
+ }
+
+ /** <inheritdoc /> */
+ public IEnumerator GetEnumerator()
+ {
+ // This should return only keys.
+ return _list.Select(x => x.Key).GetEnumerator();
+ }
+
+ /** <inheritdoc /> */
+ public int Count
+ {
+ get { return _dict.Count; }
+ }
+
+ /** <inheritdoc /> */
+ public object SyncRoot
+ {
+ get { return _list; }
+ }
+
+ /** <inheritdoc /> */
+ public bool IsSynchronized
+ {
+ get { return false; }
+ }
+
+ /** <inheritdoc /> */
+ public object this[string key]
+ {
+ get
+ {
+ var entry = GetEntry(key);
+
+ if (entry == null)
+ return null;
+
+ SetDirtyOnRead(entry);
+
+ return entry.Value;
+ }
+ set
+ {
+ var entry = GetOrCreateDirtyEntry(key);
+
+ entry.Value = value;
+ }
+ }
+
+ /** <inheritdoc /> */
+ public object this[int index]
+ {
+ get
+ {
+ var entry = _list[index];
+
+ SetDirtyOnRead(entry);
+
+ return entry.Value;
+ }
+ set
+ {
+ var entry = _list[index];
+
+ entry.IsDirty = true;
+
+ entry.Value = value;
+ }
+ }
+
+ /** <inheritdoc /> */
+ public NameObjectCollectionBase.KeysCollection Keys
+ {
+ get { return new NameObjectCollection(this).Keys; }
+ }
+
+
+ /** <inheritdoc /> */
+ public bool Dirty
+ {
+ get { return _dirtyAll || _list.Any(x => x.IsDirty); }
+ set { _dirtyAll = value; }
+ }
+
+ /// <summary>
+ /// Writes this object to the given writer.
+ /// </summary>
+ public void WriteBinary(IBinaryRawWriter writer, bool changesOnly)
+ {
+ IgniteArgumentCheck.NotNull(writer, "writer");
+
+ if (_isNew || _dirtyAll || !changesOnly || (_removedKeys == null && _list.All(x => x.IsDirty)))
+ {
+ // Write in full mode.
+ writer.WriteInt(_list.Count);
+
+ foreach (var entry in _list)
+ {
+ writer.WriteString(entry.Key);
+
+ // Write as byte array to enable partial deserialization.
+ writer.WriteByteArray(entry.GetBytes());
+ }
+ }
+ else
+ {
+ // Write in diff mode.
+ var removed = GetRemovedKeys();
+
+ var count = _list.Count(x => x.IsDirty) + (removed == null ? 0 : removed.Count);
+
+ writer.WriteInt(count); // reserve count
+
+ // Write removed keys as [key + null].
+ if (removed != null)
+ {
+ foreach (var removedKey in removed)
+ {
+ writer.WriteString(removedKey);
+ writer.WriteByteArray(null);
+ }
+ }
+
+ // Write dirty items.
+ foreach (var entry in _list)
+ {
+ if (!entry.IsDirty)
+ continue;
+
+ writer.WriteString(entry.Key);
+
+ // Write as byte array to enable partial deserialization.
+ writer.WriteByteArray(entry.GetBytes());
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the removed keys.
+ /// </summary>
+ private ICollection<string> GetRemovedKeys()
+ {
+ if (_removedKeys == null)
+ return null;
+
+ // Filter out existing keys.
+ var removed = new HashSet<string>(_removedKeys);
+
+ foreach (var entry in _list)
+ removed.Remove(entry.Key);
+
+ return removed;
+ }
+
+ /// <summary>
+ /// Removes the specified key.
+ /// </summary>
+ public void Remove(string key)
+ {
+ var index = GetIndex(key);
+
+ if (index < 0)
+ return;
+
+ var entry = _list[index];
+ Debug.Assert(key == entry.Key);
+
+ _list.RemoveAt(index);
+ _dict.Remove(key);
+
+ // Update all indexes.
+ for (var i = 0; i < _list.Count; i++)
+ _dict[_list[i].Key] = i;
+
+ if (entry.IsInitial)
+ AddRemovedKey(key);
+ }
+
+ /// <summary>
+ /// Removes at specified index.
+ /// </summary>
+ public void RemoveAt(int index)
+ {
+ var entry = _list[index];
+
+ _list.RemoveAt(index);
+ _dict.Remove(entry.Key);
+
+ if (entry.IsInitial)
+ AddRemovedKey(entry.Key);
+ }
+
+ /// <summary>
+ /// Clears this instance.
+ /// </summary>
+ public void Clear()
+ {
+ foreach (var entry in _list)
+ {
+ if (entry.IsInitial)
+ AddRemovedKey(entry.Key);
+ }
+
+ _list.Clear();
+ _dict.Clear();
+
+ _dirtyAll = true;
+ }
+
+ /// <summary>
+ /// Applies the changes.
+ /// </summary>
+ public void ApplyChanges(IgniteSessionStateItemCollection changes)
+ {
+ var removed = changes._removedKeys;
+
+ if (removed != null)
+ {
+ foreach (var key in removed)
+ Remove(key);
+ }
+ else
+ {
+ // Not a diff: replace all.
+ Clear();
+ }
+
+ foreach (var changedEntry in changes._list)
+ {
+ var entry = GetOrCreateDirtyEntry(changedEntry.Key);
+
+ // Copy without deserialization.
+ changedEntry.CopyTo(entry);
+ }
+ }
+
+ /// <summary>
+ /// Adds the removed key.
+ /// </summary>
+ private void AddRemovedKey(string key)
+ {
+ Debug.Assert(!_isNew);
+
+ if (_removedKeys == null)
+ _removedKeys = new HashSet<string>();
+
+ _removedKeys.Add(key);
+ }
+
+ /// <summary>
+ /// Gets or creates an entry.
+ /// </summary>
+ private Entry GetOrCreateDirtyEntry(string key)
+ {
+ var entry = GetEntry(key);
+
+ if (entry == null)
+ {
+ entry = new Entry(key, false, null);
+
+ _dict[key] = _list.Count;
+ _list.Add(entry);
+ }
+
+ entry.IsDirty = true;
+
+ return entry;
+ }
+
+ /// <summary>
+ /// Gets the entry.
+ /// </summary>
+ private Entry GetEntry(string key)
+ {
+ IgniteArgumentCheck.NotNull(key, "key");
+
+ int index;
+
+ return !_dict.TryGetValue(key, out index) ? null : _list[index];
+ }
+
+ /// <summary>
+ /// Gets the index.
+ /// </summary>
+ private int GetIndex(string key)
+ {
+ int index;
+
+ return !_dict.TryGetValue(key, out index) ? -1 : index;
+ }
+
+ /// <summary>
+ /// Sets the dirty on read.
+ /// </summary>
+ private static void SetDirtyOnRead(Entry entry)
+ {
+ var type = entry.Value.GetType();
+
+ if (IsImmutable(type))
+ return;
+
+ entry.IsDirty = true;
+ }
+
+ /// <summary>
+ /// Determines whether the specified type is immutable.
+ /// </summary>
+ private static bool IsImmutable(Type type)
+ {
+ type = Nullable.GetUnderlyingType(type) ?? type; // Unwrap nullable.
+
+ if (type.IsPrimitive)
+ return true;
+
+ if (type == typeof(string) || type == typeof(DateTime) || type == typeof(Guid) || type == typeof(decimal))
+ return true;
+
+ return false;
+ }
+
+ /// <summary>
+ /// Inner entry.
+ /// </summary>
+ private class Entry
+ {
+ /** */
+ public readonly bool IsInitial;
+
+ /** */
+ public readonly string Key;
+
+ /** */
+ public bool IsDirty;
+
+ /** */
+ private object _value;
+
+ /** */
+ private bool _isDeserialized;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Entry"/> class.
+ /// </summary>
+ public Entry(string key, bool isInitial, object value)
+ {
+ Debug.Assert(key != null);
+
+ Key = key;
+ IsInitial = isInitial;
+ _isDeserialized = !isInitial;
+ _value = value;
+ }
+
+ /// <summary>
+ /// Gets or sets the value.
+ /// </summary>
+ public object Value
+ {
+ get
+ {
+ if (!_isDeserialized)
+ {
+ using (var stream = new MemoryStream((byte[])_value))
+ {
+ _value = new BinaryFormatter().Deserialize(stream);
+ }
+
+ _isDeserialized = true;
+ }
+
+ return _value;
+ }
+ set
+ {
+ _value = value;
+ _isDeserialized = true;
+ }
+ }
+
+ /// <summary>
+ /// Copies contents to another entry.
+ /// </summary>
+ public void CopyTo(Entry entry)
+ {
+ Debug.Assert(entry != null);
+
+ entry._isDeserialized = _isDeserialized;
+ entry._value = _value;
+ }
+
+ /// <summary>
+ /// Gets the bytes.
+ /// </summary>
+ public byte[] GetBytes()
+ {
+ if (!_isDeserialized)
+ return (byte[]) _value;
+
+ using (var stream = new MemoryStream())
+ {
+ new BinaryFormatter().Serialize(stream, _value);
+
+ return stream.ToArray();
+ }
+ }
+ }
+
+ /// <summary>
+ /// NameObjectCollectionBase.KeysCollection has internal constructor.
+ /// The only way to implement ISessionStateItemCollection.Keys property
+ /// is to have a NameObjectCollectionBase in hand.
+ /// </summary>
+ private class NameObjectCollection : NameObjectCollectionBase
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="NameObjectCollection"/> class.
+ /// </summary>
+ public NameObjectCollection(IEnumerable keys)
+ {
+ foreach (string key in keys)
+ BaseAdd(key, null);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/IgniteSessionStateStoreData.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/IgniteSessionStateStoreData.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/IgniteSessionStateStoreData.cs
new file mode 100644
index 0000000..32c36b5
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/IgniteSessionStateStoreData.cs
@@ -0,0 +1,116 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 Apache.Ignite.AspNet.Impl
+{
+ using System;
+ using System.IO;
+ using System.Web;
+ using System.Web.SessionState;
+ using Apache.Ignite.Core.Binary;
+
+ /// <summary>
+ /// Ignite <see cref="SessionStateStoreData"/> implementation.
+ /// </summary>
+ internal class IgniteSessionStateStoreData : SessionStateStoreData
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="IgniteSessionStateStoreData"/> class.
+ /// </summary>
+ /// <param name="reader">The reader.</param>
+ public IgniteSessionStateStoreData(IBinaryRawReader reader) : base(
+ new IgniteSessionStateItemCollection(reader),
+ DeserializeStaticObjects(reader.ReadByteArray()), reader.ReadInt())
+ {
+ LockNodeId = reader.ReadGuid();
+ LockId = reader.ReadLong();
+ LockTime = reader.ReadTimestamp();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="IgniteSessionStateStoreData"/> class.
+ /// </summary>
+ /// <param name="staticObjects">The static objects.</param>
+ /// <param name="timeout">The timeout.</param>
+ public IgniteSessionStateStoreData(HttpStaticObjectsCollection staticObjects, int timeout)
+ : base(new IgniteSessionStateItemCollection(), staticObjects, timeout)
+ {
+ // No-op.
+ }
+
+ /// <summary>
+ /// Writes this object to the given writer.
+ /// </summary>
+ public void WriteBinary(IBinaryRawWriter writer, bool changesOnly)
+ {
+ ((IgniteSessionStateItemCollection)Items).WriteBinary(writer, changesOnly);
+ writer.WriteByteArray(SerializeStaticObjects());
+ writer.WriteInt(Timeout);
+
+ writer.WriteGuid(LockNodeId);
+ writer.WriteLong(LockId);
+ writer.WriteTimestamp(LockTime);
+ }
+
+ /// <summary>
+ /// Gets or sets the lock node id. Null means not locked.
+ /// </summary>
+ public Guid? LockNodeId { get; set; }
+
+ /// <summary>
+ /// Gets or sets the lock id.
+ /// </summary>
+ public long LockId { get; set; }
+
+ /// <summary>
+ /// Gets or sets the lock time.
+ /// </summary>
+ public DateTime? LockTime { get; set; }
+
+ /// <summary>
+ /// Deserializes the static objects.
+ /// </summary>
+ private static HttpStaticObjectsCollection DeserializeStaticObjects(byte[] bytes)
+ {
+ if (bytes == null)
+ return new HttpStaticObjectsCollection();
+
+ using (var stream = new MemoryStream(bytes))
+ using (var reader = new BinaryReader(stream))
+ {
+ return HttpStaticObjectsCollection.Deserialize(reader);
+ }
+ }
+
+ /// <summary>
+ /// Serializes the static objects.
+ /// </summary>
+ private byte[] SerializeStaticObjects()
+ {
+ if (StaticObjects == null || StaticObjects.Count == 0)
+ return null;
+
+ using (var stream = new MemoryStream())
+ using (var writer = new BinaryWriter(stream))
+ {
+ StaticObjects.Serialize(writer);
+
+ return stream.ToArray();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/SessionStateLockResult.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/SessionStateLockResult.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/SessionStateLockResult.cs
new file mode 100644
index 0000000..ebca8e0
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/SessionStateLockResult.cs
@@ -0,0 +1,91 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 Apache.Ignite.AspNet.Impl
+{
+ using System;
+ using System.Diagnostics;
+ using Apache.Ignite.Core.Binary;
+
+ /// <summary>
+ /// Result of the session state lock processor.
+ /// </summary>
+ internal class SessionStateLockResult
+ {
+ /** Success flag. */
+ private readonly bool _success;
+
+ /** Session state data. */
+ private readonly IgniteSessionStateStoreData _data;
+
+ /** Lock time. */
+ private readonly DateTime? _lockTime;
+
+ /** Lock id. */
+ private readonly long _lockId;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SessionStateLockResult"/> class.
+ /// </summary>
+ /// <param name="reader">The reader.</param>
+ public SessionStateLockResult(IBinaryRawReader reader)
+ {
+ _success = reader.ReadBoolean();
+
+ if (_success)
+ _data = new IgniteSessionStateStoreData(reader);
+
+ _lockTime = reader.ReadTimestamp();
+ _lockId = reader.ReadLong();
+
+ Debug.Assert(_success ^ (_data == null));
+ Debug.Assert(_success ^ (_lockTime != null));
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether lock succeeded.
+ /// </summary>
+ public bool Success
+ {
+ get { return _success; }
+ }
+
+ /// <summary>
+ /// Gets the data. Null when <see cref="Success"/> is <c>false</c>.
+ /// </summary>
+ public IgniteSessionStateStoreData Data
+ {
+ get { return _data; }
+ }
+
+ /// <summary>
+ /// Gets the lock time. Null when <see cref="Success"/> is <c>true</c>.
+ /// </summary>
+ public DateTime? LockTime
+ {
+ get { return _lockTime; }
+ }
+
+ /// <summary>
+ /// Gets the lock identifier.
+ /// </summary>
+ public long LockId
+ {
+ get { return _lockId; }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet/Properties/AssemblyInfo.cs
index ad61ecd..2a7da67 100644
--- a/modules/platforms/dotnet/Apache.Ignite.AspNet/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/Properties/AssemblyInfo.cs
@@ -17,6 +17,7 @@
using System;
using System.Reflection;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Apache.Ignite.AspNet")]
@@ -36,4 +37,6 @@ using System.Runtime.InteropServices;
[assembly: AssemblyFileVersion("1.8.0.14218")]
[assembly: AssemblyInformationalVersion("1.8.0")]
-[assembly: CLSCompliant(true)]
\ No newline at end of file
+[assembly: CLSCompliant(true)]
+
+[assembly: InternalsVisibleTo("Apache.Ignite.AspNet.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c9380ce05eb74bd7c531f72e9ea615c59d7eceb09bd9795cb3dff1fcf638fd799c2a58a9be42fff156efe1c8cdebb751e27763f6c9a7c80cdc1dc1bbf44283608ef18ccd5017fd57b2b026503637c89c2537f361807f3bdd49265f4d444716159d989342561d324b1a0961640338bb32eaf67f4ae0c95f1b210f65404b0909c6")]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
index 95fea8f..b1e0dbe 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
@@ -49,13 +49,11 @@
<Reference Include="System.configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
- <Reference Include="System.Web" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.XML" />
</ItemGroup>
<ItemGroup>
<Compile Include="TestAppConfig.cs" />
- <Compile Include="AspNet\IgniteOutputCacheProviderTest.cs" />
<Compile Include="Binary\BinaryBuilderSelfTestFullFooter.cs" />
<Compile Include="Binary\BinaryCompactFooterInteropTest.cs" />
<Compile Include="Binary\BinarySelfTestFullFooter.cs" />
@@ -167,10 +165,6 @@
<Compile Include="WindowsServiceTest.cs" />
</ItemGroup>
<ItemGroup>
- <ProjectReference Include="..\Apache.Ignite.AspNet\Apache.Ignite.AspNet.csproj">
- <Project>{13EA96FC-CC83-4164-A7C0-4F30ED797460}</Project>
- <Name>Apache.Ignite.AspNet</Name>
- </ProjectReference>
<ProjectReference Include="..\Apache.Ignite.Core\Apache.Ignite.Core.csproj">
<Project>{4CD2F726-7E2B-46C4-A5BA-057BB82EECB6}</Project>
<Name>Apache.Ignite.Core</Name>
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.Core.Tests/AspNet/IgniteOutputCacheProviderTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/AspNet/IgniteOutputCacheProviderTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/AspNet/IgniteOutputCacheProviderTest.cs
deleted file mode 100644
index 51bfdc1..0000000
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/AspNet/IgniteOutputCacheProviderTest.cs
+++ /dev/null
@@ -1,172 +0,0 @@
-\ufeff/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 Apache.Ignite.Core.Tests.AspNet
-{
- using System;
- using System.Collections.Specialized;
- using System.Threading;
- using Apache.Ignite.AspNet;
- using Apache.Ignite.Core.Common;
- using NUnit.Framework;
-
- /// <summary>
- /// Tests for <see cref="IgniteOutputCacheProvider"/>
- /// </summary>
- public class IgniteOutputCacheProviderTest
- {
- /** Grid name XML config attribute. */
- private const string GridNameAttr = "gridName";
-
- /** Cache name XML config attribute. */
- private const string CacheNameAttr = "cacheName";
-
- /** Cache name XML config attribute. */
- private const string SectionNameAttr = "igniteConfigurationSectionName";
-
- /** Grid name. */
- private const string GridName = "grid1";
-
- /** Cache name. */
- private const string CacheName = "myCache";
-
- /// <summary>
- /// Fixture setup.
- /// </summary>
- [TestFixtureSetUp]
- public void TestFixtureSetUp()
- {
- Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration()) {GridName = GridName});
- }
-
- /// <summary>
- /// Fixture teardown.
- /// </summary>
- [TestFixtureTearDown]
- public void TestFixtureTearDown()
- {
- Ignition.StopAll(true);
- }
-
- /// <summary>
- /// Tests provider initialization.
- /// </summary>
- [Test]
- public void TestInitialization()
- {
- var cacheProvider = new IgniteOutputCacheProvider();
-
- // Not initialized
- Assert.Throws<InvalidOperationException>(() => cacheProvider.Get("1"));
-
- // Grid not started
- Assert.Throws<IgniteException>(() =>
- cacheProvider.Initialize("testName", new NameValueCollection
- {
- {GridNameAttr, "invalidGridName"},
- {CacheNameAttr, CacheName}
- }));
-
- // Valid grid
- cacheProvider = GetProvider();
-
- cacheProvider.Set("1", 1, DateTime.MaxValue);
- Assert.AreEqual(1, cacheProvider.Get("1"));
- }
-
- /// <summary>
- /// Tests autostart from web configuration section.
- /// </summary>
- [Test]
- public void TestStartFromWebConfigSection()
- {
- var cacheProvider = new IgniteOutputCacheProvider();
-
- cacheProvider.Initialize("testName2", new NameValueCollection
- {
- {SectionNameAttr, "igniteConfiguration2"},
- {CacheNameAttr, "cacheName2"}
- });
-
- cacheProvider.Set("1", 3, DateTime.MaxValue);
- Assert.AreEqual(3, cacheProvider.Get("1"));
- }
-
- /// <summary>
- /// Tests provider caching.
- /// </summary>
- [Test]
- public void TestCaching()
- {
- var cacheProvider = GetProvider();
-
- Assert.AreEqual(null, cacheProvider.Get("1"));
- cacheProvider.Set("1", 1, DateTime.MaxValue);
- Assert.AreEqual(1, cacheProvider.Get("1"));
-
- cacheProvider.Remove("1");
- Assert.AreEqual(null, cacheProvider.Get("1"));
-
- Assert.AreEqual(null, cacheProvider.Add("2", 2, DateTime.MaxValue));
- Assert.AreEqual(2, cacheProvider.Add("2", 5, DateTime.MaxValue));
- }
-
- /// <summary>
- /// Tests cache expiration.
- /// </summary>
- [Test]
- public void TestExpiry()
- {
- var cacheProvider = GetProvider();
- cacheProvider.Remove("1");
-
- // Set
- cacheProvider.Set("1", 1, DateTime.UtcNow.AddSeconds(1.3));
- Assert.AreEqual(1, cacheProvider.Get("1"));
- Thread.Sleep(2000);
- Assert.AreEqual(null, cacheProvider.Get("1"));
-
- cacheProvider.Set("1", 1, DateTime.UtcNow);
- Assert.AreEqual(null, cacheProvider.Get("1"));
-
- // Add
- cacheProvider.Add("1", 1, DateTime.UtcNow.AddSeconds(0.7));
- Assert.AreEqual(1, cacheProvider.Get("1"));
- Thread.Sleep(2000);
- Assert.AreEqual(null, cacheProvider.Get("1"));
-
- cacheProvider.Add("1", 1, DateTime.UtcNow);
- Assert.AreEqual(null, cacheProvider.Get("1"));
- }
-
- /// <summary>
- /// Gets the initialized provider.
- /// </summary>
- private static IgniteOutputCacheProvider GetProvider()
- {
- var cacheProvider = new IgniteOutputCacheProvider();
-
- cacheProvider.Initialize("testName", new NameValueCollection
- {
- {GridNameAttr, GridName},
- {CacheNameAttr, CacheName}
- });
-
- return cacheProvider;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs
index c0b8599..6ca2f9d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs
@@ -23,7 +23,6 @@ namespace Apache.Ignite.Core.Tests
using System.Collections.Generic;
using System.Linq;
using System.Threading;
- using Apache.Ignite.Core.Discovery;
using Apache.Ignite.Core.Discovery.Tcp;
using Apache.Ignite.Core.Discovery.Tcp.Static;
using Apache.Ignite.Core.Impl;
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
index 8ba3e29..fb47f29 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
@@ -872,6 +872,21 @@ namespace Apache.Ignite.Core.Impl.Cache
return AsyncInstance.GetTask(CacheOp.InvokeAll, reader => ReadInvokeAllResults<TRes>(reader.Stream));
}
+ /** <inheritDoc /> */
+ public T DoOutInOpExtension<T>(int extensionId, int opCode, Action<IBinaryRawWriter> writeAction,
+ Func<IBinaryRawReader, T> readFunc)
+ {
+ return DoOutInOpX((int) CacheOp.Extension, writer =>
+ {
+ writer.WriteInt(extensionId);
+ writer.WriteInt(opCode);
+ writeAction(writer);
+ },
+ (input, res) => res == True
+ ? readFunc(Marshaller.StartUnmarshal(input))
+ : default(T), ReadException);
+ }
+
/** <inheritdoc /> */
public ICacheLock Lock(TK key)
{
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheOp.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheOp.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheOp.cs
index 4c42bf3..e6ca938 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheOp.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheOp.cs
@@ -61,6 +61,7 @@ namespace Apache.Ignite.Core.Impl.Cache
Replace2 = 37,
Replace3 = 38,
GetConfig = 39,
- LoadAll = 40
+ LoadAll = 40,
+ Extension = 41
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/ICacheInternal.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/ICacheInternal.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/ICacheInternal.cs
index a23cf08..0349db8 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/ICacheInternal.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/ICacheInternal.cs
@@ -36,5 +36,19 @@ namespace Apache.Ignite.Core.Impl.Cache
/// Cursor.
/// </returns>
IQueryCursor<T> QueryFields<T>(SqlFieldsQuery qry, Func<IBinaryRawReader, int, T> readerFunc);
+
+ /// <summary>
+ /// Invokes a cache extension.
+ /// </summary>
+ /// <typeparam name="T">The type of the result.</typeparam>
+ /// <param name="extensionId">The extension identifier.</param>
+ /// <param name="opCode">The extension op code.</param>
+ /// <param name="writeAction">The write action.</param>
+ /// <param name="readFunc">The read action.</param>
+ /// <returns>
+ /// Result of the processing.
+ /// </returns>
+ T DoOutInOpExtension<T>(int extensionId, int opCode, Action<IBinaryRawWriter> writeAction,
+ Func<IBinaryRawReader, T> readFunc);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
index fd52c8a..4ee67dd 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
@@ -21,7 +21,6 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
- using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
index 008ba5c..9fcbeb0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
@@ -43,5 +43,6 @@ using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("Apache.Ignite.Core.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a5bf8e0062a26bde53ccf0f8c42ef5b122a22052f99aecacb7028adcc163050324ee3c75ff40eb0cbe2d0426fa20eca03726cad90d7eb882ff47f5361567a82b676a27565f88b2479d7b9354ae0a1e526ee781b6e11de943d8f4a49efb53765f8c954022bede0fca86c133fab038af8dc88b67d6b6e5b9796d6ca490e699efab")]
[assembly: InternalsVisibleTo("Apache.Ignite.Benchmarks, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a3e0c1df4cbedbd4ed0e88808401c69b69ec12575ed1c056ac9f448e018fb29af19d236b7b03563aad66c48ab2045e72971ed098d4f65d4cdd38d65abcb39b4f84c626b22ccab2754375f0e8c97dc304fa146f0eddad5cc40a71803a8f15b0b0bb0bff0d4bf0ff6a64bb1044e0d71e6e2405b83fd4c1f7b3e2cfc2e9d50823d4")]
+[assembly: InternalsVisibleTo("Apache.Ignite.AspNet.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c9380ce05eb74bd7c531f72e9ea615c59d7eceb09bd9795cb3dff1fcf638fd799c2a58a9be42fff156efe1c8cdebb751e27763f6c9a7c80cdc1dc1bbf44283608ef18ccd5017fd57b2b026503637c89c2537f361807f3bdd49265f4d444716159d989342561d324b1a0961640338bb32eaf67f4ae0c95f1b210f65404b0909c6")]
#endif
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.sln
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.sln b/modules/platforms/dotnet/Apache.Ignite.sln
index 2362ce2..8a3bf04 100644
--- a/modules/platforms/dotnet/Apache.Ignite.sln
+++ b/modules/platforms/dotnet/Apache.Ignite.sln
@@ -36,6 +36,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Ignite.Linq", "Apach
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Ignite.AspNet", "Apache.Ignite.AspNet\Apache.Ignite.AspNet.csproj", "{13EA96FC-CC83-4164-A7C0-4F30ED797460}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Ignite.AspNet.Tests", "Apache.Ignite.AspNet.Tests\Apache.Ignite.AspNet.Tests.csproj", "{18EA4C71-A11D-4AB1-8042-418F7559D84F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -174,6 +176,18 @@ Global
{13EA96FC-CC83-4164-A7C0-4F30ED797460}.Release|x64.Build.0 = Release|Any CPU
{13EA96FC-CC83-4164-A7C0-4F30ED797460}.Release|x86.ActiveCfg = Release|Any CPU
{13EA96FC-CC83-4164-A7C0-4F30ED797460}.Release|x86.Build.0 = Release|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Debug|x64.Build.0 = Debug|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Debug|x86.Build.0 = Debug|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Release|x64.ActiveCfg = Release|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Release|x64.Build.0 = Release|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Release|x86.ActiveCfg = Release|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
[3/5] ignite git commit: IGNITE-3199 .NET: Add ASP.NET Session-State
Store Provider
Posted by pt...@apache.org.
IGNITE-3199 .NET: Add ASP.NET Session-State Store Provider
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/799f1909
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/799f1909
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/799f1909
Branch: refs/heads/master
Commit: 799f1909cea96037a38eee1b4ecb21fab737d092
Parents: 886ed64
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri Sep 16 17:50:24 2016 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Sep 16 17:50:24 2016 +0300
----------------------------------------------------------------------
.../ignite/internal/binary/BinaryContext.java | 5 +
.../platform/PlatformConfigurationEx.java | 7 +
.../platform/PlatformContextImpl.java | 3 -
.../processors/platform/PlatformProcessor.java | 10 +-
.../platform/PlatformProcessorImpl.java | 72 ++-
.../platform/cache/PlatformCache.java | 114 +++-
.../platform/cache/PlatformCacheExtension.java | 47 ++
.../cpp/PlatformCppConfigurationEx.java | 7 +
.../dotnet/PlatformDotNetConfigurationEx.java | 9 +
.../PlatformDotNetSessionCacheExtension.java | 144 +++++
.../websession/PlatformDotNetSessionData.java | 260 +++++++++
.../PlatformDotNetSessionLockProcessor.java | 84 +++
.../PlatformDotNetSessionLockResult.java | 106 ++++
...tformDotNetSessionSetAndUnlockProcessor.java | 179 +++++++
.../Apache.Ignite.AspNet.Tests.csproj | 77 +++
.../Apache.Ignite.AspNet.Tests.snk | Bin 0 -> 596 bytes
.../Apache.Ignite.AspNet.Tests/App.config | 72 +++
.../ExpiryCacheHolderTest.cs | 492 +++++++++++++++++
.../IgniteOutputCacheProviderTest.cs | 172 ++++++
.../IgniteSessionStateItemCollectionTest.cs | 267 ++++++++++
.../IgniteSessionStateStoreDataTest.cs | 117 ++++
.../IgniteSessionStateStoreProviderTest.cs | 425 +++++++++++++++
.../Properties/AssemblyInfo.cs | 42 ++
.../Apache.Ignite.AspNet.Tests/packages.config | 22 +
.../Apache.Ignite.AspNet.csproj | 6 +
.../Apache.Ignite.AspNet.ruleset | 3 +
.../IgniteOutputCacheProvider.cs | 120 +----
.../IgniteSessionStateStoreProvider.cs | 494 +++++++++++++++++
.../Apache.Ignite.AspNet/Impl/ConfigUtil.cs | 109 ++++
.../Impl/ExpiryCacheHolder.cs | 113 ++++
.../Impl/IgniteSessionStateItemCollection.cs | 534 +++++++++++++++++++
.../Impl/IgniteSessionStateStoreData.cs | 116 ++++
.../Impl/SessionStateLockResult.cs | 91 ++++
.../Properties/AssemblyInfo.cs | 5 +-
.../Apache.Ignite.Core.Tests.csproj | 6 -
.../AspNet/IgniteOutputCacheProviderTest.cs | 172 ------
.../Apache.Ignite.Core.Tests/TestUtils.cs | 1 -
.../Apache.Ignite.Core/Impl/Cache/CacheImpl.cs | 15 +
.../Apache.Ignite.Core/Impl/Cache/CacheOp.cs | 3 +-
.../Impl/Cache/ICacheInternal.cs | 14 +
.../Impl/Unmanaged/UnmanagedCallbacks.cs | 1 -
.../Properties/AssemblyInfo.cs | 1 +
modules/platforms/dotnet/Apache.Ignite.sln | 14 +
43 files changed, 4223 insertions(+), 328 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
index 0d66970..c468a4d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
@@ -76,6 +76,8 @@ import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaFileUnlockProcess
import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaUpdatePropertiesProcessor;
import org.apache.ignite.internal.processors.igfs.meta.IgfsMetaUpdateTimesProcessor;
import org.apache.ignite.internal.processors.platform.PlatformJavaObjectFactoryProxy;
+import org.apache.ignite.internal.processors.platform.websession.PlatformDotNetSessionData;
+import org.apache.ignite.internal.processors.platform.websession.PlatformDotNetSessionLockResult;
import org.apache.ignite.internal.util.lang.GridMapEntry;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.T2;
@@ -321,6 +323,9 @@ public class BinaryContext {
registerPredefinedType(BinaryMetadata.class, 0);
registerPredefinedType(BinaryEnumObjectImpl.class, 0);
+ registerPredefinedType(PlatformDotNetSessionData.class, 0);
+ registerPredefinedType(PlatformDotNetSessionLockResult.class, 0);
+
// IDs range [200..1000] is used by Ignite internal APIs.
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformConfigurationEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformConfigurationEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformConfigurationEx.java
index 66eff8b..b7c8895 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformConfigurationEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformConfigurationEx.java
@@ -17,8 +17,10 @@
package org.apache.ignite.internal.processors.platform;
+import org.apache.ignite.internal.processors.platform.cache.PlatformCacheExtension;
import org.apache.ignite.internal.processors.platform.callback.PlatformCallbackGateway;
import org.apache.ignite.internal.processors.platform.memory.PlatformMemoryManagerImpl;
+import org.jetbrains.annotations.Nullable;
import java.util.Collection;
@@ -45,4 +47,9 @@ public interface PlatformConfigurationEx {
* @return Warnings to be displayed on grid start.
*/
public Collection<String> warnings();
+
+ /**
+ * @return Available cache extensions.
+ */
+ @Nullable public Collection<PlatformCacheExtension> cacheExtensions();
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
index d544fff..e7fdb0a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
@@ -118,9 +118,6 @@ public class PlatformContextImpl implements PlatformContext {
/** Platform name. */
private final String platform;
- /**
- * Static initializer.
- */
static {
Set<Integer> evtTyps0 = new HashSet<>();
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessor.java
index fc42b68..f0201ef 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessor.java
@@ -19,7 +19,6 @@ package org.apache.ignite.internal.processors.platform;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.IgniteException;
import org.apache.ignite.internal.processors.GridProcessor;
import org.apache.ignite.internal.processors.platform.cache.store.PlatformCacheStore;
import org.jetbrains.annotations.Nullable;
@@ -203,9 +202,8 @@ public interface PlatformProcessor extends GridProcessor {
* @param initVal Initial value.
* @param create Create flag.
* @return Platform atomic long.
- * @throws IgniteException
*/
- public PlatformTarget atomicLong(String name, long initVal, boolean create) throws IgniteException;
+ public PlatformTarget atomicLong(String name, long initVal, boolean create);
/**
* Get or create AtomicSequence.
@@ -213,9 +211,8 @@ public interface PlatformProcessor extends GridProcessor {
* @param initVal Initial value.
* @param create Create flag.
* @return Platform atomic long.
- * @throws IgniteException
*/
- public PlatformTarget atomicSequence(String name, long initVal, boolean create) throws IgniteException;
+ public PlatformTarget atomicSequence(String name, long initVal, boolean create);
/**
* Get or create AtomicReference.
@@ -223,9 +220,8 @@ public interface PlatformProcessor extends GridProcessor {
* @param memPtr Pointer to a stream with initial value. 0 for null initial value.
* @param create Create flag.
* @return Platform atomic long.
- * @throws IgniteException
*/
- public PlatformTarget atomicReference(String name, long memPtr, boolean create) throws IgniteException;
+ public PlatformTarget atomicReference(String name, long memPtr, boolean create);
/**
* Gets the configuration of the current Ignite instance.
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
index 8c9e205..b364c4a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
@@ -35,6 +35,7 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheProxy;
import org.apache.ignite.internal.processors.datastreamer.DataStreamerImpl;
import org.apache.ignite.internal.processors.datastructures.GridCacheAtomicLongImpl;
import org.apache.ignite.internal.processors.platform.cache.PlatformCache;
+import org.apache.ignite.internal.processors.platform.cache.PlatformCacheExtension;
import org.apache.ignite.internal.processors.platform.cache.affinity.PlatformAffinity;
import org.apache.ignite.internal.processors.platform.cache.store.PlatformCacheStore;
import org.apache.ignite.internal.processors.platform.cluster.PlatformClusterGroup;
@@ -59,6 +60,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReadWriteLock;
@@ -79,6 +82,7 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
private final ReadWriteLock storeLock = new ReentrantReadWriteLock();
/** Logger. */
+ @SuppressWarnings("FieldCanBeLocal")
private final IgniteLogger log;
/** Context. */
@@ -93,6 +97,9 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
/** Whether processor if stopped (or stopping). */
private volatile boolean stopped;
+ /** Cache extensions. */
+ private final PlatformCacheExtension[] cacheExts;
+
/**
* Constructor.
*
@@ -118,6 +125,9 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
}
platformCtx = new PlatformContextImpl(ctx, interopCfg.gate(), interopCfg.memory(), interopCfg.platform());
+
+ // Initialize cache extensions (if any).
+ cacheExts = prepareCacheExtensions(interopCfg.cacheExtensions());
}
/** {@inheritDoc} */
@@ -207,7 +217,7 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
if (cache == null)
throw new IllegalArgumentException("Cache doesn't exist: " + name);
- return new PlatformCache(platformCtx, cache.keepBinary(), false);
+ return createPlatformCache(cache);
}
/** {@inheritDoc} */
@@ -216,7 +226,7 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
assert cache != null;
- return new PlatformCache(platformCtx, cache.keepBinary(), false);
+ return createPlatformCache(cache);
}
/** {@inheritDoc} */
@@ -225,7 +235,7 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
assert cache != null;
- return new PlatformCache(platformCtx, cache.keepBinary(), false);
+ return createPlatformCache(cache);
}
/** {@inheritDoc} */
@@ -237,7 +247,7 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
? (IgniteCacheProxy)ctx.grid().createCache(cfg, PlatformConfigurationUtils.readNearConfiguration(reader))
: (IgniteCacheProxy)ctx.grid().createCache(cfg);
- return new PlatformCache(platformCtx, cache.keepBinary(), false);
+ return createPlatformCache(cache);
}
/** {@inheritDoc} */
@@ -250,7 +260,7 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
PlatformConfigurationUtils.readNearConfiguration(reader))
: (IgniteCacheProxy)ctx.grid().getOrCreateCache(cfg);
- return new PlatformCache(platformCtx, cache.keepBinary(), false);
+ return createPlatformCache(cache);
}
/** {@inheritDoc} */
@@ -404,7 +414,7 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
IgniteCacheProxy cache = (IgniteCacheProxy)ctx.grid().createNearCache(cacheName, cfg);
- return new PlatformCache(platformCtx, cache.keepBinary(), false);
+ return createPlatformCache(cache);
}
/** {@inheritDoc} */
@@ -413,7 +423,14 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
IgniteCacheProxy cache = (IgniteCacheProxy)ctx.grid().getOrCreateNearCache(cacheName, cfg);
- return new PlatformCache(platformCtx, cache.keepBinary(), false);
+ return createPlatformCache(cache);
+ }
+
+ /**
+ * Creates new platform cache.
+ */
+ private PlatformTarget createPlatformCache(IgniteCacheProxy cache) {
+ return new PlatformCache(platformCtx, cache, false, cacheExts);
}
/**
@@ -447,6 +464,47 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
}
/**
+ * Prepare cache extensions.
+ *
+ * @param cacheExts Original extensions.
+ * @return Prepared extensions.
+ */
+ private static PlatformCacheExtension[] prepareCacheExtensions(Collection<PlatformCacheExtension> cacheExts) {
+ if (!F.isEmpty(cacheExts)) {
+ int maxExtId = 0;
+
+ Map<Integer, PlatformCacheExtension> idToExt = new HashMap<>();
+
+ for (PlatformCacheExtension cacheExt : cacheExts) {
+ if (cacheExt == null)
+ throw new IgniteException("Platform cache extension cannot be null.");
+
+ if (cacheExt.id() < 0)
+ throw new IgniteException("Platform cache extension ID cannot be negative: " + cacheExt);
+
+ PlatformCacheExtension oldCacheExt = idToExt.put(cacheExt.id(), cacheExt);
+
+ if (oldCacheExt != null)
+ throw new IgniteException("Platform cache extensions cannot have the same ID [" +
+ "id=" + cacheExt.id() + ", first=" + oldCacheExt + ", second=" + cacheExt + ']');
+
+ if (cacheExt.id() > maxExtId)
+ maxExtId = cacheExt.id();
+ }
+
+ PlatformCacheExtension[] res = new PlatformCacheExtension[maxExtId + 1];
+
+ for (PlatformCacheExtension cacheExt : cacheExts)
+ res[cacheExt.id()]= cacheExt;
+
+ return res;
+ }
+ else
+ //noinspection ZeroLengthArrayAllocation
+ return new PlatformCacheExtension[0];
+ }
+
+ /**
* Store and manager pair.
*/
private static class StoreInfo {
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCache.java
index a7b6e41..a1f8da9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCache.java
@@ -19,6 +19,8 @@ package org.apache.ignite.internal.processors.platform.cache;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.binary.BinaryRawReader;
import org.apache.ignite.cache.CacheEntryProcessor;
import org.apache.ignite.cache.CacheMetrics;
import org.apache.ignite.cache.CachePartialUpdateException;
@@ -28,7 +30,7 @@ import org.apache.ignite.cache.query.ScanQuery;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.cache.query.SqlQuery;
import org.apache.ignite.cache.query.TextQuery;
-import org.apache.ignite.configuration.*;
+import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.binary.BinaryRawReaderEx;
import org.apache.ignite.internal.binary.BinaryRawWriterEx;
@@ -52,12 +54,13 @@ import org.apache.ignite.internal.processors.platform.utils.PlatformWriterClosur
import org.apache.ignite.internal.util.GridConcurrentFactory;
import org.apache.ignite.internal.util.future.IgniteFutureImpl;
import org.apache.ignite.internal.util.typedef.C1;
-import org.apache.ignite.lang.IgniteBiInClosure;
import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.lang.IgniteBiInClosure;
import org.apache.ignite.lang.IgniteFuture;
import org.jetbrains.annotations.Nullable;
import javax.cache.Cache;
+import javax.cache.CacheException;
import javax.cache.expiry.Duration;
import javax.cache.expiry.ExpiryPolicy;
import javax.cache.integration.CompletionListener;
@@ -193,20 +196,26 @@ public class PlatformCache extends PlatformAbstractTarget {
/** */
public static final int OP_LOAD_ALL = 40;
- /** Underlying JCache. */
+ /** */
+ public static final int OP_EXTENSION = 41;
+
+ /** Underlying JCache in binary mode. */
private final IgniteCacheProxy cache;
+ /** Initial JCache (not in binary mode). */
+ private final IgniteCache rawCache;
+
/** Whether this cache is created with "keepBinary" flag on the other side. */
private final boolean keepBinary;
/** */
- private static final GetAllWriter WRITER_GET_ALL = new GetAllWriter();
+ private static final PlatformFutureUtils.Writer WRITER_GET_ALL = new GetAllWriter();
/** */
- private static final EntryProcessorInvokeWriter WRITER_INVOKE = new EntryProcessorInvokeWriter();
+ private static final PlatformFutureUtils.Writer WRITER_INVOKE = new EntryProcessorInvokeWriter();
/** */
- private static final EntryProcessorInvokeAllWriter WRITER_INVOKE_ALL = new EntryProcessorInvokeAllWriter();
+ private static final PlatformFutureUtils.Writer WRITER_INVOKE_ALL = new EntryProcessorInvokeAllWriter();
/** Map with currently active locks. */
private final ConcurrentMap<Long, Lock> lockMap = GridConcurrentFactory.newMap();
@@ -214,6 +223,9 @@ public class PlatformCache extends PlatformAbstractTarget {
/** Lock ID sequence. */
private static final AtomicLong LOCK_ID_GEN = new AtomicLong();
+ /** Extensions. */
+ private final PlatformCacheExtension[] exts;
+
/**
* Constructor.
*
@@ -222,10 +234,29 @@ public class PlatformCache extends PlatformAbstractTarget {
* @param keepBinary Keep binary flag.
*/
public PlatformCache(PlatformContext platformCtx, IgniteCache cache, boolean keepBinary) {
+ this(platformCtx, cache, keepBinary, new PlatformCacheExtension[0]);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param platformCtx Context.
+ * @param cache Underlying cache.
+ * @param keepBinary Keep binary flag.
+ * @param exts Extensions.
+ */
+ public PlatformCache(PlatformContext platformCtx, IgniteCache cache, boolean keepBinary,
+ PlatformCacheExtension[] exts) {
super(platformCtx);
- this.cache = (IgniteCacheProxy)cache;
+ assert cache != null;
+ assert exts != null;
+
+ rawCache = cache;
+
+ this.cache = (IgniteCacheProxy)cache.withKeepBinary();
this.keepBinary = keepBinary;
+ this.exts = exts;
}
/**
@@ -237,7 +268,7 @@ public class PlatformCache extends PlatformAbstractTarget {
if (cache.delegate().skipStore())
return this;
- return new PlatformCache(platformCtx, cache.withSkipStore(), keepBinary);
+ return copy(rawCache.withSkipStore(), keepBinary);
}
/**
@@ -249,7 +280,7 @@ public class PlatformCache extends PlatformAbstractTarget {
if (keepBinary)
return this;
- return new PlatformCache(platformCtx, cache.withKeepBinary(), true);
+ return copy(rawCache.withKeepBinary(), true);
}
/**
@@ -261,9 +292,9 @@ public class PlatformCache extends PlatformAbstractTarget {
* @return Cache.
*/
public PlatformCache withExpiryPolicy(final long create, final long update, final long access) {
- IgniteCache cache0 = cache.withExpiryPolicy(new InteropExpiryPolicy(create, update, access));
+ IgniteCache cache0 = rawCache.withExpiryPolicy(new InteropExpiryPolicy(create, update, access));
- return new PlatformCache(platformCtx, cache0, keepBinary);
+ return copy(cache0, keepBinary);
}
/**
@@ -275,7 +306,7 @@ public class PlatformCache extends PlatformAbstractTarget {
if (cache.isAsync())
return this;
- return new PlatformCache(platformCtx, (IgniteCache)cache.withAsync(), keepBinary);
+ return copy(rawCache.withAsync(), keepBinary);
}
/**
@@ -289,11 +320,19 @@ public class PlatformCache extends PlatformAbstractTarget {
if (opCtx != null && opCtx.noRetries())
return this;
- return new PlatformCache(platformCtx, cache.withNoRetries(), keepBinary);
+ return copy(rawCache.withNoRetries(), keepBinary);
+ }
+
+ /**
+ * @return Raw cache.
+ */
+ public IgniteCache rawCache() {
+ return rawCache;
}
/** {@inheritDoc} */
- @Override protected long processInStreamOutLong(int type, BinaryRawReaderEx reader, PlatformMemory mem) throws IgniteCheckedException {
+ @Override protected long processInStreamOutLong(int type, BinaryRawReaderEx reader, PlatformMemory mem)
+ throws IgniteCheckedException {
try {
switch (type) {
case OP_PUT:
@@ -452,6 +491,11 @@ public class PlatformCache extends PlatformAbstractTarget {
case OP_LOCK_ALL:
return registerLock(cache.lockAll(PlatformUtils.readCollection(reader)));
+
+ case OP_EXTENSION:
+ PlatformCacheExtension ext = extension(reader.readInt());
+
+ return ext.processInOutStreamLong(this, reader.readInt(), reader, mem);
}
}
catch (Exception e) {
@@ -474,14 +518,14 @@ public class PlatformCache extends PlatformAbstractTarget {
/**
* Writes the result to reused stream, if any.
*/
- private long writeResult(PlatformMemory mem, Object obj) {
+ public long writeResult(PlatformMemory mem, Object obj) {
return writeResult(mem, obj, null);
}
/**
* Writes the result to reused stream, if any.
*/
- private long writeResult(PlatformMemory mem, Object obj, PlatformWriterClosure clo) {
+ public long writeResult(PlatformMemory mem, Object obj, PlatformWriterClosure clo) {
if (obj == null)
return FALSE;
@@ -665,7 +709,7 @@ public class PlatformCache extends PlatformAbstractTarget {
return new PlatformCachePartialUpdateException((CachePartialUpdateCheckedException)e, platformCtx, keepBinary);
if (e.getCause() instanceof EntryProcessorException)
- return (EntryProcessorException) e.getCause();
+ return (Exception)e.getCause();
return super.convertException(e);
}
@@ -743,7 +787,7 @@ public class PlatformCache extends PlatformAbstractTarget {
* Clears the contents of the cache, without notifying listeners or CacheWriters.
*
* @throws IllegalStateException if the cache is closed.
- * @throws javax.cache.CacheException if there is a problem during the clear
+ * @throws CacheException if there is a problem during the clear
*/
public void clear() throws IgniteCheckedException {
cache.clear();
@@ -752,7 +796,7 @@ public class PlatformCache extends PlatformAbstractTarget {
/**
* Removes all entries.
*
- * @throws org.apache.ignite.IgniteCheckedException In case of error.
+ * @throws IgniteCheckedException In case of error.
*/
public void removeAll() throws IgniteCheckedException {
cache.removeAll();
@@ -969,7 +1013,7 @@ public class PlatformCache extends PlatformAbstractTarget {
/**
* Reads text query.
*/
- private Query readTextQuery(BinaryRawReaderEx reader) {
+ private Query readTextQuery(BinaryRawReader reader) {
boolean loc = reader.readBoolean();
String txt = reader.readString();
String typ = reader.readString();
@@ -1004,6 +1048,34 @@ public class PlatformCache extends PlatformAbstractTarget {
}
/**
+ * Clones this instance.
+ *
+ * @param cache Cache.
+ * @param keepBinary Keep binary flag.
+ * @return Cloned instance.
+ */
+ private PlatformCache copy(IgniteCache cache, boolean keepBinary) {
+ return new PlatformCache(platformCtx, cache, keepBinary, exts);
+ }
+
+ /**
+ * Get extension by ID.
+ *
+ * @param id ID.
+ * @return Extension.
+ */
+ private PlatformCacheExtension extension(int id) {
+ if (exts != null && id < exts.length) {
+ PlatformCacheExtension ext = exts[id];
+
+ if (ext != null)
+ return ext;
+ }
+
+ throw new IgniteException("Platform cache extension is not registered [id=" + id + ']');
+ }
+
+ /**
* Writes error with EntryProcessorException cause.
*/
private static class GetAllWriter implements PlatformFutureUtils.Writer {
@@ -1088,7 +1160,7 @@ public class PlatformCache extends PlatformAbstractTarget {
* @param update Expiry for update.
* @param access Expiry for access.
*/
- public InteropExpiryPolicy(long create, long update, long access) {
+ private InteropExpiryPolicy(long create, long update, long access) {
this.create = convert(create);
this.update = convert(update);
this.access = convert(access);
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheExtension.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheExtension.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheExtension.java
new file mode 100644
index 0000000..5d2040c
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCacheExtension.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.internal.processors.platform.cache;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.binary.BinaryRawReaderEx;
+import org.apache.ignite.internal.processors.platform.memory.PlatformMemory;
+
+/**
+ * Platform cache extension. Decouples other modules from cache.
+ */
+public interface PlatformCacheExtension {
+ /**
+ * Get extension ID. Must be unique among all extensions.
+ *
+ * @return Extension ID.
+ */
+ public int id();
+
+ /**
+ * Invokes in-out operation with long return type.
+ *
+ * @param target Target cache.
+ * @param type Operation type.
+ * @param reader Reader.
+ * @param mem Memory.
+ * @return Result.
+ * @throws IgniteCheckedException If failed.
+ */
+ long processInOutStreamLong(PlatformCache target, int type, BinaryRawReaderEx reader, PlatformMemory mem)
+ throws IgniteCheckedException;
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cpp/PlatformCppConfigurationEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cpp/PlatformCppConfigurationEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cpp/PlatformCppConfigurationEx.java
index ea11ce9..931a18e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cpp/PlatformCppConfigurationEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cpp/PlatformCppConfigurationEx.java
@@ -18,10 +18,12 @@
package org.apache.ignite.internal.processors.platform.cpp;
import org.apache.ignite.internal.processors.platform.PlatformConfigurationEx;
+import org.apache.ignite.internal.processors.platform.cache.PlatformCacheExtension;
import org.apache.ignite.internal.processors.platform.callback.PlatformCallbackGateway;
import org.apache.ignite.internal.processors.platform.memory.PlatformMemoryManagerImpl;
import org.apache.ignite.internal.processors.platform.utils.PlatformUtils;
import org.apache.ignite.platform.cpp.PlatformCppConfiguration;
+import org.jetbrains.annotations.Nullable;
import java.util.Collection;
@@ -73,6 +75,11 @@ public class PlatformCppConfigurationEx extends PlatformCppConfiguration impleme
return warns;
}
+ /** {@inheritDoc} */
+ @Override @Nullable public Collection<PlatformCacheExtension> cacheExtensions() {
+ return null;
+ }
+
/**
* @param warnings Warnings.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationEx.java
index eaf0997..78fb755 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationEx.java
@@ -18,12 +18,16 @@
package org.apache.ignite.internal.processors.platform.dotnet;
import org.apache.ignite.internal.processors.platform.PlatformConfigurationEx;
+import org.apache.ignite.internal.processors.platform.cache.PlatformCacheExtension;
import org.apache.ignite.internal.processors.platform.callback.PlatformCallbackGateway;
import org.apache.ignite.internal.processors.platform.memory.PlatformMemoryManagerImpl;
import org.apache.ignite.internal.processors.platform.utils.PlatformUtils;
+import org.apache.ignite.internal.processors.platform.websession.PlatformDotNetSessionCacheExtension;
import org.apache.ignite.platform.dotnet.PlatformDotNetConfiguration;
+import org.jetbrains.annotations.Nullable;
import java.util.Collection;
+import java.util.Collections;
/**
* Extended .Net configuration.
@@ -73,6 +77,11 @@ public class PlatformDotNetConfigurationEx extends PlatformDotNetConfiguration i
return warnings;
}
+ /** {@inheritDoc} */
+ @Nullable @Override public Collection<PlatformCacheExtension> cacheExtensions() {
+ return Collections.<PlatformCacheExtension>singleton(new PlatformDotNetSessionCacheExtension());
+ }
+
/**
* @param warnings Warnings.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionCacheExtension.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionCacheExtension.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionCacheExtension.java
new file mode 100644
index 0000000..aa5f69f
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionCacheExtension.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.internal.processors.platform.websession;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.binary.BinaryRawReaderEx;
+import org.apache.ignite.internal.binary.BinaryRawWriterEx;
+import org.apache.ignite.internal.processors.platform.cache.PlatformCache;
+import org.apache.ignite.internal.processors.platform.cache.PlatformCacheExtension;
+import org.apache.ignite.internal.processors.platform.memory.PlatformMemory;
+import org.apache.ignite.internal.processors.platform.utils.PlatformWriterClosure;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+import java.sql.Timestamp;
+import java.util.UUID;
+
+/**
+ * Custom entry processor invoker.
+ */
+public class PlatformDotNetSessionCacheExtension implements PlatformCacheExtension {
+ /** Extension ID. */
+ private static final int EXT_ID = 0;
+
+ /** Operation: session lock. */
+ private static final int OP_LOCK = 1;
+
+ /** Operation: session set/unlock. */
+ private static final int OP_SET_AND_UNLOCK = 2;
+
+ /** Operation: session get without lock. */
+ private static final int OP_GET = 3;
+
+ /** Operation: session put without lock. */
+ private static final int OP_PUT = 4;
+
+ /** Operation: session remove without lock. */
+ private static final int OP_REMOVE = 5;
+
+ /** {@inheritDoc} */
+ @Override public int id() {
+ return EXT_ID;
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public long processInOutStreamLong(PlatformCache target, int type, BinaryRawReaderEx reader,
+ PlatformMemory mem) throws IgniteCheckedException {
+ switch (type) {
+ case OP_LOCK: {
+ String key = reader.readString();
+ UUID lockNodeId = reader.readUuid();
+ long lockId = reader.readLong();
+ Timestamp lockTime = reader.readTimestamp();
+
+ final PlatformDotNetSessionLockResult res = (PlatformDotNetSessionLockResult)
+ target.rawCache().invoke(key, new PlatformDotNetSessionLockProcessor(lockNodeId, lockId, lockTime));
+
+ return target.writeResult(mem, res, new PlatformWriterClosure() {
+ @Override public void write(BinaryRawWriterEx writer, Object val) {
+ res.writeBinary(writer);
+ }
+ });
+ }
+
+ case OP_SET_AND_UNLOCK: {
+ String key = reader.readString();
+
+ PlatformDotNetSessionSetAndUnlockProcessor proc;
+
+ if (reader.readBoolean()) {
+ PlatformDotNetSessionData data = new PlatformDotNetSessionData();
+
+ data.readBinary(reader);
+
+ proc = new PlatformDotNetSessionSetAndUnlockProcessor(data);
+ }
+ else {
+ UUID lockNodeId = reader.readUuid();
+ long lockId = reader.readLong();
+
+ proc = new PlatformDotNetSessionSetAndUnlockProcessor(lockNodeId, lockId);
+ }
+
+ target.rawCache().invoke(key, proc);
+
+ return target.writeResult(mem, null);
+ }
+
+ case OP_GET: {
+ String key = reader.readString();
+
+ final PlatformDotNetSessionData data = (PlatformDotNetSessionData)target.rawCache().get(key);
+
+ return target.writeResult(mem, data, new PlatformWriterClosure() {
+ @Override public void write(BinaryRawWriterEx writer, Object val) {
+ data.writeBinary(writer);
+ }
+ });
+ }
+
+ case OP_PUT: {
+ String key = reader.readString();
+
+ PlatformDotNetSessionData data = new PlatformDotNetSessionData();
+
+ data.readBinary(reader);
+
+ target.rawCache().put(key, data);
+
+ return target.writeResult(mem, null);
+ }
+
+ case OP_REMOVE: {
+ String key = reader.readString();
+
+ target.rawCache().remove(key);
+
+ return target.writeResult(mem, null);
+ }
+ }
+
+ throw new IgniteCheckedException("Unsupported operation type: " + type);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(PlatformDotNetSessionCacheExtension.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionData.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionData.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionData.java
new file mode 100644
index 0000000..18dbab0
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionData.java
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.internal.processors.platform.websession;
+
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.binary.BinaryRawReader;
+import org.apache.ignite.binary.BinaryRawWriter;
+import org.apache.ignite.binary.BinaryReader;
+import org.apache.ignite.binary.BinaryWriter;
+import org.apache.ignite.binary.Binarylizable;
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+import java.sql.Timestamp;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
+
+/**
+ * Web session state data.
+ */
+@SuppressWarnings({"ReturnOfDateField", "AssignmentToDateFieldFromParameter"})
+public class PlatformDotNetSessionData implements Binarylizable {
+ /** Items. */
+ private Map<String, byte[]> items;
+
+ /** Static objects. */
+ @GridToStringExclude
+ private byte[] staticObjects;
+
+ /** Timeout. */
+ private int timeout;
+
+ /** Lock ID. */
+ private long lockId;
+
+ /** Lock node ID. */
+ private UUID lockNodeId;
+
+ /** Lock time. */
+ private Timestamp lockTime;
+
+ /**
+ * @return Items.
+ */
+ public Map<String, byte[]> items() {
+ return items;
+ }
+
+ /**
+ * @return Static objects.
+ */
+ public byte[] staticObjects() {
+ return staticObjects;
+ }
+
+ /**
+ * @return Timeout.
+ */
+ public int timeout() {
+ return timeout;
+ }
+
+ /**
+ * @return Lock ID.
+ */
+ public long lockId() {
+ return lockId;
+ }
+
+ /**
+ * @return Lock node ID.
+ */
+ public UUID lockNodeId() {
+ return lockNodeId;
+ }
+
+ /**
+ * @return Lock time.
+ */
+ public Timestamp lockTime() {
+ return lockTime;
+ }
+
+ /**
+ * @return {@code True} if locked.
+ */
+ public boolean isLocked() {
+ return lockTime != null;
+ }
+
+ /**
+ * Locks the session state data.
+ *
+ * @param lockNodeId Lock node ID.
+ * @param lockId Lock ID.
+ * @param lockTime Lock time.
+ *
+ * @return Unlocked data copy.
+ */
+ public PlatformDotNetSessionData lock(UUID lockNodeId, long lockId, Timestamp lockTime) {
+ assert !isLocked();
+
+ PlatformDotNetSessionData res = copyWithoutLockInfo();
+
+ res.lockId = lockId;
+ res.lockNodeId = lockNodeId;
+ res.lockTime = lockTime;
+
+ return res;
+ }
+
+ /**
+ * Unlocks the session state data.
+ *
+ * @param lockNodeId Lock node ID.
+ * @param lockId Lock ID.
+ *
+ * @return Unlocked data copy.
+ */
+ public PlatformDotNetSessionData unlock(UUID lockNodeId, long lockId) {
+ assert isLocked();
+
+ if (!this.lockNodeId.equals(lockNodeId))
+ throw new IllegalStateException("Can not unlock session data: lock node id check failed.");
+
+ if (this.lockId != lockId)
+ throw new IllegalStateException("Can not unlock session data: lock id check failed.");
+
+ return copyWithoutLockInfo();
+ }
+
+ /**
+ * Update session state and release the lock.
+ *
+ * @param lockNodeId Lock node ID.
+ * @param lockId Lock ID.
+ * @param items Items.
+ * @param isDiff Diff flag.
+ * @param staticObjects Static objects.
+ * @param timeout Timeout.
+ * @return Result.
+ */
+ public PlatformDotNetSessionData updateAndUnlock(UUID lockNodeId, long lockId, Map<String, byte[]> items,
+ boolean isDiff, byte[] staticObjects, int timeout) {
+ assert items != null;
+
+ PlatformDotNetSessionData res = unlock(lockNodeId, lockId);
+
+ if (!isDiff) {
+ // Not a diff: remove all
+ this.items.clear();
+ }
+
+ for (Map.Entry<String, byte[]> e : items.entrySet()) {
+ String key = e.getKey();
+ byte[] value = e.getValue();
+
+ if (value != null)
+ this.items.put(key, value);
+ else
+ this.items.remove(key); // Null value indicates removed key.
+ }
+
+ res.staticObjects = staticObjects;
+ res.timeout = timeout;
+
+ return res;
+ }
+
+ /**
+ * Gets a copy of this instance with non-lock properties set.
+ *
+ * @return Copied state data.
+ */
+ private PlatformDotNetSessionData copyWithoutLockInfo() {
+ PlatformDotNetSessionData res = new PlatformDotNetSessionData();
+
+ res.staticObjects = staticObjects;
+ res.items = items;
+ res.timeout = timeout;
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
+ BinaryRawWriter raw = writer.rawWriter();
+
+ writeBinary(raw);
+ }
+
+ /**
+ * Writes to a binary writer.
+ *
+ * @param writer Binary writer.
+ */
+ public void writeBinary(BinaryRawWriter writer) {
+ writer.writeInt(items.size());
+
+ for (Map.Entry<String, byte[]> e : items.entrySet()) {
+ writer.writeString(e.getKey());
+ writer.writeByteArray(e.getValue());
+ }
+
+ writer.writeByteArray(staticObjects);
+
+ writer.writeInt(timeout);
+ writer.writeUuid(lockNodeId);
+ writer.writeLong(lockId);
+ writer.writeTimestamp(lockTime);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readBinary(BinaryReader reader) throws BinaryObjectException {
+ BinaryRawReader raw = reader.rawReader();
+
+ readBinary(raw);
+ }
+
+ /**
+ * Reads from a binary reader.
+ *
+ * @param reader Reader.
+ */
+ public void readBinary(BinaryRawReader reader) {
+ items = new TreeMap<>();
+ int count = reader.readInt();
+
+ for (int i = 0; i < count; i++)
+ items.put(reader.readString(), reader.readByteArray());
+
+ staticObjects = reader.readByteArray();
+
+ timeout = reader.readInt();
+ lockNodeId = reader.readUuid();
+ lockId = reader.readLong();
+ lockTime = reader.readTimestamp();
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(PlatformDotNetSessionData.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionLockProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionLockProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionLockProcessor.java
new file mode 100644
index 0000000..0e51448
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionLockProcessor.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.internal.processors.platform.websession;
+
+import org.apache.ignite.cache.CacheEntryProcessor;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+import javax.cache.processor.EntryProcessorException;
+import javax.cache.processor.MutableEntry;
+import java.sql.Timestamp;
+import java.util.UUID;
+
+/**
+ * Entry processor that locks web session data.
+ */
+@SuppressWarnings("AssignmentToDateFieldFromParameter")
+public class PlatformDotNetSessionLockProcessor implements CacheEntryProcessor<String, PlatformDotNetSessionData, Object> {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** Lock node id. */
+ private UUID lockNodeId;
+
+ /** Lock id. */
+ private long lockId;
+
+ /** Lock time. */
+ private Timestamp lockTime;
+
+ /**
+ * Ctor.
+ *
+ * @param lockNodeId Lock node id.
+ * @param lockId Lock id.
+ * @param lockTime Lock time.
+ */
+ public PlatformDotNetSessionLockProcessor(UUID lockNodeId, long lockId, Timestamp lockTime) {
+ this.lockNodeId = lockNodeId;
+ this.lockId = lockId;
+ this.lockTime = lockTime;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object process(MutableEntry<String, PlatformDotNetSessionData> entry, Object... args)
+ throws EntryProcessorException {
+ if (!entry.exists())
+ return null;
+
+ PlatformDotNetSessionData data = entry.getValue();
+
+ assert data != null;
+
+ if (data.isLocked())
+ return new PlatformDotNetSessionLockResult(false, null, data.lockTime(), data.lockId());
+
+ // Not locked: lock and return result
+ data = data.lock(lockNodeId, lockId, lockTime);
+
+ // Apply.
+ entry.setValue(data);
+
+ return new PlatformDotNetSessionLockResult(true, data, null, data.lockId());
+ }
+
+ /** {@inheritDoc */
+ @Override public String toString() {
+ return S.toString(PlatformDotNetSessionLockProcessor.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionLockResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionLockResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionLockResult.java
new file mode 100644
index 0000000..cfa355c
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionLockResult.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.internal.processors.platform.websession;
+
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.binary.BinaryRawReader;
+import org.apache.ignite.binary.BinaryRawWriter;
+import org.apache.ignite.binary.BinaryReader;
+import org.apache.ignite.binary.BinaryWriter;
+import org.apache.ignite.binary.Binarylizable;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+import java.sql.Timestamp;
+
+/**
+ * Result of the {@link PlatformDotNetSessionLockProcessor} execution.
+ */
+@SuppressWarnings({"AssignmentToDateFieldFromParameter", "ReturnOfDateField"})
+public class PlatformDotNetSessionLockResult implements Binarylizable {
+ /** Success flag. */
+ private boolean success;
+
+ /** Data. */
+ private PlatformDotNetSessionData data;
+
+ /** Lock time. */
+ private Timestamp lockTime;
+
+ /** Lock id. */
+ private long lockId;
+
+ /**
+ * Constructor.
+ *
+ * @param success Success flag.
+ * @param data Session data.
+ * @param lockTime Lock time.
+ */
+ public PlatformDotNetSessionLockResult(boolean success, PlatformDotNetSessionData data, Timestamp lockTime,
+ long lockId) {
+ assert success ^ (data == null);
+
+ this.success = success;
+ this.data = data;
+ this.lockTime = lockTime;
+ this.lockId = lockId;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
+ BinaryRawWriter raw = writer.rawWriter();
+
+ writeBinary(raw);
+ }
+
+ /**
+ * Writes to a binary writer.
+ *
+ * @param writer Binary writer.
+ */
+ public void writeBinary(BinaryRawWriter writer) {
+ writer.writeBoolean(success);
+
+ if (success)
+ data.writeBinary(writer);
+
+ writer.writeTimestamp(lockTime);
+ writer.writeLong(lockId);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readBinary(BinaryReader reader) throws BinaryObjectException {
+ BinaryRawReader raw = reader.rawReader();
+
+ success = raw.readBoolean();
+
+ if (success) {
+ data = new PlatformDotNetSessionData();
+
+ data.readBinary(raw);
+ }
+
+ lockTime = raw.readTimestamp();
+ lockId = raw.readLong();
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(PlatformDotNetSessionLockResult.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionSetAndUnlockProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionSetAndUnlockProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionSetAndUnlockProcessor.java
new file mode 100644
index 0000000..9015c5c
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionSetAndUnlockProcessor.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.internal.processors.platform.websession;
+
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.binary.BinaryRawReader;
+import org.apache.ignite.binary.BinaryRawWriter;
+import org.apache.ignite.binary.BinaryReader;
+import org.apache.ignite.binary.BinaryWriter;
+import org.apache.ignite.binary.Binarylizable;
+import org.apache.ignite.cache.CacheEntryProcessor;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+import javax.cache.processor.EntryProcessorException;
+import javax.cache.processor.MutableEntry;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
+
+/**
+ * Processor to unlock and optionally update the session.
+ */
+public class PlatformDotNetSessionSetAndUnlockProcessor implements
+ CacheEntryProcessor<String, PlatformDotNetSessionData, Void>, Binarylizable {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** Lock node ID. */
+ private UUID lockNodeId;
+
+ /** Lock ID. */
+ private long lockId;
+
+ /** Update flag. */
+ private boolean update;
+
+ /** Data. */
+ private Map<String, byte[]> items;
+
+ /** Whether items collection represents a diff. */
+ private boolean isDiff;
+
+ /** Static data. */
+ private byte[] staticData;
+
+ /** Timeout. */
+ private int timeout;
+
+ /**
+ * Constructor for unlock.
+ *
+ * @param lockNodeId Lock node ID.
+ * @param lockId Lock ID.
+ */
+ public PlatformDotNetSessionSetAndUnlockProcessor(UUID lockNodeId, long lockId) {
+ this(lockNodeId, lockId, false, null, false, null, 0);
+ }
+
+ /**
+ * Constructor for unlock/update.
+ *
+ * @param data Data.
+ */
+ public PlatformDotNetSessionSetAndUnlockProcessor(PlatformDotNetSessionData data) {
+ this(data.lockNodeId(), data.lockId(), true, data.items(), true, data.staticObjects(), data.timeout());
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param lockNodeId Lock node ID.
+ * @param lockId Lock ID.
+ * @param update Whether to perform update.
+ * @param items Items.
+ * @param isDiff Whether items is a diff.
+ * @param staticData Static data.
+ * @param timeout Timeout.
+ */
+ public PlatformDotNetSessionSetAndUnlockProcessor(UUID lockNodeId, long lockId, boolean update,
+ Map<String, byte[]> items, boolean isDiff, byte[] staticData, int timeout) {
+ this.lockNodeId = lockNodeId;
+ this.lockId = lockId;
+ this.update = update;
+ this.items = items;
+ this.isDiff = isDiff;
+ this.staticData = staticData;
+ this.timeout = timeout;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Void process(MutableEntry<String, PlatformDotNetSessionData> entry, Object... args)
+ throws EntryProcessorException {
+ assert entry.exists();
+
+ PlatformDotNetSessionData data = entry.getValue();
+
+ assert data != null;
+
+ // Unlock and update.
+ data = update
+ ? data.updateAndUnlock(lockNodeId, lockId, items, isDiff, staticData, timeout)
+ : data.unlock(lockNodeId, lockId);
+
+ // Apply.
+ entry.setValue(data);
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
+ BinaryRawWriter raw = writer.rawWriter();
+
+ raw.writeUuid(lockNodeId);
+ raw.writeLong(lockId);
+ raw.writeBoolean(update);
+
+ if (update) {
+ raw.writeBoolean(isDiff);
+ raw.writeByteArray(staticData);
+ raw.writeInt(timeout);
+
+ if (items != null) {
+ raw.writeInt(items.size());
+
+ for (Map.Entry<String, byte[]> e : items.entrySet()) {
+ raw.writeString(e.getKey());
+ raw.writeByteArray(e.getValue());
+ }
+ }
+ else
+ raw.writeInt(-1);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readBinary(BinaryReader reader) throws BinaryObjectException {
+ BinaryRawReader raw = reader.rawReader();
+
+ lockNodeId = raw.readUuid();
+ lockId = raw.readLong();
+ update = raw.readBoolean();
+
+ if (update) {
+ isDiff = raw.readBoolean();
+ staticData = raw.readByteArray();
+ timeout = raw.readInt();
+
+ int cnt = raw.readInt();
+
+ if (cnt >= 0) {
+ items = new TreeMap<>();
+
+ for (int i = 0; i < cnt; i++)
+ items.put(raw.readString(), raw.readByteArray());
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(PlatformDotNetSessionSetAndUnlockProcessor.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Apache.Ignite.AspNet.Tests.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Apache.Ignite.AspNet.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Apache.Ignite.AspNet.Tests.csproj
new file mode 100644
index 0000000..aed74db
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Apache.Ignite.AspNet.Tests.csproj
@@ -0,0 +1,77 @@
+\ufeff<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{18EA4C71-A11D-4AB1-8042-418F7559D84F}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Apache.Ignite.AspNet.Tests</RootNamespace>
+ <AssemblyName>Apache.Ignite.AspNet.Tests</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <RunCodeAnalysis>true</RunCodeAnalysis>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SignAssembly>true</SignAssembly>
+ </PropertyGroup>
+ <PropertyGroup>
+ <AssemblyOriginatorKeyFile>Apache.Ignite.AspNet.Tests.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="nunit.framework">
+ <HintPath>..\packages\NUnit.Runners.2.6.3\tools\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Web" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ExpiryCacheHolderTest.cs" />
+ <Compile Include="IgniteOutputCacheProviderTest.cs" />
+ <Compile Include="IgniteSessionStateItemCollectionTest.cs" />
+ <Compile Include="IgniteSessionStateStoreDataTest.cs" />
+ <Compile Include="IgniteSessionStateStoreProviderTest.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Apache.Ignite.AspNet.Tests.snk" />
+ <None Include="App.config" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Apache.Ignite.AspNet\Apache.Ignite.AspNet.csproj">
+ <Project>{13EA96FC-CC83-4164-A7C0-4F30ED797460}</Project>
+ <Name>Apache.Ignite.AspNet</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Apache.Ignite.Core.Tests\Apache.Ignite.Core.Tests.csproj">
+ <Project>{6A62F66C-DA5B-4FBB-8CE7-A95F740FDC7A}</Project>
+ <Name>Apache.Ignite.Core.Tests</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Apache.Ignite.Core\Apache.Ignite.Core.csproj">
+ <Project>{4CD2F726-7E2B-46C4-A5BA-057BB82EECB6}</Project>
+ <Name>Apache.Ignite.Core</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Apache.Ignite.AspNet.Tests.snk
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Apache.Ignite.AspNet.Tests.snk b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Apache.Ignite.AspNet.Tests.snk
new file mode 100644
index 0000000..799e742
Binary files /dev/null and b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Apache.Ignite.AspNet.Tests.snk differ
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/App.config
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/App.config b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/App.config
new file mode 100644
index 0000000..86ee3d4
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/App.config
@@ -0,0 +1,72 @@
+\ufeff<?xml version="1.0" encoding="utf-8" ?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+-->
+
+<configuration>
+ <configSections>
+ <section name="igniteConfiguration" type="Apache.Ignite.Core.IgniteConfigurationSection, Apache.Ignite.Core" />
+ <section name="igniteConfiguration2" type="Apache.Ignite.Core.IgniteConfigurationSection, Apache.Ignite.Core" />
+ <section name="igniteConfiguration3" type="Apache.Ignite.Core.IgniteConfigurationSection, Apache.Ignite.Core" />
+ </configSections>
+
+ <runtime>
+ <gcServer enabled="true"/>
+ </runtime>
+
+ <igniteConfiguration xmlns="http://ignite.apache.org/schema/dotnet/IgniteConfigurationSection" gridName="myGrid1">
+ <discoverySpi type="TcpDiscoverySpi">
+ <ipFinder type="TcpDiscoveryStaticIpFinder">
+ <endpoints>
+ <string>127.0.0.1:47500</string>
+ </endpoints>
+ </ipFinder>
+ </discoverySpi>
+
+ <cacheConfiguration>
+ <cacheConfiguration name="cacheName" />
+ </cacheConfiguration>
+ </igniteConfiguration>
+
+ <igniteConfiguration2 gridName="myGrid2" localhost="127.0.0.1">
+ <discoverySpi type="TcpDiscoverySpi">
+ <ipFinder type="TcpDiscoveryStaticIpFinder">
+ <endpoints>
+ <string>127.0.0.1:47500</string>
+ </endpoints>
+ </ipFinder>
+ </discoverySpi>
+
+ <cacheConfiguration>
+ <cacheConfiguration name="cacheName2" />
+ </cacheConfiguration>
+ </igniteConfiguration2>
+
+ <igniteConfiguration3 gridName="myGrid3" localhost="127.0.0.1">
+ <discoverySpi type="TcpDiscoverySpi">
+ <ipFinder type="TcpDiscoveryStaticIpFinder">
+ <endpoints>
+ <string>127.0.0.1:47500</string>
+ </endpoints>
+ </ipFinder>
+ </discoverySpi>
+
+ <cacheConfiguration>
+ <cacheConfiguration name="cacheName3" atomicityMode="Transactional" />
+ </cacheConfiguration>
+ </igniteConfiguration3>
+</configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/ExpiryCacheHolderTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/ExpiryCacheHolderTest.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/ExpiryCacheHolderTest.cs
new file mode 100644
index 0000000..c12fe93
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/ExpiryCacheHolderTest.cs
@@ -0,0 +1,492 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+// ReSharper disable UnusedAutoPropertyAccessor.Local
+namespace Apache.Ignite.AspNet.Tests
+{
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Threading.Tasks;
+ using Apache.Ignite.AspNet.Impl;
+ using Apache.Ignite.Core;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Cache.Configuration;
+ using Apache.Ignite.Core.Cache.Expiry;
+ using Apache.Ignite.Core.Cache.Query;
+ using Apache.Ignite.Core.Cache.Query.Continuous;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Tests for <see cref="ExpiryCacheHolder{TK,TV}"/>.
+ /// </summary>
+ public class ExpiryCacheHolderTest
+ {
+ /// <summary>
+ /// Tests the expiry policy.
+ /// </summary>
+ [Test]
+ public void TestExpiryPolicy()
+ {
+ var cache = new CacheEx();
+
+ Assert.IsNull(cache.ExpiryPolicy);
+
+ var holder = new ExpiryCacheHolder<int, int>(cache);
+
+ // Check same cache for same expiry.
+ var cache1 = (CacheEx) holder.GetCacheWithExpiry(15);
+
+ CheckExpiry(TimeSpan.FromSeconds(15), cache1);
+ Assert.AreNotSame(cache, cache1);
+ Assert.AreSame(cache1, holder.GetCacheWithExpiry(15));
+
+ // Check rounding.
+ var cache2 = (CacheEx) holder.GetCacheWithExpiry(DateTime.UtcNow.AddSeconds(15.1));
+ Assert.AreSame(cache1, cache2);
+
+ // Check no expiration.
+ var cache3 = (CacheEx) holder.GetCacheWithExpiry(DateTime.MaxValue);
+ Assert.AreSame(cache, cache3);
+ }
+
+ /// <summary>
+ /// Checks the expiry.
+ /// </summary>
+ private static void CheckExpiry(TimeSpan timeSpan, CacheEx cache)
+ {
+ Assert.AreEqual(timeSpan, cache.ExpiryPolicy.GetExpiryForCreate());
+ Assert.IsNull(cache.ExpiryPolicy.GetExpiryForUpdate());
+ Assert.IsNull(cache.ExpiryPolicy.GetExpiryForAccess());
+ }
+
+ /// <summary>
+ /// Test cache implementation.
+ /// </summary>
+ private class CacheEx : ICache<int, int>
+ {
+ public IExpiryPolicy ExpiryPolicy { get; set; }
+
+ public IEnumerator<ICacheEntry<int, int>> GetEnumerator()
+ {
+ throw new NotImplementedException();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public string Name { get; private set; }
+
+ public IIgnite Ignite { get; private set; }
+
+ public CacheConfiguration GetConfiguration()
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool IsEmpty()
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool IsKeepBinary { get; private set; }
+
+ public ICache<int, int> WithSkipStore()
+ {
+ throw new NotImplementedException();
+ }
+
+ public ICache<int, int> WithExpiryPolicy(IExpiryPolicy plc)
+ {
+ return new CacheEx {ExpiryPolicy = plc};
+ }
+
+ public ICache<TK1, TV1> WithKeepBinary<TK1, TV1>()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void LoadCache(ICacheEntryFilter<int, int> p, params object[] args)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task LoadCacheAsync(ICacheEntryFilter<int, int> p, params object[] args)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void LocalLoadCache(ICacheEntryFilter<int, int> p, params object[] args)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task LocalLoadCacheAsync(ICacheEntryFilter<int, int> p, params object[] args)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void LoadAll(IEnumerable<int> keys, bool replaceExistingValues)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task LoadAllAsync(IEnumerable<int> keys, bool replaceExistingValues)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool ContainsKey(int key)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<bool> ContainsKeyAsync(int key)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool ContainsKeys(IEnumerable<int> keys)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<bool> ContainsKeysAsync(IEnumerable<int> keys)
+ {
+ throw new NotImplementedException();
+ }
+
+ public int LocalPeek(int key, params CachePeekMode[] modes)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryLocalPeek(int key, out int value, params CachePeekMode[] modes)
+ {
+ throw new NotImplementedException();
+ }
+
+ public int this[int key]
+ {
+ get { throw new NotImplementedException(); }
+ set { throw new NotImplementedException(); }
+ }
+
+ public int Get(int key)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<int> GetAsync(int key)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGet(int key, out int value)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<CacheResult<int>> TryGetAsync(int key)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IDictionary<int, int> GetAll(IEnumerable<int> keys)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<IDictionary<int, int>> GetAllAsync(IEnumerable<int> keys)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Put(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task PutAsync(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public CacheResult<int> GetAndPut(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<CacheResult<int>> GetAndPutAsync(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public CacheResult<int> GetAndReplace(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<CacheResult<int>> GetAndReplaceAsync(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public CacheResult<int> GetAndRemove(int key)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<CacheResult<int>> GetAndRemoveAsync(int key)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool PutIfAbsent(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<bool> PutIfAbsentAsync(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public CacheResult<int> GetAndPutIfAbsent(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<CacheResult<int>> GetAndPutIfAbsentAsync(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool Replace(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<bool> ReplaceAsync(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool Replace(int key, int oldVal, int newVal)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<bool> ReplaceAsync(int key, int oldVal, int newVal)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void PutAll(IDictionary<int, int> vals)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task PutAllAsync(IDictionary<int, int> vals)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void LocalEvict(IEnumerable<int> keys)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Clear()
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task ClearAsync()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Clear(int key)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task ClearAsync(int key)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void ClearAll(IEnumerable<int> keys)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task ClearAllAsync(IEnumerable<int> keys)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void LocalClear(int key)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void LocalClearAll(IEnumerable<int> keys)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool Remove(int key)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<bool> RemoveAsync(int key)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool Remove(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<bool> RemoveAsync(int key, int val)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveAll(IEnumerable<int> keys)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task RemoveAllAsync(IEnumerable<int> keys)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveAll()
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task RemoveAllAsync()
+ {
+ throw new NotImplementedException();
+ }
+
+ public int GetLocalSize(params CachePeekMode[] modes)
+ {
+ throw new NotImplementedException();
+ }
+
+ public int GetSize(params CachePeekMode[] modes)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<int> GetSizeAsync(params CachePeekMode[] modes)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void LocalPromote(IEnumerable<int> keys)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IQueryCursor<ICacheEntry<int, int>> Query(QueryBase qry)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IQueryCursor<IList> QueryFields(SqlFieldsQuery qry)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IContinuousQueryHandle QueryContinuous(ContinuousQuery<int, int> qry)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IContinuousQueryHandle<ICacheEntry<int, int>> QueryContinuous(ContinuousQuery<int, int> qry, QueryBase initialQry)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerable<ICacheEntry<int, int>> GetLocalEntries(params CachePeekMode[] peekModes)
+ {
+ throw new NotImplementedException();
+ }
+
+ public TRes Invoke<TArg, TRes>(int key, ICacheEntryProcessor<int, int, TArg, TRes> processor, TArg arg)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<TRes> InvokeAsync<TArg, TRes>(int key, ICacheEntryProcessor<int, int, TArg, TRes> processor, TArg arg)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IDictionary<int, ICacheEntryProcessorResult<TRes>> InvokeAll<TArg, TRes>(IEnumerable<int> keys, ICacheEntryProcessor<int, int, TArg, TRes> processor, TArg arg)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<IDictionary<int, ICacheEntryProcessorResult<TRes>>> InvokeAllAsync<TArg, TRes>(IEnumerable<int> keys, ICacheEntryProcessor<int, int, TArg, TRes> processor, TArg arg)
+ {
+ throw new NotImplementedException();
+ }
+
+ public ICacheLock Lock(int key)
+ {
+ throw new NotImplementedException();
+ }
+
+ public ICacheLock LockAll(IEnumerable<int> keys)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool IsLocalLocked(int key, bool byCurrentThread)
+ {
+ throw new NotImplementedException();
+ }
+
+ public ICacheMetrics GetMetrics()
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task Rebalance()
+ {
+ throw new NotImplementedException();
+ }
+
+ public ICache<int, int> WithNoRetries()
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+}
[5/5] ignite git commit: Fix merge from 1.7.2
Posted by pt...@apache.org.
Fix merge from 1.7.2
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/77a9aaca
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/77a9aaca
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/77a9aaca
Branch: refs/heads/master
Commit: 77a9aaca1ff8673f30548ba4f4e806ac2bbdde51
Parents: 0b7512a
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri Sep 16 18:07:52 2016 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Sep 16 18:07:52 2016 +0300
----------------------------------------------------------------------
.../dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/77a9aaca/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
index ecc76f9..bea49da 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
@@ -21,6 +21,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+ using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
@@ -1116,6 +1117,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
if (_ignite != null && errDataLen > 0)
{
// Stream disposal intentionally omitted: IGNITE-1598
+ // ReSharper disable once ExpressionIsAlwaysNull
var stream = new PlatformRawMemory(errData, errDataLen).GetStream();
throw ExceptionUtils.GetException(_ignite, errCls, errMsg, stackTrace,
[2/5] ignite git commit: IGNITE-3199 .NET: Add ASP.NET Session-State
Store Provider
Posted by pt...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteOutputCacheProviderTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteOutputCacheProviderTest.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteOutputCacheProviderTest.cs
new file mode 100644
index 0000000..bf2fd7e
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteOutputCacheProviderTest.cs
@@ -0,0 +1,172 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 Apache.Ignite.AspNet.Tests
+{
+ using System;
+ using System.Collections.Specialized;
+ using System.Threading;
+ using Apache.Ignite.Core;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Tests;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Tests for <see cref="IgniteOutputCacheProvider"/>
+ /// </summary>
+ public class IgniteOutputCacheProviderTest
+ {
+ /** Grid name XML config attribute. */
+ private const string GridNameAttr = "gridName";
+
+ /** Cache name XML config attribute. */
+ private const string CacheNameAttr = "cacheName";
+
+ /** Cache name XML config attribute. */
+ private const string SectionNameAttr = "igniteConfigurationSectionName";
+
+ /** Grid name. */
+ private const string GridName = "grid1";
+
+ /** Cache name. */
+ private const string CacheName = "myCache";
+
+ /// <summary>
+ /// Fixture setup.
+ /// </summary>
+ [TestFixtureSetUp]
+ public void TestFixtureSetUp()
+ {
+ Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration()) {GridName = GridName});
+ }
+
+ /// <summary>
+ /// Fixture teardown.
+ /// </summary>
+ [TestFixtureTearDown]
+ public void TestFixtureTearDown()
+ {
+ Ignition.StopAll(true);
+ }
+
+ /// <summary>
+ /// Tests provider initialization.
+ /// </summary>
+ [Test]
+ public void TestInitialization()
+ {
+ var cacheProvider = new IgniteOutputCacheProvider();
+
+ // Not initialized.
+ Assert.Throws<InvalidOperationException>(() => cacheProvider.Get("1"));
+
+ // Invalid section.
+ Assert.Throws<IgniteException>(() =>
+ cacheProvider.Initialize("testName", new NameValueCollection
+ {
+ {SectionNameAttr, "invalidSection"},
+ }));
+
+ // Valid grid.
+ cacheProvider = GetProvider();
+
+ cacheProvider.Set("1", 1, DateTime.MaxValue);
+ Assert.AreEqual(1, cacheProvider.Get("1"));
+ }
+
+ /// <summary>
+ /// Tests autostart from web configuration section.
+ /// </summary>
+ [Test]
+ public void TestStartFromWebConfigSection()
+ {
+ var cacheProvider = new IgniteOutputCacheProvider();
+
+ cacheProvider.Initialize("testName2", new NameValueCollection
+ {
+ {SectionNameAttr, "igniteConfiguration2"},
+ {CacheNameAttr, "cacheName2"}
+ });
+
+ cacheProvider.Set("1", 3, DateTime.MaxValue);
+ Assert.AreEqual(3, cacheProvider.Get("1"));
+ }
+
+ /// <summary>
+ /// Tests provider caching.
+ /// </summary>
+ [Test]
+ public void TestCaching()
+ {
+ var cacheProvider = GetProvider();
+
+ Assert.AreEqual(null, cacheProvider.Get("1"));
+ cacheProvider.Set("1", 1, DateTime.MaxValue);
+ Assert.AreEqual(1, cacheProvider.Get("1"));
+
+ cacheProvider.Remove("1");
+ Assert.AreEqual(null, cacheProvider.Get("1"));
+
+ Assert.AreEqual(null, cacheProvider.Add("2", 2, DateTime.MaxValue));
+ Assert.AreEqual(2, cacheProvider.Add("2", 5, DateTime.MaxValue));
+ }
+
+ /// <summary>
+ /// Tests cache expiration.
+ /// </summary>
+ [Test]
+ public void TestExpiry()
+ {
+ var cacheProvider = GetProvider();
+ cacheProvider.Remove("1");
+
+ // Set
+ cacheProvider.Set("1", 1, DateTime.UtcNow.AddSeconds(1.3));
+ Assert.AreEqual(1, cacheProvider.Get("1"));
+ Thread.Sleep(2000);
+ Assert.AreEqual(null, cacheProvider.Get("1"));
+
+ cacheProvider.Set("1", 1, DateTime.UtcNow);
+ Assert.AreEqual(null, cacheProvider.Get("1"));
+
+ // Add
+ cacheProvider.Add("1", 1, DateTime.UtcNow.AddSeconds(0.7));
+ Assert.AreEqual(1, cacheProvider.Get("1"));
+ Thread.Sleep(2000);
+ Assert.AreEqual(null, cacheProvider.Get("1"));
+
+ cacheProvider.Add("1", 1, DateTime.UtcNow);
+ Assert.AreEqual(null, cacheProvider.Get("1"));
+ }
+
+ /// <summary>
+ /// Gets the initialized provider.
+ /// </summary>
+ private static IgniteOutputCacheProvider GetProvider()
+ {
+ var cacheProvider = new IgniteOutputCacheProvider();
+
+ cacheProvider.Initialize("testName", new NameValueCollection
+ {
+ {GridNameAttr, GridName},
+ {CacheNameAttr, CacheName}
+ });
+
+ return cacheProvider;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateItemCollectionTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateItemCollectionTest.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateItemCollectionTest.cs
new file mode 100644
index 0000000..137382e
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateItemCollectionTest.cs
@@ -0,0 +1,267 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 Apache.Ignite.AspNet.Tests
+{
+ using System;
+ using System.IO;
+ using System.Linq;
+ using Apache.Ignite.AspNet.Impl;
+ using Apache.Ignite.Core.Impl.Binary;
+ using Apache.Ignite.Core.Impl.Binary.IO;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Tests for <see cref="IgniteSessionStateItemCollection"/>.
+ /// </summary>
+ public class IgniteSessionStateItemCollectionTest
+ {
+ /// <summary>
+ /// Tests the empty collection.
+ /// </summary>
+ [Test]
+ public void TestEmpty()
+ {
+ var col1 = new IgniteSessionStateItemCollection();
+ var col2 = SerializeDeserialize(col1);
+
+ foreach (var col in new[] { col1, col2 })
+ {
+ Assert.IsFalse(col.Dirty);
+ Assert.IsFalse(col.IsSynchronized);
+ Assert.AreEqual(0, col.Count);
+ Assert.IsNotNull(col.SyncRoot);
+ Assert.IsEmpty(col);
+ Assert.IsEmpty(col.OfType<string>().ToArray());
+ Assert.IsEmpty(col.Keys);
+ Assert.IsNotNull(col.SyncRoot);
+
+ Assert.IsNull(col["key"]);
+ Assert.Throws<ArgumentOutOfRangeException>(() => col[0] = "x");
+ Assert.Throws<ArgumentOutOfRangeException>(() => Assert.AreEqual(0, col[0]));
+ Assert.Throws<ArgumentOutOfRangeException>(() => col.RemoveAt(0));
+
+ col.Clear();
+ col.Remove("test");
+
+ Assert.AreEqual(0, col.Count);
+
+ col.Dirty = true;
+ Assert.IsTrue(col.Dirty);
+ }
+ }
+
+ /// <summary>
+ /// Tests the modification.
+ /// </summary>
+ [Test]
+ public void TestModification()
+ {
+ var col = new IgniteSessionStateItemCollection();
+
+ // Populate and check.
+ col["key"] = "val";
+ col["1"] = 1;
+
+ Assert.AreEqual("val", col["key"]);
+ Assert.AreEqual(1, col["1"]);
+
+ Assert.AreEqual(2, col.Count);
+ Assert.IsTrue(col.Dirty);
+
+ CollectionAssert.AreEquivalent(new[] {"key", "1"}, col);
+ CollectionAssert.AreEquivalent(new[] {"key", "1"}, col.Keys);
+
+ // Modify using index.
+ col[0] = "val1";
+ col[1] = 2;
+
+ Assert.AreEqual("val1", col["key"]);
+ Assert.AreEqual(2, col["1"]);
+
+ // Modify using key.
+ col["1"] = 3;
+ col["key"] = "val2";
+
+ Assert.AreEqual("val2", col["key"]);
+ Assert.AreEqual(3, col["1"]);
+
+ // CopyTo.
+ var keys = new string[5];
+ col.CopyTo(keys, 2);
+ Assert.AreEqual(new[] {null, null, "key", "1", null}, keys);
+
+ // Remove.
+ col["2"] = 2;
+ col["3"] = 3;
+
+ col.Remove("invalid");
+ Assert.AreEqual(4, col.Count);
+
+ col.Remove("1");
+
+ Assert.AreEqual(new[] { "key", "2", "3" }, col.OfType<string>());
+ Assert.AreEqual(null, col["1"]);
+
+ Assert.AreEqual("val2", col["key"]);
+ Assert.AreEqual("val2", col[0]);
+
+ Assert.AreEqual(2, col["2"]);
+ Assert.AreEqual(2, col[1]);
+
+ Assert.AreEqual(3, col["3"]);
+ Assert.AreEqual(3, col[2]);
+
+ // RemoveAt.
+ col.RemoveAt(0);
+ Assert.AreEqual(new[] { "2", "3" }, col.OfType<string>());
+
+ // Clear.
+ Assert.AreEqual(2, col.Count);
+
+ col.Clear();
+ Assert.AreEqual(0, col.Count);
+
+ // Set dirty.
+ var col1 = new IgniteSessionStateItemCollection {Dirty = true};
+ Assert.IsTrue(col1.Dirty);
+ }
+
+ /// <summary>
+ /// Tests dirty tracking.
+ /// </summary>
+ [Test]
+ public void TestApplyChanges()
+ {
+ Func<IgniteSessionStateItemCollection> getCol = () =>
+ {
+ var res = new IgniteSessionStateItemCollection();
+
+ res["1"] = 1;
+ res["2"] = 2;
+ res["3"] = 3;
+
+ return res;
+ };
+
+ var col = getCol();
+
+ var col0 = SerializeDeserialize(col);
+
+ Assert.AreEqual(3, col0.Count);
+
+ col0.Remove("1");
+ col0["2"] = 22;
+ col0["4"] = 44;
+
+ // Apply non-serialized changes.
+ col.ApplyChanges(col0);
+
+ Assert.AreEqual(3, col.Count);
+ Assert.AreEqual(null, col["1"]);
+ Assert.AreEqual(22, col["2"]);
+ Assert.AreEqual(3, col["3"]);
+ Assert.AreEqual(44, col["4"]);
+
+ // Apply serialized changes without WriteChangesOnly.
+ col = getCol();
+ col.ApplyChanges(SerializeDeserialize(col0));
+
+ Assert.AreEqual(3, col.Count);
+ Assert.AreEqual(null, col["1"]);
+ Assert.AreEqual(22, col["2"]);
+ Assert.AreEqual(3, col["3"]);
+ Assert.AreEqual(44, col["4"]);
+
+ // Apply serialized changes with WriteChangesOnly.
+ col = getCol();
+ col.ApplyChanges(SerializeDeserialize(col0, true));
+
+ Assert.AreEqual(3, col.Count);
+ Assert.AreEqual(null, col["1"]);
+ Assert.AreEqual(22, col["2"]);
+ Assert.AreEqual(3, col["3"]);
+ Assert.AreEqual(44, col["4"]);
+
+ // Remove key then add back.
+ col0.Remove("2");
+ col0.Remove("3");
+ col0["2"] = 222;
+
+ col = getCol();
+ col.ApplyChanges(SerializeDeserialize(col0));
+
+ Assert.AreEqual(2, col.Count);
+ Assert.AreEqual(222, col["2"]);
+ Assert.AreEqual(44, col["4"]);
+
+ // Remove all.
+ col0 = SerializeDeserialize(getCol());
+ col0.Clear();
+
+ col = getCol();
+ col.ApplyChanges(SerializeDeserialize(col0, true));
+
+ Assert.AreEqual(0, col.Count);
+
+ // Add to empty.
+ col0["-1"] = -1;
+ col0["-2"] = -2;
+
+ col = getCol();
+ col.ApplyChanges(SerializeDeserialize(col0));
+
+ Assert.AreEqual(2, col.Count);
+ Assert.AreEqual(-1, col0["-1"]);
+ Assert.AreEqual(-2, col0["-2"]);
+
+ // Remove initial key, then add it back, then remove again.
+ col0 = SerializeDeserialize(getCol());
+
+ col0.Remove("1");
+ col0.Remove("2");
+ col0["1"] = "111";
+ col0.Remove("1");
+
+ col = getCol();
+ col.ApplyChanges(SerializeDeserialize(col0, true));
+
+ Assert.AreEqual(1, col.Count);
+ Assert.AreEqual(3, col["3"]);
+ }
+
+ /// <summary>
+ /// Serializes and deserializes back an instance.
+ /// </summary>
+ private static IgniteSessionStateItemCollection SerializeDeserialize(IgniteSessionStateItemCollection data,
+ bool changesOnly = false)
+ {
+ var marsh = BinaryUtils.Marshaller;
+
+ using (var stream = new BinaryHeapStream(128))
+ {
+ var writer = marsh.StartMarshal(stream);
+
+ data.WriteBinary(writer.GetRawWriter(), changesOnly);
+
+ stream.Seek(0, SeekOrigin.Begin);
+
+ return new IgniteSessionStateItemCollection(marsh.StartUnmarshal(stream));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateStoreDataTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateStoreDataTest.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateStoreDataTest.cs
new file mode 100644
index 0000000..e8dcd7c
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateStoreDataTest.cs
@@ -0,0 +1,117 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 Apache.Ignite.AspNet.Tests
+{
+ using System;
+ using System.IO;
+ using System.Reflection;
+ using System.Web;
+ using Apache.Ignite.AspNet.Impl;
+ using Apache.Ignite.Core.Impl.Binary;
+ using Apache.Ignite.Core.Impl.Binary.IO;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Tests for <see cref="IgniteSessionStateStoreData"/>.
+ /// </summary>
+ public class IgniteSessionStateStoreDataTest
+ {
+ /// <summary>
+ /// Tests the data.
+ /// </summary>
+ [Test]
+ public void TestData()
+ {
+ // Modification method is internal.
+ var statics = new HttpStaticObjectsCollection();
+ statics.GetType().GetMethod("Add", BindingFlags.Instance | BindingFlags.NonPublic)
+ .Invoke(statics, new object[] { "int", typeof(int), false });
+
+ var data = new IgniteSessionStateStoreData(statics, 44);
+
+ data.Items["key"] = "val";
+
+ Assert.AreEqual(44, data.Timeout);
+ Assert.AreEqual(1, data.StaticObjects.Count);
+ Assert.AreEqual(0, data.StaticObjects["int"]);
+ Assert.AreEqual("val", data.Items["key"]);
+ }
+
+ /// <summary>
+ /// Tests the empty data.
+ /// </summary>
+ [Test]
+ public void TestEmpty()
+ {
+ var data = new IgniteSessionStateStoreData(null, 0);
+
+ Assert.AreEqual(0, data.LockId);
+ Assert.AreEqual(0, data.Items.Count);
+ Assert.AreEqual(0, data.Timeout);
+ Assert.IsNull(data.LockNodeId);
+ Assert.IsNull(data.LockTime);
+ Assert.IsNull(data.StaticObjects);
+ }
+
+ /// <summary>
+ /// Tests the serialization.
+ /// </summary>
+ [Test]
+ public void TestSerialization()
+ {
+ var data = new IgniteSessionStateStoreData(null, 96)
+ {
+ Timeout = 97,
+ LockId = 11,
+ LockNodeId = Guid.NewGuid(),
+ LockTime = DateTime.UtcNow.AddHours(-1),
+ };
+
+ data.Items["key1"] = 1;
+ data.Items["key2"] = 2;
+
+ var data0 = SerializeDeserialize(data);
+
+ Assert.AreEqual(data.Timeout, data0.Timeout);
+ Assert.AreEqual(data.LockId, data0.LockId);
+ Assert.AreEqual(data.LockNodeId, data0.LockNodeId);
+ Assert.AreEqual(data.LockTime, data0.LockTime);
+ Assert.AreEqual(data.Items.Keys, data0.Items.Keys);
+ }
+
+
+ /// <summary>
+ /// Serializes and deserializes back an instance.
+ /// </summary>
+ private static IgniteSessionStateStoreData SerializeDeserialize(IgniteSessionStateStoreData data)
+ {
+ var marsh = BinaryUtils.Marshaller;
+
+ using (var stream = new BinaryHeapStream(128))
+ {
+ var writer = marsh.StartMarshal(stream);
+
+ data.WriteBinary(writer.GetRawWriter(), false);
+
+ stream.Seek(0, SeekOrigin.Begin);
+
+ return new IgniteSessionStateStoreData(marsh.StartUnmarshal(stream));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateStoreProviderTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateStoreProviderTest.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateStoreProviderTest.cs
new file mode 100644
index 0000000..fc239ad
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateStoreProviderTest.cs
@@ -0,0 +1,425 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 Apache.Ignite.AspNet.Tests
+{
+ using System;
+ using System.Collections.Specialized;
+ using System.Linq;
+ using System.Reflection;
+ using System.Threading;
+ using System.Threading.Tasks;
+ using System.Web;
+ using System.Web.SessionState;
+ using Apache.Ignite.Core;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Tests;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Tests for <see cref="IgniteSessionStateStoreProvider"/>.
+ /// </summary>
+ public class IgniteSessionStateStoreProviderTest
+ {
+ /** Grid name XML config attribute. */
+ private const string GridNameAttr = "gridName";
+
+ /** Cache name XML config attribute. */
+ private const string CacheNameAttr = "cacheName";
+
+ /** Section name XML config attribute. */
+ private const string SectionNameAttr = "igniteConfigurationSectionName";
+
+ /** Grid name. */
+ private const string GridName = "grid1";
+
+ /** Cache name. */
+ private const string CacheName = "myCache";
+
+ /** Session id. */
+ private const string Id = "1";
+
+ /** Test context. */
+ private static readonly HttpContext HttpContext =
+ new HttpContext(new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null));
+
+ /// <summary>
+ /// Fixture setup.
+ /// </summary>
+ [TestFixtureSetUp]
+ public void TestFixtureSetUp()
+ {
+ Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration()) { GridName = GridName });
+ }
+
+ /// <summary>
+ /// Fixture teardown.
+ /// </summary>
+ [TestFixtureTearDown]
+ public void TestFixtureTearDown()
+ {
+ Ignition.StopAll(true);
+ }
+
+ /// <summary>
+ /// Test teardown.
+ /// </summary>
+ [TearDown]
+ public void TearDown()
+ {
+ // Clear all caches.
+ var ignite = Ignition.GetIgnite(GridName);
+ ignite.GetCacheNames().ToList().ForEach(x => ignite.GetCache<object, object>(x).RemoveAll());
+ }
+
+ /// <summary>
+ /// Test setup.
+ /// </summary>
+ [SetUp]
+ public void SetUp()
+ {
+ // Make sure caches are empty.
+ var ignite = Ignition.GetIgnite(GridName);
+
+ foreach (var cache in ignite.GetCacheNames().Select(x => ignite.GetCache<object, object>(x)))
+ CollectionAssert.IsEmpty(cache.ToArray());
+ }
+
+ /// <summary>
+ /// Tests provider initialization.
+ /// </summary>
+ [Test]
+ public void TestInitialization()
+ {
+ var stateProvider = new IgniteSessionStateStoreProvider();
+
+ SessionStateActions actions;
+ bool locked;
+ TimeSpan lockAge;
+ object lockId;
+
+ // Not initialized.
+ Assert.Throws<InvalidOperationException>(() =>
+ stateProvider.GetItem(HttpContext, Id, out locked, out lockAge, out lockId, out actions));
+
+ // Invalid section.
+ Assert.Throws<IgniteException>(() =>
+ stateProvider.Initialize("testName", new NameValueCollection
+ {
+ {SectionNameAttr, "invalidSection"},
+ {CacheNameAttr, CacheName}
+ }));
+
+ // Valid grid.
+ stateProvider = GetProvider();
+
+ CheckProvider(stateProvider);
+
+ // Same grid once again.
+ stateProvider = GetProvider();
+
+ CheckProvider(stateProvider);
+ }
+
+ /// <summary>
+ /// Tests autostart from web configuration section.
+ /// </summary>
+ [Test]
+ public void TestStartFromWebConfigSection()
+ {
+ var provider = new IgniteSessionStateStoreProvider();
+
+ provider.Initialize("testName3", new NameValueCollection
+ {
+ {SectionNameAttr, "igniteConfiguration3"},
+ {CacheNameAttr, "cacheName3"}
+ });
+
+ CheckProvider(provider);
+ }
+
+ /// <summary>
+ /// Tests the caching.
+ /// </summary>
+ [Test]
+ public void TestCaching()
+ {
+ bool locked;
+ TimeSpan lockAge;
+ object lockId;
+ SessionStateActions actions;
+
+ var provider = GetProvider();
+
+ // Not locked, no item.
+ var res = provider.GetItem(HttpContext, Id, out locked, out lockAge, out lockId, out actions);
+ Assert.IsNull(res);
+ Assert.IsNull(lockId);
+ Assert.IsFalse(locked);
+ Assert.AreEqual(TimeSpan.Zero, lockAge);
+ Assert.AreEqual(SessionStateActions.None, actions);
+
+ // Exclusive: not locked, no item.
+ res = provider.GetItemExclusive(HttpContext, Id, out locked, out lockAge, out lockId, out actions);
+ Assert.IsNull(res);
+ Assert.IsNull(lockId);
+ Assert.IsFalse(locked);
+ Assert.AreEqual(TimeSpan.Zero, lockAge);
+ Assert.AreEqual(SessionStateActions.None, actions);
+
+ // Add item.
+ provider.CreateUninitializedItem(HttpContext, Id, 7);
+
+ // Check added item.
+ res = provider.GetItem(HttpContext, Id, out locked, out lockAge, out lockId, out actions);
+ Assert.IsNotNull(res);
+ Assert.IsNull(lockId);
+ Assert.AreEqual(7, res.Timeout);
+ Assert.IsFalse(locked);
+ Assert.AreEqual(TimeSpan.Zero, lockAge);
+ Assert.AreEqual(SessionStateActions.None, actions);
+
+ // Lock and update.
+ res = provider.GetItemExclusive(HttpContext, Id, out locked, out lockAge, out lockId, out actions);
+ Assert.IsNotNull(res);
+ Assert.IsNotNull(lockId);
+ Assert.IsFalse(locked);
+ Assert.AreEqual(TimeSpan.Zero, lockAge);
+ Assert.AreEqual(SessionStateActions.None, actions);
+ provider.SetAndReleaseItemExclusive(HttpContext, Id, UpdateStoreData(res), lockId, true);
+
+ // Not locked, item present.
+ res = provider.GetItem(HttpContext, Id, out locked, out lockAge, out lockId, out actions);
+ CheckStoreData(res);
+ Assert.IsNull(lockId);
+ Assert.IsFalse(locked);
+ Assert.AreEqual(TimeSpan.Zero, lockAge);
+ Assert.AreEqual(SessionStateActions.None, actions);
+
+ // Lock item.
+ res = provider.GetItemExclusive(HttpContext, Id, out locked, out lockAge, out lockId, out actions);
+ CheckStoreData(res);
+ Assert.IsNotNull(lockId);
+ Assert.IsFalse(locked);
+ Assert.AreEqual(TimeSpan.Zero, lockAge);
+ Assert.AreEqual(SessionStateActions.None, actions);
+
+ // Try to get it in a different thread.
+ Task.Factory.StartNew(() =>
+ {
+ object lockId1; // do not overwrite lockId
+ res = provider.GetItem(HttpContext, Id, out locked, out lockAge, out lockId1, out actions);
+ Assert.IsNull(res);
+ Assert.IsNotNull(lockId1);
+ Assert.IsTrue(locked);
+ Assert.Greater(lockAge, TimeSpan.Zero);
+ Assert.AreEqual(SessionStateActions.None, actions);
+ }).Wait();
+
+ // Try to get it in a different thread.
+ Task.Factory.StartNew(() =>
+ {
+ object lockId1; // do not overwrite lockId
+ res = provider.GetItemExclusive(HttpContext, Id, out locked, out lockAge, out lockId1, out actions);
+ Assert.IsNull(res);
+ Assert.IsNotNull(lockId1);
+ Assert.IsTrue(locked);
+ Assert.Greater(lockAge, TimeSpan.Zero);
+ Assert.AreEqual(SessionStateActions.None, actions);
+ }).Wait();
+
+ // Release item.
+ provider.ReleaseItemExclusive(HttpContext, Id, lockId);
+
+ // Make sure it is accessible in a different thread.
+ Task.Factory.StartNew(() =>
+ {
+ res = provider.GetItem(HttpContext, Id, out locked, out lockAge, out lockId, out actions);
+ Assert.IsNotNull(res);
+ Assert.IsFalse(locked);
+ Assert.AreEqual(TimeSpan.Zero, lockAge);
+ Assert.AreEqual(SessionStateActions.None, actions);
+ }).Wait();
+
+ // Remove item.
+ provider.RemoveItem(HttpContext, Id, lockId, null);
+
+ // Check removal.
+ res = provider.GetItem(HttpContext, Id, out locked, out lockAge, out lockId, out actions);
+ Assert.IsNull(res);
+ Assert.IsFalse(locked);
+ Assert.AreEqual(TimeSpan.Zero, lockAge);
+ Assert.AreEqual(SessionStateActions.None, actions);
+ }
+
+ /// <summary>
+ /// Tests the create new store data.
+ /// </summary>
+ [Test]
+ public void TestCreateNewStoreData()
+ {
+ var provider = GetProvider();
+
+ var data = provider.CreateNewStoreData(HttpContext, 56);
+
+ Assert.AreEqual(56, data.Timeout);
+ Assert.IsEmpty(data.Items);
+ Assert.IsEmpty(data.StaticObjects);
+
+ // Check that caches are empty.
+ var ignite = Ignition.GetIgnite(GridName);
+ Assert.IsFalse(ignite.GetCacheNames().SelectMany(x => ignite.GetCache<int, int>(x)).Any());
+ }
+
+ /// <summary>
+ /// Tests the expiry.
+ /// </summary>
+ [Test]
+ [Category(TestUtils.CategoryIntensive)] // Minimum expiration is 1 minute
+ public void TestExpiry()
+ {
+ var provider = GetProvider();
+
+ bool locked;
+ TimeSpan lockAge;
+ object lockId;
+ SessionStateActions actions;
+
+ // Callbacks are not supported for now.
+ Assert.IsFalse(GetProvider().SetItemExpireCallback(null));
+
+ // Check there is no item.
+ var res = provider.GetItem(HttpContext, "myId", out locked, out lockAge, out lockId, out actions);
+ Assert.IsNull(res);
+
+ // Put an item.
+ provider.CreateUninitializedItem(HttpContext, "myId", 1);
+
+ // Check that it is there.
+ res = provider.GetItem(HttpContext, "myId", out locked, out lockAge, out lockId, out actions);
+ Assert.IsNotNull(res);
+
+ // Wait a minute and check again.
+ Thread.Sleep(TimeSpan.FromMinutes(1.05));
+
+ res = provider.GetItem(HttpContext, "myId", out locked, out lockAge, out lockId, out actions);
+ Assert.IsNull(res);
+ }
+
+ /// <summary>
+ /// Tests the create uninitialized item.
+ /// </summary>
+ [Test]
+ public void TestCreateUninitializedItem()
+ {
+ bool locked;
+ TimeSpan lockAge;
+ object lockId;
+ SessionStateActions actions;
+
+ var provider = GetProvider();
+ provider.CreateUninitializedItem(HttpContext, "myId", 45);
+
+ var res = provider.GetItem(HttpContext, "myId", out locked, out lockAge, out lockId, out actions);
+ Assert.IsNotNull(res);
+ Assert.AreEqual(45, res.Timeout);
+ Assert.AreEqual(0, res.Items.Count);
+ Assert.AreEqual(0, res.StaticObjects.Count);
+ }
+
+ /// <summary>
+ /// Updates the store data.
+ /// </summary>
+ private static SessionStateStoreData UpdateStoreData(SessionStateStoreData data)
+ {
+ data.Timeout = 8;
+
+ data.Items["name1"] = 1;
+ data.Items["name2"] = "2";
+
+ var statics = data.StaticObjects;
+
+ // Modification method is internal.
+ statics.GetType().GetMethod("Add", BindingFlags.Instance | BindingFlags.NonPublic)
+ .Invoke(statics, new object[] {"int", typeof(int), false});
+
+ CheckStoreData(data);
+
+ return data;
+ }
+
+ /// <summary>
+ /// Checks that store data is the same as <see cref="UpdateStoreData"/> returns.
+ /// </summary>
+ private static void CheckStoreData(SessionStateStoreData data)
+ {
+ Assert.IsNotNull(data);
+
+ Assert.AreEqual(8, data.Timeout);
+
+ Assert.AreEqual(1, data.Items["name1"]);
+ Assert.AreEqual(1, data.Items[0]);
+
+ Assert.AreEqual("2", data.Items["name2"]);
+ Assert.AreEqual("2", data.Items[1]);
+
+ Assert.AreEqual(0, data.StaticObjects["int"]);
+ }
+
+ /// <summary>
+ /// Gets the initialized provider.
+ /// </summary>
+ private static IgniteSessionStateStoreProvider GetProvider()
+ {
+ var stateProvider = new IgniteSessionStateStoreProvider();
+
+ stateProvider.Initialize("testName", new NameValueCollection
+ {
+ {GridNameAttr, GridName},
+ {CacheNameAttr, CacheName}
+ });
+
+ return stateProvider;
+ }
+
+ /// <summary>
+ /// Checks the provider.
+ /// </summary>
+ private static void CheckProvider(SessionStateStoreProviderBase provider)
+ {
+ bool locked;
+ TimeSpan lockAge;
+ object lockId;
+ SessionStateActions actions;
+
+ provider.InitializeRequest(HttpContext);
+ provider.CreateUninitializedItem(HttpContext, Id, 42);
+
+ var data = provider.GetItem(HttpContext, Id, out locked, out lockAge, out lockId, out actions);
+ Assert.IsNotNull(data);
+ Assert.AreEqual(42, data.Timeout);
+ Assert.IsFalse(locked);
+ Assert.AreEqual(TimeSpan.Zero, lockAge);
+ Assert.IsNull(lockId);
+ Assert.AreEqual(SessionStateActions.None, actions);
+
+ provider.ResetItemTimeout(HttpContext, Id);
+ provider.EndRequest(HttpContext);
+ provider.Dispose();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..afaa6f0
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,42 @@
+\ufeff/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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.Reflection;
+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("Apache.Ignite.AspNet.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache Ignite.NET")]
+[assembly: AssemblyCopyright("Copyright � 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+
+[assembly: Guid("18ea4c71-a11d-4ab1-8042-418f7559d84f")]
+
+[assembly: AssemblyVersion("1.8.0.14218")]
+[assembly: AssemblyFileVersion("1.8.0.14218")]
+[assembly: AssemblyInformationalVersion("1.8.0")]
+
+[assembly: CLSCompliant(true)]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/packages.config
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/packages.config b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/packages.config
new file mode 100644
index 0000000..c1198cb
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/packages.config
@@ -0,0 +1,22 @@
+\ufeff<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+-->
+
+<packages>
+ <package id="NUnit.Runners" version="2.6.3" targetFramework="net40" />
+</packages>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.csproj b/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.csproj
index 0c273e0..1ac452f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.csproj
@@ -47,7 +47,13 @@
</ItemGroup>
<ItemGroup>
<Compile Include="IgniteOutputCacheProvider.cs" />
+ <Compile Include="IgniteSessionStateStoreProvider.cs" />
<Compile Include="IgniteWebUtils.cs" />
+ <Compile Include="Impl\ConfigUtil.cs" />
+ <Compile Include="Impl\ExpiryCacheHolder.cs" />
+ <Compile Include="Impl\IgniteSessionStateStoreData.cs" />
+ <Compile Include="Impl\IgniteSessionStateItemCollection.cs" />
+ <Compile Include="Impl\SessionStateLockResult.cs" />
<Compile Include="Package-Info.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.ruleset
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.ruleset b/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.ruleset
index bc7683a..5a77e40 100644
--- a/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.ruleset
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.ruleset
@@ -2,7 +2,10 @@
<RuleSet Name="Rules for Apache.Ignite.AspNet" Description="Code analysis rules for Apache.Ignite.AspNet.csproj." ToolsVersion="14.0">
<IncludeAll Action="Error" />
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
+ <Rule Id="CA1020" Action="None" />
+ <Rule Id="CA1303" Action="None" />
<Rule Id="CA1704" Action="None" />
+ <Rule Id="CA2202" Action="None" />
<Rule Id="CA2204" Action="None" />
<Rule Id="CA2243" Action="None" />
</Rules>
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteOutputCacheProvider.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteOutputCacheProvider.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteOutputCacheProvider.cs
index 64216dd..d232726 100644
--- a/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteOutputCacheProvider.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteOutputCacheProvider.cs
@@ -18,23 +18,20 @@
namespace Apache.Ignite.AspNet
{
using System;
- using System.Collections.Generic;
using System.Collections.Specialized;
- using System.Configuration;
using System.Diagnostics.CodeAnalysis;
- using System.Globalization;
using System.Web.Caching;
+ using Apache.Ignite.AspNet.Impl;
using Apache.Ignite.Core;
using Apache.Ignite.Core.Cache;
- using Apache.Ignite.Core.Cache.Expiry;
- using Apache.Ignite.Core.Common;
/// <summary>
/// ASP.NET output cache provider that uses Ignite cache as a storage.
/// <para />
/// You can either start Ignite yourself, and provide <c>gridName</c> attribute,
/// or provide <c>igniteConfigurationSectionName</c> attribute to start Ignite automatically from specified
- /// configuration section (see <see cref="IgniteConfigurationSection"/>).
+ /// configuration section (see <see cref="IgniteConfigurationSection"/>)
+ /// using <c>igniteConfigurationSectionName</c>.
/// <para />
/// <c>cacheName</c> attribute specifies Ignite cache name to use for data storage. This attribute can be omitted
/// if cache name is null.
@@ -42,26 +39,7 @@ namespace Apache.Ignite.AspNet
public class IgniteOutputCacheProvider : OutputCacheProvider
{
/** */
- private const string GridName = "gridName";
-
- /** */
- private const string CacheName = "cacheName";
-
- /** */
- private const string IgniteConfigurationSectionName = "igniteConfigurationSectionName";
-
- /** Max number of cached expiry caches. */
- private const int MaxExpiryCaches = 1000;
-
- /** */
- private volatile ICache<string, object> _cache;
-
- /** Cached caches per expiry seconds. */
- private volatile Dictionary<long, ICache<string, object>> _expiryCaches =
- new Dictionary<long, ICache<string, object>>();
-
- /** Sync object. */
- private readonly object _syncRoot = new object();
+ private volatile ExpiryCacheHolder<string, object> _expiryCacheHolder;
/// <summary>
/// Returns a reference to the specified entry in the output cache.
@@ -88,7 +66,7 @@ namespace Apache.Ignite.AspNet
/// </returns>
public override object Add(string key, object entry, DateTime utcExpiry)
{
- return GetCacheWithExpiry(utcExpiry).GetAndPutIfAbsent(key, entry).Value;
+ return _expiryCacheHolder.GetCacheWithExpiry(utcExpiry).GetAndPutIfAbsent(key, entry).Value;
}
/// <summary>
@@ -99,7 +77,7 @@ namespace Apache.Ignite.AspNet
/// <param name="utcExpiry">The time and date on which the cached <paramref name="entry" /> expires.</param>
public override void Set(string key, object entry, DateTime utcExpiry)
{
- GetCacheWithExpiry(utcExpiry)[key] = entry;
+ _expiryCacheHolder.GetCacheWithExpiry(utcExpiry)[key] = entry;
}
/// <summary>
@@ -121,46 +99,11 @@ namespace Apache.Ignite.AspNet
{
base.Initialize(name, config);
- var gridName = config[GridName];
- var cacheName = config[CacheName];
- var cfgSection = config[IgniteConfigurationSectionName];
-
- try
- {
- var grid = cfgSection != null
- ? StartFromApplicationConfiguration(cfgSection)
- : Ignition.GetIgnite(gridName);
+ var cache = ConfigUtil.InitializeCache<string, object>(config, GetType());
- _cache = grid.GetOrCreateCache<string, object>(cacheName);
- }
- catch (Exception ex)
- {
- throw new IgniteException(string.Format(CultureInfo.InvariantCulture,
- "Failed to initialize {0}: {1}", GetType(), ex), ex);
- }
+ _expiryCacheHolder = new ExpiryCacheHolder<string, object>(cache);
}
- /// <summary>
- /// Starts Ignite from application configuration.
- /// </summary>
- private static IIgnite StartFromApplicationConfiguration(string sectionName)
- {
- var section = ConfigurationManager.GetSection(sectionName) as IgniteConfigurationSection;
-
- if (section == null)
- throw new ConfigurationErrorsException(string.Format(CultureInfo.InvariantCulture,
- "Could not find {0} with name '{1}'", typeof(IgniteConfigurationSection).Name, sectionName));
-
- var config = section.IgniteConfiguration;
-
- if (string.IsNullOrWhiteSpace(config.IgniteHome))
- {
- // IgniteHome not set by user: populate from default directory
- config = new IgniteConfiguration(config) {IgniteHome = IgniteWebUtils.GetWebIgniteHome()};
- }
-
- return Ignition.Start(config);
- }
/// <summary>
/// Gets the cache.
@@ -169,51 +112,12 @@ namespace Apache.Ignite.AspNet
{
get
{
- var cache = _cache;
-
- if (cache == null)
- throw new InvalidOperationException("IgniteOutputCacheProvider has not been initialized.");
-
- return cache;
- }
- }
-
- /// <summary>
- /// Gets the cache with expiry policy according to provided expiration date.
- /// </summary>
- /// <param name="utcExpiry">The UTC expiry.</param>
- /// <returns>Cache with expiry policy.</returns>
- private ICache<string, object> GetCacheWithExpiry(DateTime utcExpiry)
- {
- if (utcExpiry == DateTime.MaxValue)
- return Cache;
-
- // Round up to seconds ([OutputCache] duration is in seconds).
- var expirySeconds = (long) Math.Round((utcExpiry - DateTime.UtcNow).TotalSeconds);
-
- if (expirySeconds < 0)
- expirySeconds = 0;
-
- ICache<string, object> expiryCache;
-
- if (_expiryCaches.TryGetValue(expirySeconds, out expiryCache))
- return expiryCache;
-
- lock (_syncRoot)
- {
- if (_expiryCaches.TryGetValue(expirySeconds, out expiryCache))
- return expiryCache;
-
- // Copy on write with size limit
- _expiryCaches = _expiryCaches.Count > MaxExpiryCaches
- ? new Dictionary<long, ICache<string, object>>()
- : new Dictionary<long, ICache<string, object>>(_expiryCaches);
-
- expiryCache = Cache.WithExpiryPolicy(new ExpiryPolicy(TimeSpan.FromSeconds(expirySeconds), null, null));
+ var holder = _expiryCacheHolder;
- _expiryCaches[expirySeconds] = expiryCache;
+ if (holder == null)
+ throw new InvalidOperationException(GetType() + " has not been initialized.");
- return expiryCache;
+ return holder.Cache;
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteSessionStateStoreProvider.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteSessionStateStoreProvider.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteSessionStateStoreProvider.cs
new file mode 100644
index 0000000..1ee6d92
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteSessionStateStoreProvider.cs
@@ -0,0 +1,494 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 Apache.Ignite.AspNet
+{
+ using System;
+ using System.Collections.Specialized;
+ using System.Diagnostics;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Globalization;
+ using System.Threading;
+ using System.Web;
+ using System.Web.SessionState;
+ using Apache.Ignite.AspNet.Impl;
+ using Apache.Ignite.Core;
+ using Apache.Ignite.Core.Binary;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Impl.Cache;
+
+ /// <summary>
+ /// ASP.NET Session-State Store Provider that uses Ignite distributed cache as an underlying storage.
+ /// <para />
+ /// You can either start Ignite yourself, and provide <c>gridName</c> attribute,
+ /// or provide <c>igniteConfigurationSectionName</c> attribute to start Ignite automatically from specified
+ /// configuration section (see <see cref="IgniteConfigurationSection"/>)
+ /// using <c>igniteConfigurationSectionName</c>.
+ /// <para />
+ /// <c>cacheName</c> attribute specifies Ignite cache name to use for data storage. This attribute can be omitted
+ /// if cache name is null.
+ /// <para />
+ /// Optional <c>applicationId</c> attribute allows sharing a single Ignite cache between multiple web applications.
+ /// </summary>
+ public class IgniteSessionStateStoreProvider : SessionStateStoreProviderBase
+ {
+ /** Extension id */
+ private const int ExtensionId = 0;
+
+ /// <summary>
+ /// Op codes for <see cref="ICacheInternal.DoOutInOpExtension{T}"/>.
+ /// </summary>
+ private enum Op
+ {
+ /** Lock the session data. */
+ Lock = 1,
+
+ /** Update and unlock the session data. */
+ SetAndUnlock = 2,
+
+ /** Get the data without lock. */
+ Get = 3,
+
+ /** Put the data without lock. */
+ Put = 4,
+
+ /** Remove the data without lock. */
+ Remove = 5
+ }
+
+ /** Application id config parameter. */
+ private const string ApplicationId = "applicationId";
+
+ /** */
+ private volatile string _applicationId;
+
+ /** */
+ private volatile ExpiryCacheHolder<string, IgniteSessionStateStoreData> _expiryCacheHolder;
+
+ /** */
+ private static long _lockId;
+
+ /// <summary>
+ /// Initializes the provider.
+ /// </summary>
+ /// <param name="name">The friendly name of the provider.</param>
+ /// <param name="config">A collection of the name/value pairs representing the provider-specific attributes
+ /// specified in the configuration for this provider.</param>
+ [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")]
+ public override void Initialize(string name, NameValueCollection config)
+ {
+ base.Initialize(name, config);
+
+ var cache = ConfigUtil.InitializeCache<string, IgniteSessionStateStoreData>(config, GetType());
+
+ _expiryCacheHolder = new ExpiryCacheHolder<string, IgniteSessionStateStoreData>(cache);
+
+ _applicationId = config[ApplicationId];
+ }
+
+
+ /// <summary>
+ /// Releases all resources used by the <see cref="T:System.Web.SessionState.SessionStateStoreProviderBase" />
+ /// implementation.
+ /// </summary>
+ public override void Dispose()
+ {
+ // No-op.
+ }
+
+ /// <summary>
+ /// Sets a reference to the <see cref="T:System.Web.SessionState.SessionStateItemExpireCallback" />
+ /// delegate for the Session_OnEnd event defined in the Global.asax file.
+ /// </summary>
+ /// <param name="expireCallback">The <see cref="T:System.Web.SessionState.SessionStateItemExpireCallback" />
+ /// delegate for the Session_OnEnd event defined in the Global.asax file.</param>
+ /// <returns>
+ /// true if the session-state store provider supports calling the Session_OnEnd event; otherwise, false.
+ /// </returns>
+ public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback)
+ {
+ // Expiration events not supported for now.
+ return false;
+ }
+
+ /// <summary>
+ /// Called by the <see cref="T:System.Web.SessionState.SessionStateModule" /> object
+ /// for per-request initialization.
+ /// </summary>
+ /// <param name="context">The <see cref="T:System.Web.HttpContext" /> for the current request.</param>
+ public override void InitializeRequest(HttpContext context)
+ {
+ // No-op.
+ }
+
+ /// <summary>
+ /// Returns read-only session-state data from the session data store.
+ /// </summary>
+ /// <param name="context">The <see cref="T:System.Web.HttpContext" /> for the current request.</param>
+ /// <param name="id">The <see cref="P:System.Web.SessionState.HttpSessionState.SessionID" /> for the
+ /// current request.</param>
+ /// <param name="locked">When this method returns, contains a Boolean value that is set to true if the
+ /// requested session item is locked at the session data store; otherwise, false.</param>
+ /// <param name="lockAge">When this method returns, contains a <see cref="T:System.TimeSpan" /> object that
+ /// is set to the amount of time that an item in the session data store has been locked.</param>
+ /// <param name="lockId">When this method returns, contains an object that is set to the lock identifier
+ /// for the current request. For details on the lock identifier, see "Locking Session-Store Data"
+ /// in the <see cref="T:System.Web.SessionState.SessionStateStoreProviderBase" /> class summary.</param>
+ /// <param name="actions">When this method returns, contains one of the
+ /// <see cref="T:System.Web.SessionState.SessionStateActions" /> values, indicating whether the current
+ /// session is an uninitialized, cookieless session.</param>
+ /// <returns>
+ /// A <see cref="T:System.Web.SessionState.SessionStateStoreData" /> populated with session values and
+ /// information from the session data store.
+ /// </returns>
+ public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked,
+ out TimeSpan lockAge, out object lockId,
+ out SessionStateActions actions)
+ {
+ actions = SessionStateActions.None;
+ lockId = null;
+ lockAge = TimeSpan.Zero;
+ locked = false;
+
+ var key = GetKey(id);
+ var data = GetItem(key);
+
+ if (data != null)
+ {
+ locked = data.LockNodeId != null;
+
+ if (!locked)
+ {
+ return data;
+ }
+
+ Debug.Assert(data.LockTime != null);
+
+ lockAge = DateTime.UtcNow - data.LockTime.Value;
+
+ lockId = data.LockId;
+
+ return null;
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Returns read-only session-state data from the session data store.
+ /// </summary>
+ /// <param name="context">The <see cref="T:System.Web.HttpContext" /> for the current request.</param>
+ /// <param name="id">The <see cref="P:System.Web.SessionState.HttpSessionState.SessionID" /> for the current
+ /// request.</param>
+ /// <param name="locked">When this method returns, contains a Boolean value that is set to true if a lock
+ /// is successfully obtained; otherwise, false.</param>
+ /// <param name="lockAge">When this method returns, contains a <see cref="T:System.TimeSpan" /> object that
+ /// is set to the amount of time that an item in the session data store has been locked.</param>
+ /// <param name="lockId">When this method returns, contains an object that is set to the lock identifier
+ /// for the current request. For details on the lock identifier, see "Locking Session-Store Data" in
+ /// the <see cref="T:System.Web.SessionState.SessionStateStoreProviderBase" /> class summary.</param>
+ /// <param name="actions">When this method returns, contains one of the
+ /// <see cref="T:System.Web.SessionState.SessionStateActions" /> values, indicating whether the current
+ /// session is an uninitialized, cookieless session.</param>
+ /// <returns>
+ /// A <see cref="T:System.Web.SessionState.SessionStateStoreData" /> populated with session values
+ /// and information from the session data store.
+ /// </returns>
+ public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked,
+ out TimeSpan lockAge,
+ out object lockId, out SessionStateActions actions)
+ {
+ actions = SessionStateActions.None; // Our items never need initialization.
+ lockAge = TimeSpan.Zero;
+ lockId = null;
+
+ var lockId0 = Interlocked.Increment(ref _lockId);
+
+ var key = GetKey(id);
+
+ var lockResult = LockItem(key, lockId0);
+
+ // No item found.
+ if (lockResult == null)
+ {
+ locked = false;
+
+ return null;
+ }
+
+ // Item was already locked.
+ if (!lockResult.Success)
+ {
+ locked = true;
+
+ Debug.Assert(lockResult.LockTime != null);
+
+ lockAge = DateTime.UtcNow - lockResult.LockTime.Value;
+ lockId = lockResult.LockId;
+
+ return null;
+ }
+
+ // Item found and lock obtained.
+ locked = false;
+ lockId = lockId0;
+
+ if (lockId0 != lockResult.Data.LockId)
+ throw new IgniteException(string.Format(CultureInfo.InvariantCulture,
+ "Invalid session state lock result, " +
+ "expected lockId: {0}, actual: {1}", lockId0, lockResult.Data.LockId));
+
+ return lockResult.Data;
+ }
+
+ /// <summary>
+ /// Releases a lock on an item in the session data store.
+ /// </summary>
+ /// <param name="context">The <see cref="T:System.Web.HttpContext" /> for the current request.</param>
+ /// <param name="id">The session identifier for the current request.</param>
+ /// <param name="lockId">The lock identifier for the current request.</param>
+ public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
+ {
+ UnlockItem(GetKey(id), (long) lockId);
+ }
+
+ /// <summary>
+ /// Updates the session-item information in the session-state data store with values from the current request,
+ /// and clears the lock on the data.
+ /// </summary>
+ /// <param name="context">The <see cref="T:System.Web.HttpContext" /> for the current request.</param>
+ /// <param name="id">The session identifier for the current request.</param>
+ /// <param name="item">The <see cref="T:System.Web.SessionState.SessionStateStoreData" /> object that
+ /// contains the current session values to be stored.</param>
+ /// <param name="lockId">The lock identifier for the current request.</param>
+ /// <param name="newItem">true to identify the session item as a new item; false to identify the session
+ /// item as an existing item.</param>
+ [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")]
+ public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item,
+ object lockId, bool newItem)
+ {
+ Debug.Assert(item != null);
+
+ var key = GetKey(id);
+
+ var data = (IgniteSessionStateStoreData) item;
+
+ if (!(lockId is long) || data.LockId != (long) lockId)
+ throw new IgniteException(string.Format(CultureInfo.InvariantCulture,
+ "Invalid session release request, expected lockId: {0}, actual: {1}", data.LockId, lockId));
+
+ SetAndUnlockItem(key, data);
+ }
+
+ /// <summary>
+ /// Deletes item data from the session data store.
+ /// </summary>
+ /// <param name="context">The <see cref="T:System.Web.HttpContext" /> for the current request.</param>
+ /// <param name="id">The session identifier for the current request.</param>
+ /// <param name="lockId">The lock identifier for the current request.</param>
+ /// <param name="item">The <see cref="T:System.Web.SessionState.SessionStateStoreData" /> that represents
+ /// the item to delete from the data store.</param>
+ public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
+ {
+ RemoveItem(GetKey(id));
+ }
+
+ /// <summary>
+ /// Updates the expiration date and time of an item in the session data store.
+ /// </summary>
+ /// <param name="context">The <see cref="T:System.Web.HttpContext" /> for the current request.</param>
+ /// <param name="id">The session identifier for the current request.</param>
+ public override void ResetItemTimeout(HttpContext context, string id)
+ {
+ // No-op.
+
+ // This is not necessary since ResetItemTimeout is called right after SetAndReleaseItemExclusive,
+ // which itself resets the timeout when the item is inserted into cache.
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="T:System.Web.SessionState.SessionStateStoreData" /> object to be used
+ /// for the current request.
+ /// </summary>
+ /// <param name="context">The <see cref="T:System.Web.HttpContext" /> for the current request.</param>
+ /// <param name="timeout">The session-state <see cref="P:System.Web.SessionState.HttpSessionState.Timeout" />
+ /// value for the new <see cref="T:System.Web.SessionState.SessionStateStoreData" />.</param>
+ /// <returns>
+ /// A new <see cref="T:System.Web.SessionState.SessionStateStoreData" /> for the current request.
+ /// </returns>
+ public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
+ {
+ return new IgniteSessionStateStoreData(SessionStateUtility.GetSessionStaticObjects(context), timeout);
+ }
+
+ /// <summary>
+ /// Adds a new session-state item to the data store.
+ /// </summary>
+ /// <param name="context">The <see cref="T:System.Web.HttpContext" /> for the current request.</param>
+ /// <param name="id">The <see cref="P:System.Web.SessionState.HttpSessionState.SessionID" />
+ /// for the current request.</param>
+ /// <param name="timeout">The session <see cref="P:System.Web.SessionState.HttpSessionState.Timeout" />
+ /// for the current request.</param>
+ public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
+ {
+ var cache = _expiryCacheHolder.GetCacheWithExpiry((long) timeout * 60);
+
+ var key = GetKey(id);
+
+ var data = new IgniteSessionStateStoreData(SessionStateUtility.GetSessionStaticObjects(context), timeout);
+
+ PutItem(key, data, cache);
+ }
+
+ /// <summary>
+ /// Called by the <see cref="T:System.Web.SessionState.SessionStateModule" /> object at the end of a request.
+ /// </summary>
+ /// <param name="context">The <see cref="T:System.Web.HttpContext" /> for the current request.</param>
+ public override void EndRequest(HttpContext context)
+ {
+ // No-op.
+ }
+
+ /// <summary>
+ /// Gets the cache.
+ /// </summary>
+ private ICache<string, IgniteSessionStateStoreData> Cache
+ {
+ get
+ {
+ var holder = _expiryCacheHolder;
+
+ if (holder == null)
+ throw new InvalidOperationException(GetType() + " has not been initialized.");
+
+ return holder.Cache;
+ }
+ }
+
+ /// <summary>
+ /// Gets the key.
+ /// </summary>
+ private string GetKey(string sessionId)
+ {
+ return _applicationId == null ? sessionId : ApplicationId + "." + sessionId;
+ }
+
+ /// <summary>
+ /// Writes the lock info.
+ /// </summary>
+ private void WriteLockInfo(IBinaryRawWriter writer, long lockId, bool writeTime = false)
+ {
+ writer.WriteGuid(Cache.Ignite.GetCluster().GetLocalNode().Id);
+ writer.WriteLong(lockId);
+
+ if (writeTime)
+ writer.WriteTimestamp(DateTime.UtcNow);
+ }
+
+ /// <summary>
+ /// Locks the item.
+ /// </summary>
+ private SessionStateLockResult LockItem(string key, long lockId)
+ {
+ return OutInOp(Op.Lock,
+ w =>
+ {
+ w.WriteString(key);
+ WriteLockInfo(w, lockId, true);
+ },
+ r => new SessionStateLockResult(r));
+ }
+
+ /// <summary>
+ /// Unlocks the item.
+ /// </summary>
+ private void UnlockItem(string key, long lockId)
+ {
+ OutOp(Op.SetAndUnlock,
+ w =>
+ {
+ w.WriteString(key);
+ w.WriteBoolean(false); // Only unlock.
+ WriteLockInfo(w, lockId);
+ });
+ }
+
+ /// <summary>
+ /// Sets and unlocks the item.
+ /// </summary>
+ private void SetAndUnlockItem(string key, IgniteSessionStateStoreData data)
+ {
+ var cache = _expiryCacheHolder.GetCacheWithExpiry(data.Timeout * 60);
+
+ OutOp(Op.SetAndUnlock, w =>
+ {
+ w.WriteString(key);
+ w.WriteBoolean(true); // Unlock and update.
+ data.WriteBinary(w, true);
+ }, cache);
+ }
+
+ /// <summary>
+ /// Puts the item.
+ /// </summary>
+ private void PutItem(string key, IgniteSessionStateStoreData data, ICache<string, IgniteSessionStateStoreData> cache)
+ {
+ OutOp(Op.Put, w =>
+ {
+ w.WriteString(key);
+ data.WriteBinary(w, false);
+ }, cache);
+ }
+
+ /// <summary>
+ /// Gets the item.
+ /// </summary>
+ private IgniteSessionStateStoreData GetItem(string key)
+ {
+ return OutInOp(Op.Get, w => w.WriteString(key), r => new IgniteSessionStateStoreData(r));
+ }
+
+ /// <summary>
+ /// Removes the item.
+ /// </summary>
+ private void RemoveItem(string key)
+ {
+ OutOp(Op.Remove, w => w.WriteString(key));
+ }
+
+ /// <summary>
+ /// Invokes the extension operation.
+ /// </summary>
+ private void OutOp(Op op, Action<IBinaryRawWriter> writeAction,
+ ICache<string, IgniteSessionStateStoreData> cache = null)
+ {
+ OutInOp<object>(op, writeAction, null, cache);
+ }
+
+ /// <summary>
+ /// Invokes the extension operation.
+ /// </summary>
+ private T OutInOp<T>(Op op, Action<IBinaryRawWriter> writeAction, Func<IBinaryRawReader, T> readFunc,
+ ICache<string, IgniteSessionStateStoreData> cache = null)
+ {
+ cache = cache ?? Cache;
+
+ return ((ICacheInternal) cache).DoOutInOpExtension(ExtensionId, (int) op, writeAction, readFunc);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/ConfigUtil.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/ConfigUtil.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/ConfigUtil.cs
new file mode 100644
index 0000000..3eb3d90
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/ConfigUtil.cs
@@ -0,0 +1,109 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 Apache.Ignite.AspNet.Impl
+{
+ using System;
+ using System.Collections.Specialized;
+ using System.Configuration;
+ using System.Diagnostics;
+ using System.Globalization;
+ using Apache.Ignite.Core;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Cache.Configuration;
+ using Apache.Ignite.Core.Common;
+
+ /// <summary>
+ /// Config utils.
+ /// </summary>
+ internal static class ConfigUtil
+ {
+ /** */
+ public const string GridName = "gridName";
+
+ /** */
+ public const string CacheName = "cacheName";
+
+ /** */
+ public const string IgniteConfigurationSectionName = "igniteConfigurationSectionName";
+
+ /// <summary>
+ /// Initializes the cache from configuration.
+ /// </summary>
+ public static ICache<TK, TV> InitializeCache<TK, TV>(NameValueCollection config, Type callerType)
+ {
+ Debug.Assert(config != null);
+ Debug.Assert(callerType != null);
+
+ var gridName = config[GridName];
+ var cacheName = config[CacheName];
+ var cfgSection = config[IgniteConfigurationSectionName];
+
+ try
+ {
+ var grid = StartFromApplicationConfiguration(cfgSection, gridName);
+
+ var cacheConfiguration = new CacheConfiguration(cacheName);
+
+ return grid.GetOrCreateCache<TK, TV>(cacheConfiguration);
+ }
+ catch (Exception ex)
+ {
+ throw new IgniteException(string.Format(CultureInfo.InvariantCulture,
+ "Failed to initialize {0}: {1}", callerType, ex), ex);
+ }
+
+ }
+
+ /// <summary>
+ /// Starts Ignite from application configuration.
+ /// </summary>
+ private static IIgnite StartFromApplicationConfiguration(string sectionName, string gridName)
+ {
+ IgniteConfiguration config;
+
+ if (!string.IsNullOrEmpty(sectionName))
+ {
+ var section = ConfigurationManager.GetSection(sectionName) as IgniteConfigurationSection;
+
+ if (section == null)
+ throw new ConfigurationErrorsException(string.Format(CultureInfo.InvariantCulture,
+ "Could not find {0} with name '{1}'", typeof(IgniteConfigurationSection).Name, sectionName));
+
+ config = section.IgniteConfiguration;
+ }
+ else
+ config = new IgniteConfiguration {GridName = gridName};
+
+ // Check if already started.
+ var ignite = Ignition.TryGetIgnite(config.GridName);
+
+ if (ignite != null)
+ return ignite;
+
+ // Start.
+ if (string.IsNullOrWhiteSpace(config.IgniteHome))
+ {
+ // IgniteHome not set by user: populate from default directory.
+ config = new IgniteConfiguration(config) { IgniteHome = IgniteWebUtils.GetWebIgniteHome() };
+ }
+
+ return Ignition.Start(config);
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/799f1909/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/ExpiryCacheHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/ExpiryCacheHolder.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/ExpiryCacheHolder.cs
new file mode 100644
index 0000000..9678c38
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/Impl/ExpiryCacheHolder.cs
@@ -0,0 +1,113 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 Apache.Ignite.AspNet.Impl
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Cache.Expiry;
+
+ /// <summary>
+ /// Holds WithExpiry caches per expiration interval to avoid garbage on frequent WithExpiry calls.
+ /// </summary>
+ internal class ExpiryCacheHolder<TK, TV>
+ {
+ /** Max number of cached expiry caches. */
+ private const int MaxExpiryCaches = 1000;
+
+ /** */
+ private readonly ICache<TK, TV> _cache;
+
+ /** Cached caches per expiry seconds. */
+ private volatile Dictionary<long, ICache<TK, TV>> _expiryCaches =
+ new Dictionary<long, ICache<TK, TV>>();
+
+ /** Sync object. */
+ private readonly object _syncRoot = new object();
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExpiryCacheHolder{TK, TV}"/> class.
+ /// </summary>
+ /// <param name="cache">The cache.</param>
+ public ExpiryCacheHolder(ICache<TK, TV> cache)
+ {
+ Debug.Assert(cache != null);
+
+ _cache = cache;
+ }
+
+ /// <summary>
+ /// Gets the cache.
+ /// </summary>
+ public ICache<TK, TV> Cache
+ {
+ get { return _cache; }
+ }
+
+ /// <summary>
+ /// Gets the cache with expiry policy according to provided expiration date.
+ /// </summary>
+ /// <param name="utcExpiry">The UTC expiry.</param>
+ /// <returns>Cache with expiry policy.</returns>
+ public ICache<TK, TV> GetCacheWithExpiry(DateTime utcExpiry)
+ {
+ if (utcExpiry == DateTime.MaxValue)
+ return _cache;
+
+ Debug.Assert(utcExpiry.Kind == DateTimeKind.Utc);
+
+ // Round up to seconds ([OutputCache] duration is in seconds).
+ var expirySeconds = (long)Math.Round((utcExpiry - DateTime.UtcNow).TotalSeconds);
+
+ if (expirySeconds < 0)
+ expirySeconds = 0;
+
+ return GetCacheWithExpiry(expirySeconds);
+ }
+
+ /// <summary>
+ /// Gets the cache with expiry.
+ /// </summary>
+ /// <param name="expiry">The expiration interval (in seconds).</param>
+ public ICache<TK, TV> GetCacheWithExpiry(long expiry)
+ {
+ ICache<TK, TV> expiryCache;
+
+ if (_expiryCaches.TryGetValue(expiry, out expiryCache))
+ return expiryCache;
+
+ lock (_syncRoot)
+ {
+ if (_expiryCaches.TryGetValue(expiry, out expiryCache))
+ return expiryCache;
+
+ // Copy on write with size limit
+ _expiryCaches = _expiryCaches.Count > MaxExpiryCaches
+ ? new Dictionary<long, ICache<TK, TV>>()
+ : new Dictionary<long, ICache<TK, TV>>(_expiryCaches);
+
+ expiryCache = Cache.WithExpiryPolicy(new ExpiryPolicy(TimeSpan.FromSeconds(expiry), null, null));
+
+ _expiryCaches[expiry] = expiryCache;
+
+ return expiryCache;
+ }
+ }
+ }
+}
[4/5] ignite git commit: Merge remote-tracking branch
'remotes/community/ignite-1.7.2' into UPSTREAM_master
Posted by pt...@apache.org.
Merge remote-tracking branch 'remotes/community/ignite-1.7.2' into UPSTREAM_master
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformConfigurationEx.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cpp/PlatformCppConfigurationEx.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationEx.java
# modules/platforms/dotnet/Apache.Ignite.AspNet/Properties/AssemblyInfo.cs
# modules/platforms/dotnet/Apache.Ignite.sln
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0b7512a4
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0b7512a4
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0b7512a4
Branch: refs/heads/master
Commit: 0b7512a445acc39daf8cfb2108e199212be2f228
Parents: dddf6ba 799f190
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri Sep 16 17:56:32 2016 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Sep 16 17:56:32 2016 +0300
----------------------------------------------------------------------
.../ignite/internal/binary/BinaryContext.java | 5 +
.../platform/PlatformConfigurationEx.java | 7 +
.../platform/PlatformContextImpl.java | 3 -
.../processors/platform/PlatformProcessor.java | 10 +-
.../platform/PlatformProcessorImpl.java | 72 ++-
.../platform/cache/PlatformCache.java | 114 +++-
.../platform/cache/PlatformCacheExtension.java | 47 ++
.../cpp/PlatformCppConfigurationEx.java | 7 +
.../dotnet/PlatformDotNetConfigurationEx.java | 9 +
.../PlatformDotNetSessionCacheExtension.java | 144 +++++
.../websession/PlatformDotNetSessionData.java | 260 +++++++++
.../PlatformDotNetSessionLockProcessor.java | 84 +++
.../PlatformDotNetSessionLockResult.java | 106 ++++
...tformDotNetSessionSetAndUnlockProcessor.java | 179 +++++++
.../Apache.Ignite.AspNet.Tests.csproj | 77 +++
.../Apache.Ignite.AspNet.Tests.snk | Bin 0 -> 596 bytes
.../Apache.Ignite.AspNet.Tests/App.config | 72 +++
.../ExpiryCacheHolderTest.cs | 492 +++++++++++++++++
.../IgniteOutputCacheProviderTest.cs | 172 ++++++
.../IgniteSessionStateItemCollectionTest.cs | 267 ++++++++++
.../IgniteSessionStateStoreDataTest.cs | 117 ++++
.../IgniteSessionStateStoreProviderTest.cs | 425 +++++++++++++++
.../Properties/AssemblyInfo.cs | 42 ++
.../Apache.Ignite.AspNet.Tests/packages.config | 22 +
.../Apache.Ignite.AspNet.csproj | 6 +
.../Apache.Ignite.AspNet.ruleset | 3 +
.../IgniteOutputCacheProvider.cs | 120 +----
.../IgniteSessionStateStoreProvider.cs | 494 +++++++++++++++++
.../Apache.Ignite.AspNet/Impl/ConfigUtil.cs | 109 ++++
.../Impl/ExpiryCacheHolder.cs | 113 ++++
.../Impl/IgniteSessionStateItemCollection.cs | 534 +++++++++++++++++++
.../Impl/IgniteSessionStateStoreData.cs | 116 ++++
.../Impl/SessionStateLockResult.cs | 91 ++++
.../Properties/AssemblyInfo.cs | 3 +
.../Apache.Ignite.Core.Tests.csproj | 6 -
.../AspNet/IgniteOutputCacheProviderTest.cs | 172 ------
.../Apache.Ignite.Core/Impl/Cache/CacheImpl.cs | 15 +
.../Apache.Ignite.Core/Impl/Cache/CacheOp.cs | 3 +-
.../Impl/Cache/ICacheInternal.cs | 14 +
.../Impl/Unmanaged/UnmanagedCallbacks.cs | 1 -
.../Properties/AssemblyInfo.cs | 1 +
modules/platforms/dotnet/Apache.Ignite.sln | 14 +
42 files changed, 4222 insertions(+), 326 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b7512a4/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformConfigurationEx.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformConfigurationEx.java
index 96e4643,b7c8895..a58510d
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformConfigurationEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformConfigurationEx.java
@@@ -17,9 -17,10 +17,11 @@@
package org.apache.ignite.internal.processors.platform;
+import org.apache.ignite.internal.logger.platform.PlatformLogger;
+ import org.apache.ignite.internal.processors.platform.cache.PlatformCacheExtension;
import org.apache.ignite.internal.processors.platform.callback.PlatformCallbackGateway;
import org.apache.ignite.internal.processors.platform.memory.PlatformMemoryManagerImpl;
+ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
@@@ -48,7 -49,7 +50,12 @@@ public interface PlatformConfigurationE
public Collection<String> warnings();
/**
+ * @return Platform logger.
+ */
+ public PlatformLogger logger();
++
++ /**
+ * @return Available cache extensions.
+ */
+ @Nullable public Collection<PlatformCacheExtension> cacheExtensions();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b7512a4/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessor.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b7512a4/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
index e367768,b364c4a..548145e
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
@@@ -120,8 -126,8 +127,11 @@@ public class PlatformProcessorImpl exte
platformCtx = new PlatformContextImpl(ctx, interopCfg.gate(), interopCfg.memory(), interopCfg.platform());
+ // Initialize cache extensions (if any).
+ cacheExts = prepareCacheExtensions(interopCfg.cacheExtensions());
++
+ if (interopCfg.logger() != null)
+ interopCfg.logger().setContext(platformCtx);
}
/** {@inheritDoc} */
@@@ -417,61 -423,16 +427,68 @@@
IgniteCacheProxy cache = (IgniteCacheProxy)ctx.grid().getOrCreateNearCache(cacheName, cfg);
- return new PlatformCache(platformCtx, cache.keepBinary(), false);
+ return createPlatformCache(cache);
+ }
+
+ /**
+ * Creates new platform cache.
+ */
+ private PlatformTarget createPlatformCache(IgniteCacheProxy cache) {
+ return new PlatformCache(platformCtx, cache, false, cacheExts);
}
+ /** {@inheritDoc} */
+ @Override public boolean loggerIsLevelEnabled(int level) {
+ IgniteLogger log = ctx.grid().log();
+
+ switch (level) {
+ case PlatformLogger.LVL_TRACE:
+ return log.isTraceEnabled();
+ case PlatformLogger.LVL_DEBUG:
+ return log.isDebugEnabled();
+ case PlatformLogger.LVL_INFO:
+ return log.isInfoEnabled();
+ case PlatformLogger.LVL_WARN:
+ return true;
+ case PlatformLogger.LVL_ERROR:
+ return true;
+ default:
+ assert false;
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void loggerLog(int level, String message, String category, String errorInfo) {
+ IgniteLogger log = ctx.grid().log();
+
+ if (category != null)
+ log = log.getLogger(category);
+
+ Throwable err = errorInfo == null ? null : new IgniteException("Platform error:" + errorInfo);
+
+ switch (level) {
+ case PlatformLogger.LVL_TRACE:
+ log.trace(message);
+ break;
+ case PlatformLogger.LVL_DEBUG:
+ log.debug(message);
+ break;
+ case PlatformLogger.LVL_INFO:
+ log.info(message);
+ break;
+ case PlatformLogger.LVL_WARN:
+ log.warning(message, err);
+ break;
+ case PlatformLogger.LVL_ERROR:
+ log.error(message, err);
+ break;
+ default:
+ assert false;
+ }
+ }
+
/**
* Gets the near cache config.
*
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b7512a4/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cpp/PlatformCppConfigurationEx.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cpp/PlatformCppConfigurationEx.java
index 75c48ef,931a18e..4f6bb2d
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cpp/PlatformCppConfigurationEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cpp/PlatformCppConfigurationEx.java
@@@ -17,8 -17,8 +17,9 @@@
package org.apache.ignite.internal.processors.platform.cpp;
+import org.apache.ignite.internal.logger.platform.PlatformLogger;
import org.apache.ignite.internal.processors.platform.PlatformConfigurationEx;
+ import org.apache.ignite.internal.processors.platform.cache.PlatformCacheExtension;
import org.apache.ignite.internal.processors.platform.callback.PlatformCallbackGateway;
import org.apache.ignite.internal.processors.platform.memory.PlatformMemoryManagerImpl;
import org.apache.ignite.internal.processors.platform.utils.PlatformUtils;
@@@ -75,10 -76,10 +77,15 @@@ public class PlatformCppConfigurationE
}
/** {@inheritDoc} */
+ @Override public PlatformLogger logger() {
+ return null;
+ }
+
++ /** {@inheritDoc} */
+ @Override @Nullable public Collection<PlatformCacheExtension> cacheExtensions() {
+ return null;
+ }
+
/**
* @param warnings Warnings.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b7512a4/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationEx.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationEx.java
index 906080e,78fb755..34e7ce2
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationEx.java
@@@ -17,8 -17,8 +17,9 @@@
package org.apache.ignite.internal.processors.platform.dotnet;
+import org.apache.ignite.internal.logger.platform.PlatformLogger;
import org.apache.ignite.internal.processors.platform.PlatformConfigurationEx;
+ import org.apache.ignite.internal.processors.platform.cache.PlatformCacheExtension;
import org.apache.ignite.internal.processors.platform.callback.PlatformCallbackGateway;
import org.apache.ignite.internal.processors.platform.memory.PlatformMemoryManagerImpl;
import org.apache.ignite.internal.processors.platform.utils.PlatformUtils;
@@@ -79,10 -78,10 +83,15 @@@ public class PlatformDotNetConfiguratio
}
/** {@inheritDoc} */
+ @Override public PlatformLogger logger() {
+ return logger;
+ }
+
++ /** {@inheritDoc} */
+ @Nullable @Override public Collection<PlatformCacheExtension> cacheExtensions() {
+ return Collections.<PlatformCacheExtension>singleton(new PlatformDotNetSessionCacheExtension());
+ }
+
/**
* @param warnings Warnings.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b7512a4/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
----------------------------------------------------------------------
diff --cc modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
index 1d7b245,b1e0dbe..aa74939
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
@@@ -53,28 -49,11 +53,26 @@@
<Reference Include="System.configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
- <Reference Include="System.Web" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.XML" />
+ <Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="Binary\BinaryReaderWriterTest.cs" />
+ <Compile Include="Binary\IO\BinaryStreamsTest.cs" />
+ <Compile Include="Binary\JavaTypeMappingTest.cs" />
+ <Compile Include="Binary\TypeResolverTest.cs" />
+ <Compile Include="Cache\Affinity\AffinityKeyTest.cs" />
+ <Compile Include="Cache\Affinity\AffinityTopologyVersionTest.cs" />
+ <Compile Include="Cache\CacheResultTest.cs" />
+ <Compile Include="Cache\Store\CacheStoreAdapterTest.cs" />
+ <Compile Include="Collections\MultiValueDictionaryTest.cs" />
+ <Compile Include="Collections\ReadOnlyCollectionTest.cs" />
+ <Compile Include="Collections\ReadOnlyDictionaryTest.cs" />
+ <Compile Include="Common\IgniteGuidTest.cs" />
+ <Compile Include="Log\DefaultLoggerTest.cs" />
+ <Compile Include="Log\NLogLoggerTest.cs" />
<Compile Include="TestAppConfig.cs" />
- <Compile Include="AspNet\IgniteOutputCacheProviderTest.cs" />
<Compile Include="Binary\BinaryBuilderSelfTestFullFooter.cs" />
<Compile Include="Binary\BinaryCompactFooterInteropTest.cs" />
<Compile Include="Binary\BinarySelfTestFullFooter.cs" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b7512a4/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b7512a4/modules/platforms/dotnet/Apache.Ignite.sln
----------------------------------------------------------------------
diff --cc modules/platforms/dotnet/Apache.Ignite.sln
index b2dd535,8a3bf04..1f5163d
--- a/modules/platforms/dotnet/Apache.Ignite.sln
+++ b/modules/platforms/dotnet/Apache.Ignite.sln
@@@ -36,8 -36,8 +36,10 @@@ Project("{FAE04EC0-301F-11D3-BF4B-00C04
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Ignite.AspNet", "Apache.Ignite.AspNet\Apache.Ignite.AspNet.csproj", "{13EA96FC-CC83-4164-A7C0-4F30ED797460}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Ignite.NLog", "Apache.Ignite.NLog\Apache.Ignite.NLog.csproj", "{C6B58E4A-A2E9-4554-AD02-68CE6DA5CFB7}"
+EndProject
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Ignite.AspNet.Tests", "Apache.Ignite.AspNet.Tests\Apache.Ignite.AspNet.Tests.csproj", "{18EA4C71-A11D-4AB1-8042-418F7559D84F}"
+ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@@ -176,18 -176,18 +178,30 @@@
{13EA96FC-CC83-4164-A7C0-4F30ED797460}.Release|x64.Build.0 = Release|Any CPU
{13EA96FC-CC83-4164-A7C0-4F30ED797460}.Release|x86.ActiveCfg = Release|Any CPU
{13EA96FC-CC83-4164-A7C0-4F30ED797460}.Release|x86.Build.0 = Release|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Debug|x64.Build.0 = Debug|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Debug|x86.Build.0 = Debug|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Release|x64.ActiveCfg = Release|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Release|x64.Build.0 = Release|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Release|x86.ActiveCfg = Release|Any CPU
+ {18EA4C71-A11D-4AB1-8042-418F7559D84F}.Release|x86.Build.0 = Release|Any CPU
+ {C6B58E4A-A2E9-4554-AD02-68CE6DA5CFB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C6B58E4A-A2E9-4554-AD02-68CE6DA5CFB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C6B58E4A-A2E9-4554-AD02-68CE6DA5CFB7}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C6B58E4A-A2E9-4554-AD02-68CE6DA5CFB7}.Debug|x64.Build.0 = Debug|Any CPU
+ {C6B58E4A-A2E9-4554-AD02-68CE6DA5CFB7}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C6B58E4A-A2E9-4554-AD02-68CE6DA5CFB7}.Debug|x86.Build.0 = Debug|Any CPU
+ {C6B58E4A-A2E9-4554-AD02-68CE6DA5CFB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C6B58E4A-A2E9-4554-AD02-68CE6DA5CFB7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C6B58E4A-A2E9-4554-AD02-68CE6DA5CFB7}.Release|x64.ActiveCfg = Release|Any CPU
+ {C6B58E4A-A2E9-4554-AD02-68CE6DA5CFB7}.Release|x64.Build.0 = Release|Any CPU
+ {C6B58E4A-A2E9-4554-AD02-68CE6DA5CFB7}.Release|x86.ActiveCfg = Release|Any CPU
+ {C6B58E4A-A2E9-4554-AD02-68CE6DA5CFB7}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE