├── .gitignore
├── Build.cmd
├── LICENSE
├── Orleans.Storage.MongoDB.sln
├── Orleans.Storage.MongoDB
├── .nuget
│ ├── NuGet.Config
│ ├── NuGet.exe
│ └── NuGet.targets
├── JsonConverter.cs
├── MongoDBStorage.cs
├── Orleans.Storage.MongoDB.csproj
├── Orleans.Storage.MongoDB.nuspec
├── Properties
│ └── AssemblyInfo.cs
└── packages.config
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Dd]ebugPublic/
12 | [Rr]elease/
13 | [Rr]eleases/
14 | x64/
15 | x86/
16 | build/
17 | bld/
18 | [Bb]in/
19 | [Oo]bj/
20 |
21 | # Roslyn cache directories
22 | *.ide/
23 |
24 | # MSTest test Results
25 | [Tt]est[Rr]esult*/
26 | [Bb]uild[Ll]og.*
27 |
28 | #NUNIT
29 | *.VisualState.xml
30 | TestResult.xml
31 |
32 | # Build Results of an ATL Project
33 | [Dd]ebugPS/
34 | [Rr]eleasePS/
35 | dlldata.c
36 |
37 | *_i.c
38 | *_p.c
39 | *_i.h
40 | *.ilk
41 | *.meta
42 | *.obj
43 | *.pch
44 | *.pdb
45 | *.pgc
46 | *.pgd
47 | *.rsp
48 | *.sbr
49 | *.tlb
50 | *.tli
51 | *.tlh
52 | *.tmp
53 | *.tmp_proj
54 | *.log
55 | *.vspscc
56 | *.vssscc
57 | .builds
58 | *.pidb
59 | *.svclog
60 | *.scc
61 |
62 | # Chutzpah Test files
63 | _Chutzpah*
64 |
65 | # Visual C++ cache files
66 | ipch/
67 | *.aps
68 | *.ncb
69 | *.opensdf
70 | *.sdf
71 | *.cachefile
72 |
73 | # Visual Studio profiler
74 | *.psess
75 | *.vsp
76 | *.vspx
77 |
78 | # TFS 2012 Local Workspace
79 | $tf/
80 |
81 | # Guidance Automation Toolkit
82 | *.gpState
83 |
84 | # ReSharper is a .NET coding add-in
85 | _ReSharper*/
86 | *.[Rr]e[Ss]harper
87 | *.DotSettings.user
88 |
89 | # JustCode is a .NET coding addin-in
90 | .JustCode
91 |
92 | # TeamCity is a build add-in
93 | _TeamCity*
94 |
95 | # DotCover is a Code Coverage Tool
96 | *.dotCover
97 |
98 | # NCrunch
99 | _NCrunch_*
100 | .*crunch*.local.xml
101 |
102 | # MightyMoose
103 | *.mm.*
104 | AutoTest.Net/
105 |
106 | # Web workbench (sass)
107 | .sass-cache/
108 |
109 | # Installshield output folder
110 | [Ee]xpress/
111 |
112 | # DocProject is a documentation generator add-in
113 | DocProject/buildhelp/
114 | DocProject/Help/*.HxT
115 | DocProject/Help/*.HxC
116 | DocProject/Help/*.hhc
117 | DocProject/Help/*.hhk
118 | DocProject/Help/*.hhp
119 | DocProject/Help/Html2
120 | DocProject/Help/html
121 |
122 | # Click-Once directory
123 | publish/
124 |
125 | # Publish Web Output
126 | *.[Pp]ublish.xml
127 | *.azurePubxml
128 | # TODO: Comment the next line if you want to checkin your web deploy settings
129 | # but database connection strings (with potential passwords) will be unencrypted
130 | *.pubxml
131 | *.publishproj
132 |
133 | # NuGet Packages
134 | *.nupkg
135 | # The packages folder can be ignored because of Package Restore
136 | **/packages/*
137 | # except build/, which is used as an MSBuild target.
138 | !**/packages/build/
139 | # If using the old MSBuild-Integrated Package Restore, uncomment this:
140 | #!**/packages/repositories.config
141 |
142 | # Windows Azure Build Output
143 | csx/
144 | *.build.csdef
145 |
146 | # Windows Store app package directory
147 | AppPackages/
148 |
149 | # Others
150 | sql/
151 | *.Cache
152 | ClientBin/
153 | [Ss]tyle[Cc]op.*
154 | ~$*
155 | *~
156 | *.dbmdl
157 | *.dbproj.schemaview
158 | *.pfx
159 | *.publishsettings
160 | node_modules/
161 |
162 | # RIA/Silverlight projects
163 | Generated_Code/
164 |
165 | # Backup & report files from converting an old project file
166 | # to a newer Visual Studio version. Backup files are not needed,
167 | # because we have git ;-)
168 | _UpgradeReport_Files/
169 | Backup*/
170 | UpgradeLog*.XML
171 | UpgradeLog*.htm
172 |
173 | # SQL Server files
174 | *.mdf
175 | *.ldf
176 |
177 | # Business Intelligence projects
178 | *.rdl.data
179 | *.bim.layout
180 | *.bim_*.settings
181 |
182 | # Microsoft Fakes
183 | FakesAssemblies/
184 |
--------------------------------------------------------------------------------
/Build.cmd:
--------------------------------------------------------------------------------
1 | @REM NOTE: This script must be run from a Visual Studio command prompt window
2 |
3 | @setlocal
4 | @ECHO off
5 |
6 | SET CMDHOME=%~dp0.
7 | if "%FrameworkDir%" == "" set FrameworkDir=%WINDIR%\Microsoft.NET\Framework
8 | if "%FrameworkVersion%" == "" set FrameworkVersion=v4.0.30319
9 |
10 | SET MSBUILDEXEDIR=%FrameworkDir%\%FrameworkVersion%
11 | SET MSBUILDEXE=%MSBUILDEXEDIR%\MSBuild.exe
12 | SET NUGETEXE=NUGET.exe
13 |
14 | set PROJ=%CMDHOME%\Orleans.Storage.MongoDB.sln
15 |
16 | @echo ===== Building %PROJ% =====
17 |
18 | @echo Build Debug ==============================
19 |
20 | SET CONFIGURATION=Debug
21 |
22 | "%MSBUILDEXE%" /p:Configuration=%CONFIGURATION% "%PROJ%"
23 | @if ERRORLEVEL 1 GOTO :ErrorStop
24 | @echo BUILD ok for %CONFIGURATION% %PROJ%
25 |
26 | @echo Build Release ============================
27 |
28 | SET CONFIGURATION=Release
29 |
30 | "%MSBUILDEXE%" /p:Configuration=%CONFIGURATION% "%PROJ%"
31 | @if ERRORLEVEL 1 GOTO :ErrorStop
32 | @echo BUILD ok for %CONFIGURATION% %PROJ%
33 | @echo ===== wait for generate nupkg =====
34 | del %CMDHOME%\*.nupkg
35 | "%NUGETEXE%" pack Orleans.Storage.MongoDB\Orleans.Storage.MongoDB.csproj -Prop Configuration=%CONFIGURATION%
36 | @echo ===== wait for generate nupkg =====
37 | "%NUGETEXE%" push *.nupkg -s http://10.0.0.200/
38 | @echo ===== press any key ... =====
39 | pause
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 涛
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/Orleans.Storage.MongoDB.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.31101.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orleans.Storage.MongoDB", "Orleans.Storage.MongoDB\Orleans.Storage.MongoDB.csproj", "{57A79748-F261-4098-B59B-3B0050C4C7C4}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {57A79748-F261-4098-B59B-3B0050C4C7C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {57A79748-F261-4098-B59B-3B0050C4C7C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {57A79748-F261-4098-B59B-3B0050C4C7C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {57A79748-F261-4098-B59B-3B0050C4C7C4}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/Orleans.Storage.MongoDB/.nuget/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Orleans.Storage.MongoDB/.nuget/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/witterlee/Orleans.Storage.MongoDB/1bad271c34df24ed9d69bb5172797b6b7c172704/Orleans.Storage.MongoDB/.nuget/NuGet.exe
--------------------------------------------------------------------------------
/Orleans.Storage.MongoDB/.nuget/NuGet.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildProjectDirectory)\..\
5 |
6 |
7 | false
8 |
9 |
10 | false
11 |
12 |
13 | true
14 |
15 |
16 | false
17 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget"))
31 |
32 |
33 |
34 |
35 | $(SolutionDir).nuget
36 |
37 |
38 |
39 | packages.$(MSBuildProjectName.Replace(' ', '_')).config
40 |
41 |
42 |
43 |
44 |
45 | $(PackagesProjectConfig)
46 |
47 |
48 |
49 |
50 | packages.config
51 |
52 |
53 |
54 |
55 |
56 |
57 | $(NuGetToolsPath)\NuGet.exe
58 | @(PackageSource)
59 |
60 | "$(NuGetExePath)"
61 | mono --runtime=v4.0.30319 $(NuGetExePath)
62 |
63 | $(TargetDir.Trim('\\'))
64 |
65 | -RequireConsent
66 | -NonInteractive
67 |
68 | "$(SolutionDir) "
69 | "$(SolutionDir)"
70 |
71 |
72 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)
73 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols
74 |
75 |
76 |
77 | RestorePackages;
78 | $(BuildDependsOn);
79 |
80 |
81 |
82 |
83 | $(BuildDependsOn);
84 | BuildPackage;
85 |
86 |
87 |
88 |
89 |
90 |
91 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
113 |
115 |
116 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
148 |
149 |
150 |
151 |
152 |
--------------------------------------------------------------------------------
/Orleans.Storage.MongoDB/JsonConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using Newtonsoft.Json;
8 | using Newtonsoft.Json.Converters;
9 |
10 | namespace Orleans.Storage.MongoDB
11 | {
12 | public class UnixDateTimeConverter : DateTimeConverterBase
13 | {
14 | private DateTime initialTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
15 |
16 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
17 | {
18 | if (value is DateTime)
19 | {
20 | DateTime currentValue = ((DateTime)value).ToUniversalTime();
21 | TimeSpan span = currentValue - initialTime;
22 | writer.WriteValue(span.TotalSeconds);
23 | }
24 | else
25 | throw new ArgumentException("Must provide a valid datetime struct", "value");
26 |
27 | }
28 |
29 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
30 | {
31 | try
32 | {
33 | long ticks = Convert.ToInt64(reader.Value);
34 | return initialTime.AddSeconds(ticks);
35 | }
36 | catch { }
37 |
38 | try
39 | {
40 | return Convert.ToDateTime(reader.Value.ToString());
41 | }
42 | catch { }
43 |
44 | if (objectType == typeof(DateTime?)) return null;
45 | else
46 | throw new Exception("can not read value from json");
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Orleans.Storage.MongoDB/MongoDBStorage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Threading.Tasks;
4 | using MongoDB.Bson;
5 | using MongoDB.Bson.Serialization;
6 | using MongoDB.Driver;
7 | using Newtonsoft.Json;
8 | using Orleans.Providers;
9 | using Orleans.Runtime;
10 | using MongoDBBson = MongoDB.Bson;
11 | using System.Collections.Concurrent;
12 | using System.Collections.Generic;
13 |
14 |
15 | namespace Orleans.Storage.MongoDB
16 | {
17 | ///
18 | /// A MongoDB storage provider.
19 | ///
20 | ///
21 | /// The storage provider should be included in a deployment by adding this line to the Orleans server configuration file:
22 | ///
23 | ///
24 | /// and this line to any grain that uses it:
25 | ///
26 | /// [StorageProvider(ProviderName = "MongoDBStore")]
27 | ///
28 | /// The name 'MongoDBStore' is an arbitrary choice.
29 | ///
30 | public class MongoDBStorage : IStorageProvider
31 | {
32 | private const string DATA_CONNECTION_STRING = "ConnectionString";
33 | private const string DATABASE_NAME_PROPERTY = "Database";
34 | private const string DELETE_ON_CLEAR_PROPERTY = "DeleteStateOnClear";
35 | private const string USE_GUID_AS_STORAGE_KEY = "UseGuidAsStorageKey";
36 | private const string USE_ONE_COLLECTION = "UseOneCollection";
37 |
38 | ///
39 | /// Logger object
40 | ///
41 | public Logger Log { get; protected set; }
42 | ///
43 | /// Database name
44 | ///
45 | public string Name { get; set; }
46 |
47 | ///
48 | /// Database connection string
49 | ///
50 | public string ConnectionString { get; set; }
51 |
52 | ///
53 | /// Database name
54 | ///
55 | public string Database { get; set; }
56 |
57 | ///
58 | /// use grain's guid key as the storage key,default is true
59 | /// default is true,use guid as the storeage key, else false use like GrainReference=40011c8c7bcc4141b3569464533a06a203ffffff9c20d2b7 as the key
60 | ///
61 | public bool UseGuidAsStorageKey { get; protected set; }
62 |
63 | ///
64 | /// Initializes the storage provider.
65 | ///
66 | /// The name of this provider instance.
67 | /// A Orleans runtime object managing all storage providers.
68 | /// Configuration info for this provider instance.
69 | /// Completion promise for this operation.
70 | public Task Init(string name, IProviderRuntime providerRuntime, IProviderConfiguration config)
71 | {
72 | Log = providerRuntime.GetLogger(this.GetType().FullName);
73 |
74 | this.Name = name;
75 |
76 | if (!config.Properties.ContainsKey(DATA_CONNECTION_STRING) ||
77 | !config.Properties.ContainsKey(DATABASE_NAME_PROPERTY))
78 | {
79 | throw new ArgumentException("ConnectionString Or Database property not set");
80 | }
81 |
82 | this.ConnectionString = config.Properties[DATA_CONNECTION_STRING];
83 | this.Database = config.Properties[DATABASE_NAME_PROPERTY];
84 |
85 | this.UseGuidAsStorageKey = !config.Properties.ContainsKey(USE_GUID_AS_STORAGE_KEY) ||
86 | "true".Equals(config.Properties[USE_GUID_AS_STORAGE_KEY],
87 | StringComparison.OrdinalIgnoreCase);
88 |
89 | DataManager = new GrainStateMongoDataManager(Database, ConnectionString);
90 |
91 | return TaskDone.Done;
92 | }
93 | private GrainStateMongoDataManager DataManager { get; set; }
94 | ///
95 | /// Closes the storage provider during silo shutdown.
96 | ///
97 | /// Completion promise for this operation.
98 | public Task Close()
99 | {
100 | DataManager = null;
101 | return TaskDone.Done;
102 | }
103 |
104 | ///
105 | /// Reads persisted state from the backing store and deserializes it into the the target
106 | /// grain state object.
107 | ///
108 | /// A string holding the name of the grain class.
109 | /// Represents the long-lived identity of the grain.
110 | /// A reference to an object to hold the persisted state of the grain.
111 | /// Completion promise for this operation.
112 | public async Task ReadStateAsync(string grainType, GrainReference grainReference, GrainState grainState)
113 | {
114 | if (DataManager == null) throw new ArgumentException("DataManager property not initialized");
115 |
116 | string extendKey;
117 |
118 | var key = this.UseGuidAsStorageKey ? grainReference.GetPrimaryKey(out extendKey).ToString() : grainReference.ToKeyString();
119 |
120 | var entityData = await DataManager.ReadAsync(grainType, key);
121 |
122 | if (!string.IsNullOrEmpty(entityData))
123 | {
124 | ConvertFromStorageFormat(grainState, entityData);
125 | }
126 | }
127 |
128 | ///
129 | /// Writes the persisted state from a grain state object into its backing store.
130 | ///
131 | /// A string holding the name of the grain class.
132 | /// Represents the long-lived identity of the grain.
133 | /// A reference to an object holding the persisted state of the grain.
134 | /// Completion promise for this operation.
135 | public Task WriteStateAsync(string grainType, GrainReference grainReference, GrainState grainState)
136 | {
137 | if (DataManager == null) throw new ArgumentException("DataManager property not initialized");
138 |
139 | string extendKey;
140 |
141 | var key = this.UseGuidAsStorageKey ? grainReference.GetPrimaryKey(out extendKey).ToString() : grainReference.ToKeyString();
142 |
143 | return DataManager.WriteAsync(grainType, key, grainState);
144 | }
145 |
146 | ///
147 | /// Removes grain state from its backing store, if found.
148 | ///
149 | /// A string holding the name of the grain class.
150 | /// Represents the long-lived identity of the grain.
151 | /// An object holding the persisted state of the grain.
152 | ///
153 | public Task ClearStateAsync(string grainType, GrainReference grainReference, GrainState grainState)
154 | {
155 | if (DataManager == null) throw new ArgumentException("DataManager property not initialized");
156 |
157 | string extendKey;
158 |
159 | var key = this.UseGuidAsStorageKey ? grainReference.GetPrimaryKey(out extendKey).ToString() : grainReference.ToKeyString();
160 |
161 | return DataManager.DeleteAsync(grainType, key);
162 | }
163 |
164 | ///
165 | /// Constructs a grain state instance by deserializing a JSON document.
166 | ///
167 | /// Grain state to be populated for storage.
168 | /// JSON storage format representaiton of the grain state.
169 | protected static void ConvertFromStorageFormat(GrainState grainState, string entityData)
170 | {
171 | object data = JsonConvert.DeserializeObject(entityData, grainState.GetType(), GrainStateMongoDataManager.JsonSetting);
172 | var dict = ((GrainState)data).AsDictionary();
173 | grainState.SetAll(dict);
174 | }
175 | }
176 |
177 | ///
178 | /// Interfaces with a MongoDB database driver.
179 | ///
180 | internal class GrainStateMongoDataManager
181 | {
182 | private static ConcurrentDictionary registerIndexMap = new ConcurrentDictionary();
183 |
184 | public static JsonSerializerSettings JsonSetting = new JsonSerializerSettings()
185 | {
186 | NullValueHandling = NullValueHandling.Ignore,
187 | Converters = new List() { new UnixDateTimeConverter() }
188 | };
189 | ///
190 | /// Constructor
191 | ///
192 | /// A database name.
193 | /// A MongoDB database connection string.
194 | public GrainStateMongoDataManager(string databaseName, string connectionString)
195 | {
196 | MongoClient client = new MongoClient(connectionString);
197 | _database = client.GetDatabase(databaseName);
198 | }
199 |
200 | ///
201 | /// Deletes a file representing a grain state object.
202 | ///
203 | /// The type of the grain state object.
204 | /// The grain id string.
205 | /// Completion promise for this operation.
206 | public Task DeleteAsync(string collectionName, string key)
207 | {
208 | var collection = _database.GetCollection(collectionName);
209 | if (collection == null)
210 | return TaskDone.Done;
211 |
212 | var query = BsonDocument.Parse("{key:\"" + key + "\"}");
213 | collection.FindOneAndDeleteAsync(query);
214 |
215 | return TaskDone.Done;
216 | }
217 |
218 | ///
219 | /// Reads a file representing a grain state object.
220 | ///
221 | /// The type of the grain state object.
222 | /// The grain id string.
223 | /// Completion promise for this operation.
224 | public async Task ReadAsync(string collectionName, string key)
225 | {
226 | var collection = await GetCollection(collectionName);
227 |
228 | if (collection == null)
229 | return null;
230 |
231 | var query = BsonDocument.Parse("{__key:\"" + key + "\"}");
232 | using (var cursor = await collection.FindAsync(query))
233 | {
234 | var existing = (await cursor.ToListAsync()).FirstOrDefault();
235 |
236 | if (existing == null)
237 | return null;
238 |
239 | existing.Remove("_id");
240 | existing.Remove("__key");
241 |
242 | return existing.ToJson();
243 | }
244 | }
245 |
246 | ///
247 | /// Writes a file representing a grain state object.
248 | ///
249 | /// The type of the grain state object.
250 | /// The grain id string.
251 | /// The grain state data to be stored./
252 | /// Completion promise for this operation.
253 | public async Task WriteAsync(string collectionName, string key, GrainState entityData)
254 | {
255 | var collection = await GetCollection(collectionName);
256 |
257 | var query = BsonDocument.Parse("{__key:\"" + key + "\"}");
258 |
259 | using (var cursor = await collection.FindAsync(query))
260 | {
261 | var existing = (await cursor.ToListAsync()).FirstOrDefault();
262 |
263 | var json = JsonConvert.SerializeObject(entityData, JsonSetting);
264 |
265 | var doc = BsonSerializer.Deserialize(json);
266 | doc["__key"] = key;
267 |
268 | if (existing != null)
269 | {
270 | doc["_id"] = existing["_id"];
271 | await collection.ReplaceOneAsync(query, doc);
272 |
273 | }
274 | else
275 | {
276 | await collection.InsertOneAsync(doc);
277 | }
278 | }
279 | }
280 |
281 | private async Task> GetCollection(string name)
282 | {
283 | var collection = _database.GetCollection(name);
284 |
285 | if (!registerIndexMap.ContainsKey(name))
286 | {
287 | using (var cursor = await collection.Indexes.ListAsync())
288 | {
289 | var indexes = await cursor.ToListAsync();
290 | if (indexes.Count(index => index["name"] == "__key_1") == 0)
291 | {
292 | var keys = Builders.IndexKeys.Ascending("__key");
293 | await collection.Indexes.CreateOneAsync(keys,
294 | new CreateIndexOptions() { Unique = true, Version = 1 });
295 | }
296 | registerIndexMap.TryAdd(name, true);
297 | }
298 | }
299 | return collection;
300 | }
301 |
302 | private readonly IMongoDatabase _database;
303 | }
304 | }
305 |
--------------------------------------------------------------------------------
/Orleans.Storage.MongoDB/Orleans.Storage.MongoDB.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {57A79748-F261-4098-B59B-3B0050C4C7C4}
8 | Library
9 | Properties
10 | Orleans.Storage.MongoDB
11 | Orleans.Storage.MongoDB
12 | v4.5
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 | False
35 | ..\packages\MongoDB.Bson.2.0.1\lib\net45\MongoDB.Bson.dll
36 |
37 |
38 | False
39 | ..\packages\MongoDB.Driver.2.0.1\lib\net45\MongoDB.Driver.dll
40 |
41 |
42 | False
43 | ..\packages\MongoDB.Driver.Core.2.0.1\lib\net45\MongoDB.Driver.Core.dll
44 |
45 |
46 | False
47 | ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll
48 |
49 |
50 | ..\packages\Microsoft.Orleans.Core.1.0.10\lib\net45\Orleans.dll
51 | True
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
84 |
--------------------------------------------------------------------------------
/Orleans.Storage.MongoDB/Orleans.Storage.MongoDB.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $id$
5 | $version$
6 | $title$
7 | $author$
8 | $author$
9 | https://github.com/weitaolee/Orleans.Storage.MongoDB/blob/master/LICENSE
10 | https://github.com/weitaolee/Orleans.Storage.MongoDB
11 | false
12 | $description$
13 | First Publish
14 | Copyright 2015
15 | Orleans Storage MongoDB
16 |
17 |
--------------------------------------------------------------------------------
/Orleans.Storage.MongoDB/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的常规信息通过以下
6 | // 特性集控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("Orleans.Storage.MongoDB")]
9 | [assembly: AssemblyDescription("Orleans MongoDB Storage Provider")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("Orleans.Storage.MongoDB")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 使此程序集中的类型
18 | // 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
19 | // 则将该类型上的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("6b263fbc-443a-40c4-8723-e5599cae92ce")]
24 |
25 | // 程序集的版本信息由下面四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
33 | // 方法是按如下所示使用“*”:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.*")]
36 |
--------------------------------------------------------------------------------
/Orleans.Storage.MongoDB/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Orleans.Storage.MongoDB
2 | Orleans Storage MongoDB Provider
3 |
4 | ## USE CASE
5 |
6 | ###### 1. ServerConfiguration.xml
7 | ```xml
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | ```
19 |
20 | If you have MongoDB running on your local machine, then this should work with no modifications.
21 |
22 | If you have MongoDB running on a remote machine, then you will have to update "localhost" to match the machine name.
23 |
24 | ###### 2. Code
25 | ```csharp
26 | [StorageProvider(ProviderName = "MongoDBStorage")]
27 | public class BankAccount : IGrain,IBankAccount
28 | {
29 | }
30 | ```
31 |
--------------------------------------------------------------------------------