mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-06-26 13:03:13 +00:00
1.6.1
This commit is contained in:
@ -40,7 +40,7 @@ namespace Esiur.Stores.EntityCore
|
|||||||
//internal object _PrimaryId;
|
//internal object _PrimaryId;
|
||||||
|
|
||||||
public event DestroyedEvent OnDestroy;
|
public event DestroyedEvent OnDestroy;
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
//public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public Instance Instance { get; set; }
|
public Instance Instance { get; set; }
|
||||||
@ -66,7 +66,7 @@ namespace Esiur.Stores.EntityCore
|
|||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
//throw new NotImplementedException();
|
OnDestroy?.Invoke(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,31 +45,25 @@ namespace Esiur.Stores.EntityCore
|
|||||||
Dictionary<Type, Dictionary<object, WeakReference>> DB = new Dictionary<Type, Dictionary<object, WeakReference>>();
|
Dictionary<Type, Dictionary<object, WeakReference>> DB = new Dictionary<Type, Dictionary<object, WeakReference>>();
|
||||||
object DBLock = new object();
|
object DBLock = new object();
|
||||||
|
|
||||||
internal struct TypeInfo
|
Dictionary<string, EntityTypeInfo> TypesByName = new Dictionary<string, EntityTypeInfo>();
|
||||||
{
|
internal Dictionary<Type, EntityTypeInfo> TypesByType = new Dictionary<Type, EntityTypeInfo>();
|
||||||
public string Name;
|
|
||||||
public IEntityType Type;
|
|
||||||
public PropertyInfo PrimaryKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dictionary<string, TypeInfo> TypesByName = new Dictionary<string, TypeInfo>();
|
[Attribute]
|
||||||
internal Dictionary<Type, TypeInfo> TypesByType = new Dictionary<Type, TypeInfo>();
|
public Func<DbContext> Getter { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Loaded;
|
|
||||||
|
|
||||||
public AsyncReply<IResource> Get(string path)
|
public AsyncReply<IResource> Get(string path)
|
||||||
{
|
{
|
||||||
var p = path.Split('/');
|
var p = path.Split('/');
|
||||||
var ti = TypesByName[p[0]];
|
var ti = TypesByName[p[0]];
|
||||||
var id = Convert.ChangeType(p[1], ti.PrimaryKey.PropertyType);// Convert.ToInt32();
|
var id = Convert.ChangeType(p[1], ti.PrimaryKey.PropertyType);
|
||||||
|
|
||||||
|
// Get db
|
||||||
var db = DbContextProvider();
|
var db = Getter();
|
||||||
var res = db.Find(ti.Type.ClrType, id);
|
var res = db.Find(ti.Type.ClrType, id);
|
||||||
var ent = db.Entry(res);
|
|
||||||
|
|
||||||
|
// load navigation properties
|
||||||
|
var ent = db.Entry(res);
|
||||||
foreach (var rf in ent.References)
|
foreach (var rf in ent.References)
|
||||||
rf.Load();
|
rf.Load();
|
||||||
|
|
||||||
@ -78,12 +72,11 @@ namespace Esiur.Stores.EntityCore
|
|||||||
|
|
||||||
public AsyncReply<bool> Put(IResource resource)
|
public AsyncReply<bool> Put(IResource resource)
|
||||||
{
|
{
|
||||||
if (resource is EntityStore)
|
if (resource == this)
|
||||||
return new AsyncReply<bool>(true);
|
return new AsyncReply<bool>(true);
|
||||||
|
|
||||||
var type = ResourceProxy.GetBaseType(resource);//.GetType().;
|
var type = ResourceProxy.GetBaseType(resource);
|
||||||
|
|
||||||
//var eid = (resource as EntityResource)._PrimaryId;// (int)resource.Instance.Variables["eid"];
|
|
||||||
|
|
||||||
var eid = TypesByType[type].PrimaryKey.GetValue(resource);
|
var eid = TypesByType[type].PrimaryKey.GetValue(resource);
|
||||||
|
|
||||||
@ -112,11 +105,12 @@ namespace Esiur.Stores.EntityCore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Attribute]
|
|
||||||
public Func<DbContext> DbContextProvider { get; set; }
|
|
||||||
|
|
||||||
[Attribute]
|
|
||||||
public DbContextOptionsBuilder Options { get; set; }
|
//public T CreateDB()
|
||||||
|
//{
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
//DbContext dbContext;
|
//DbContext dbContext;
|
||||||
//[Attribute]
|
//[Attribute]
|
||||||
@ -195,13 +189,17 @@ namespace Esiur.Stores.EntityCore
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal DbContextOptions Options { get; set; }
|
||||||
|
|
||||||
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
||||||
{
|
{
|
||||||
if (trigger == ResourceTrigger.Initialize)// SystemInitialized && DbContext != null)
|
if (trigger == ResourceTrigger.Initialize)// SystemInitialized && DbContext != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (DbContextProvider == null)
|
if (Getter == null)
|
||||||
DbContextProvider = () => Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext;
|
throw new Exception("Getter is not set for the store.");
|
||||||
|
// DbContextProvider = () => Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext;
|
||||||
|
|
||||||
|
|
||||||
ReloadModel();
|
ReloadModel();
|
||||||
}
|
}
|
||||||
@ -209,21 +207,23 @@ namespace Esiur.Stores.EntityCore
|
|||||||
return new AsyncReply<bool>(true);
|
return new AsyncReply<bool>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReloadModel()
|
void ReloadModel()
|
||||||
{
|
{
|
||||||
|
|
||||||
TypesByName.Clear();
|
TypesByName.Clear();
|
||||||
TypesByType.Clear();
|
TypesByType.Clear();
|
||||||
|
|
||||||
var context = DbContextProvider();// Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext;
|
var context = Getter();
|
||||||
|
|
||||||
var types = context.Model.GetEntityTypes();
|
var types = context.Model.GetEntityTypes();
|
||||||
foreach (var t in types)
|
foreach (var t in types)
|
||||||
{
|
{
|
||||||
var ti = new TypeInfo()
|
var ti = new EntityTypeInfo()
|
||||||
{
|
{
|
||||||
Name = t.ClrType.Name,
|
Name = t.ClrType.Name,
|
||||||
PrimaryKey = t.FindPrimaryKey().Properties.FirstOrDefault()?.PropertyInfo,
|
PrimaryKey = t.FindPrimaryKey().Properties.FirstOrDefault()?.PropertyInfo,
|
||||||
Type = t
|
Type = t,
|
||||||
|
//Getter = getter
|
||||||
};
|
};
|
||||||
|
|
||||||
TypesByName.Add(t.ClrType.Name, ti);
|
TypesByName.Add(t.ClrType.Name, ti);
|
||||||
@ -236,7 +236,7 @@ namespace Esiur.Stores.EntityCore
|
|||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
//throw new NotImplementedException();
|
OnDestroy?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
17
Esiur.Stores.EntityCore/EntityTypeInfo.cs
Normal file
17
Esiur.Stores.EntityCore/EntityTypeInfo.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Stores.EntityCore
|
||||||
|
{
|
||||||
|
struct EntityTypeInfo
|
||||||
|
{
|
||||||
|
public string Name;
|
||||||
|
public IEntityType Type;
|
||||||
|
public PropertyInfo PrimaryKey;
|
||||||
|
// public Func<DbContext> Getter;
|
||||||
|
}
|
||||||
|
}
|
@ -9,10 +9,11 @@
|
|||||||
<Product>Esiur Entity Framework Extension</Product>
|
<Product>Esiur Entity Framework Extension</Product>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<PackageId>Esiur.Stores.EntityCore</PackageId>
|
<PackageId>Esiur.Stores.EntityCore</PackageId>
|
||||||
|
<Version>1.0.2</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.2" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.6" />
|
||||||
<PackageReference Include="System.Collections" Version="4.3.0" />
|
<PackageReference Include="System.Collections" Version="4.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ using System.Linq;
|
|||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Esiur.Proxy;
|
using Esiur.Proxy;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Esiur.Stores.EntityCore
|
namespace Esiur.Stores.EntityCore
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,9 @@ SOFTWARE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using Esiur.Core;
|
using Esiur.Core;
|
||||||
|
using Esiur.Data;
|
||||||
|
using Esiur.Misc;
|
||||||
|
using Esiur.Proxy;
|
||||||
using Esiur.Resource;
|
using Esiur.Resource;
|
||||||
using Esiur.Security.Permissions;
|
using Esiur.Security.Permissions;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@ -31,6 +34,7 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Esiur.Stores.EntityCore
|
namespace Esiur.Stores.EntityCore
|
||||||
@ -43,49 +47,108 @@ namespace Esiur.Stores.EntityCore
|
|||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public static T AddResource<T>(this DbSet<T> dbSet, object properties = null) where T : class, IResource
|
public static T AddResource<T>(this DbSet<T> dbSet, T resource) where T : class, IResource
|
||||||
=> AddResourceAsync(dbSet, properties).Wait();
|
=> AddResourceAsync(dbSet, resource).Wait();
|
||||||
|
|
||||||
public static async AsyncReply<T> AddResourceAsync<T>(this DbSet<T> dbSet, object properties = null) where T : class, IResource
|
public static async AsyncReply<T> AddResourceAsync<T>(this DbSet<T> dbSet, T resource) where T : class, IResource
|
||||||
{
|
{
|
||||||
var store = dbSet.GetInfrastructure().GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions>().Store;
|
var store = dbSet.GetInfrastructure().GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions>().Store;
|
||||||
|
|
||||||
|
|
||||||
var manager = store.Instance.Managers.FirstOrDefault();// > 0 ? store.Instance.Managers.First() : null;
|
var manager = store.Instance.Managers.FirstOrDefault();// > 0 ? store.Instance.Managers.First() : null;
|
||||||
|
|
||||||
//var db = dbSet.GetService<ICurrentDbContext>().Context;
|
//var db = dbSet.GetService<ICurrentDbContext>().Context;
|
||||||
|
|
||||||
//var resource = dbSet.GetInfrastructure().CreateResource<T>(properties);
|
//var resource = dbSet.GetInfrastructure().CreateResource<T>(properties);
|
||||||
//var resource = Warehouse.New<T>("", options.Store, null, null, null, properties);
|
//var resource = Warehouse.New<T>("", options.Store, null, null, null, properties);
|
||||||
var resource = await Warehouse.New<T>("", null, null, null, null, properties);
|
|
||||||
var entity = dbSet.Add(resource);
|
var resType = typeof(T);
|
||||||
|
var proxyType = ResourceProxy.GetProxy(resType);
|
||||||
|
|
||||||
|
|
||||||
|
IResource res;
|
||||||
|
|
||||||
|
if (proxyType == resType)
|
||||||
|
{
|
||||||
|
res = resource;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res = Activator.CreateInstance(proxyType) as IResource;
|
||||||
|
var ps = Structure.FromObject(resource);
|
||||||
|
|
||||||
|
foreach (var p in ps)
|
||||||
|
{
|
||||||
|
|
||||||
|
var mi = resType.GetMember(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (mi != null)
|
||||||
|
{
|
||||||
|
if (mi is PropertyInfo)
|
||||||
|
{
|
||||||
|
var pi = mi as PropertyInfo;
|
||||||
|
if (pi.CanWrite)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pi.SetValue(res, p.Value);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Global.Log(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mi is FieldInfo)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
(mi as FieldInfo).SetValue(res, p.Value);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Global.Log(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//await Warehouse.Put<T>("", null, null, null, null, properties);
|
||||||
|
var entity = dbSet.Add((T)res);
|
||||||
await entity.Context.SaveChangesAsync();
|
await entity.Context.SaveChangesAsync();
|
||||||
|
|
||||||
var id = store.TypesByType[typeof(T)].PrimaryKey.GetValue(resource);
|
var id = store.TypesByType[typeof(T)].PrimaryKey.GetValue(resource);
|
||||||
|
|
||||||
await Warehouse.Put(resource, id.ToString(), store, null, null, 0, manager);
|
await Warehouse.Put(id.ToString(), res, store, null, null, 0, manager);
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async AsyncReply<T> CreateResourceAsync<T>(this IServiceProvider serviceProvider, object properties = null) where T : class, IResource
|
//public static async AsyncReply<T> CreateResourceAsync<T>(this IServiceProvider serviceProvider, T properties = null) where T : class, IResource
|
||||||
{
|
//{
|
||||||
var options = serviceProvider.GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions>();
|
// var options = serviceProvider.GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions<T>>();
|
||||||
|
|
||||||
var resource = await Warehouse.New<T>("", options.Store, null, null, null, properties);
|
// var resource = await Warehouse.New<T>("", options.Store, null, null, null, properties);
|
||||||
|
|
||||||
resource.Instance.Managers.AddRange(options.Store.Instance.Managers.ToArray());
|
// resource.Instance.Managers.AddRange(options.Store.Instance.Managers.ToArray());
|
||||||
|
|
||||||
return resource;
|
// return resource;
|
||||||
}
|
//}
|
||||||
|
|
||||||
public static T CreateResource<T>(this IServiceProvider serviceProvider, object properties = null) where T : class, IResource
|
//public static T CreateResource<T>(this IServiceProvider serviceProvider, object properties = null) where T : class, IResource
|
||||||
=> CreateResourceAsync<T>(serviceProvider, properties).Wait();
|
// => CreateResourceAsync<T>(serviceProvider, properties).Wait();
|
||||||
|
|
||||||
public static DbContextOptionsBuilder UseEsiur(this DbContextOptionsBuilder optionsBuilder,
|
public static DbContextOptionsBuilder UseEsiur(this DbContextOptionsBuilder optionsBuilder,
|
||||||
//DbContext context,
|
EntityStore store,
|
||||||
string name = null,
|
Func<DbContext> getter = null
|
||||||
IResource parent = null,
|
|
||||||
IPermissionsManager manager = null,
|
//IServiceCollection services = null
|
||||||
Func<DbContext> dbContextProvider = null
|
//string name = null,
|
||||||
|
//IResource parent = null,
|
||||||
|
//IPermissionsManager manager = null,
|
||||||
|
//Func<DbContext> dbContextProvider = null
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var extension = optionsBuilder.Options.FindExtension<EsiurExtensionOptions>();
|
var extension = optionsBuilder.Options.FindExtension<EsiurExtensionOptions>();
|
||||||
@ -93,10 +156,9 @@ namespace Esiur.Stores.EntityCore
|
|||||||
if (extension == null)
|
if (extension == null)
|
||||||
{
|
{
|
||||||
|
|
||||||
var store = Warehouse.New<EntityStore>(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }).Wait();
|
//var store = Warehouse.New<EntityStore>(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }).Wait();
|
||||||
|
store.Options = optionsBuilder.Options;
|
||||||
extension = new EsiurExtensionOptions(store);
|
extension = new EsiurExtensionOptions(store);
|
||||||
//store.Options = optionsBuilder;
|
|
||||||
//store.DbContext = context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||||
@ -105,34 +167,34 @@ namespace Esiur.Stores.EntityCore
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DbContextOptionsBuilder<TContext> UseEsiur<TContext>(
|
//public static DbContextOptionsBuilder<TContext> UseEsiur<TContext>(
|
||||||
this DbContextOptionsBuilder<TContext> optionsBuilder,
|
// this DbContextOptionsBuilder<TContext> optionsBuilder,
|
||||||
//DbContext context,
|
// //DbContext context,
|
||||||
string name = null,
|
// string name = null,
|
||||||
IResource parent = null,
|
// IResource parent = null,
|
||||||
IPermissionsManager manager = null,
|
// IPermissionsManager manager = null,
|
||||||
Func<DbContext> dbContextProvider = null)
|
// Func<DbContext> dbContextProvider = null)
|
||||||
where TContext : DbContext
|
// where TContext : DbContext
|
||||||
{
|
//{
|
||||||
|
|
||||||
|
|
||||||
var extension = optionsBuilder.Options.FindExtension<EsiurExtensionOptions>();
|
// var extension = optionsBuilder.Options.FindExtension<EsiurExtensionOptions>();
|
||||||
|
|
||||||
if (extension == null)
|
// if (extension == null)
|
||||||
{
|
// {
|
||||||
var store = Warehouse.New<EntityStore>(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }).Wait();
|
// var store = Warehouse.New<EntityStore>(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }).Wait();
|
||||||
extension = new EsiurExtensionOptions(store);
|
// extension = new EsiurExtensionOptions(store);
|
||||||
//store.Options = optionsBuilder;
|
// //store.Options = optionsBuilder;
|
||||||
//store.Options = extension;
|
// //store.Options = extension;
|
||||||
//store.DbContext = context;
|
// //store.DbContext = context;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
// ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||||
|
|
||||||
return optionsBuilder;
|
// return optionsBuilder;
|
||||||
|
|
||||||
}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ namespace Esiur.Stores.EntityCore
|
|||||||
var obj = Warehouse.New(entityType.ClrType).Wait() as EntityResource;//, "", options.Store, null, manager);
|
var obj = Warehouse.New(entityType.ClrType).Wait() as EntityResource;//, "", options.Store, null, manager);
|
||||||
//obj._PrimaryId = id;
|
//obj._PrimaryId = id;
|
||||||
options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id);
|
options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id);
|
||||||
Warehouse.Put(obj, id.ToString(), options.Store, null, null, 0, manager).Wait();
|
Warehouse.Put(id.ToString(), obj, options.Store, null, null, 0, manager).Wait();
|
||||||
|
|
||||||
// obj.Instance.IntVal = id;//.Variables.Add("eid", id);
|
// obj.Instance.IntVal = id;//.Variables.Add("eid", id);
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
|
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://github.com/esiur/esiur-dotnet/</RepositoryUrl>
|
<RepositoryUrl>https://github.com/esiur/esiur-dotnet/</RepositoryUrl>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
<Version>1.4.0</Version>
|
<Version>1.4.1</Version>
|
||||||
<PackageId>Esiur.Stores.MongoDB</PackageId>
|
<PackageId>Esiur.Stores.MongoDB</PackageId>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ namespace Esiur.Core
|
|||||||
public T GetResult()
|
public T GetResult()
|
||||||
{
|
{
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
throw exception;
|
throw exception;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ namespace Esiur.Core
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Trigger(object result)
|
public AsyncReply Trigger(object result)
|
||||||
{
|
{
|
||||||
lock (asyncLock)
|
lock (asyncLock)
|
||||||
{
|
{
|
||||||
@ -202,7 +202,7 @@ namespace Esiur.Core
|
|||||||
Console.WriteLine($"AsyncReply: {Id} Trigger");
|
Console.WriteLine($"AsyncReply: {Id} Trigger");
|
||||||
|
|
||||||
if (resultReady)
|
if (resultReady)
|
||||||
return;
|
return this;
|
||||||
|
|
||||||
this.result = result;
|
this.result = result;
|
||||||
|
|
||||||
@ -219,14 +219,16 @@ namespace Esiur.Core
|
|||||||
Console.WriteLine($"AsyncReply: {Id} Trigger ended");
|
Console.WriteLine($"AsyncReply: {Id} Trigger ended");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TriggerError(Exception exception)
|
public AsyncReply TriggerError(Exception exception)
|
||||||
{
|
{
|
||||||
//timeout?.Dispose();
|
//timeout?.Dispose();
|
||||||
|
|
||||||
if (resultReady)
|
if (resultReady)
|
||||||
return;
|
return this;
|
||||||
|
|
||||||
if (exception is AsyncException)
|
if (exception is AsyncException)
|
||||||
this.exception = exception as AsyncException;
|
this.exception = exception as AsyncException;
|
||||||
@ -242,9 +244,10 @@ namespace Esiur.Core
|
|||||||
|
|
||||||
mutex?.Set();
|
mutex?.Set();
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TriggerProgress(ProgressType type, int value, int max)
|
public AsyncReply TriggerProgress(ProgressType type, int value, int max)
|
||||||
{
|
{
|
||||||
//timeout?.Dispose();
|
//timeout?.Dispose();
|
||||||
|
|
||||||
@ -254,10 +257,12 @@ namespace Esiur.Core
|
|||||||
cb(type, value, max);
|
cb(type, value, max);
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void TriggerChunk(object value)
|
public AsyncReply TriggerChunk(object value)
|
||||||
{
|
{
|
||||||
|
|
||||||
//timeout?.Dispose();
|
//timeout?.Dispose();
|
||||||
@ -269,6 +274,8 @@ namespace Esiur.Core
|
|||||||
cb(value);
|
cb(value);
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncAwaiter GetAwaiter()
|
public AsyncAwaiter GetAwaiter()
|
||||||
|
@ -36,6 +36,10 @@ namespace Esiur.Core
|
|||||||
SetPropertyDenied,
|
SetPropertyDenied,
|
||||||
ReadOnlyProperty,
|
ReadOnlyProperty,
|
||||||
GeneralFailure,
|
GeneralFailure,
|
||||||
AddToStoreFailed
|
AddToStoreFailed,
|
||||||
|
NotAttached,
|
||||||
|
AlreadyListened,
|
||||||
|
AlreadyUnlistened,
|
||||||
|
NotListenable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Esiur.Resource;
|
using Esiur.Net.IIP;
|
||||||
|
using Esiur.Resource;
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Copyright (c) 2017-2021 Ahmed Kh. Zamil
|
Copyright (c) 2017-2021 Ahmed Kh. Zamil
|
||||||
@ -53,8 +54,15 @@ namespace Esiur.Data
|
|||||||
foreach (var pt in resource.Instance.Template.Properties)
|
foreach (var pt in resource.Instance.Template.Properties)
|
||||||
{
|
{
|
||||||
var rt = pt.Info.GetValue(resource, null);
|
var rt = pt.Info.GetValue(resource, null);
|
||||||
|
if (rt is DistributedPropertyContext)
|
||||||
|
continue;
|
||||||
|
|
||||||
writer.WritePropertyName(options.PropertyNamingPolicy?.ConvertName(pt.Name) ?? pt.Name);
|
writer.WritePropertyName(options.PropertyNamingPolicy?.ConvertName(pt.Name) ?? pt.Name);
|
||||||
JsonSerializer.Serialize(writer, rt, options);
|
|
||||||
|
if (rt is IResource)
|
||||||
|
JsonSerializer.Serialize(writer, (IResource) rt, options);
|
||||||
|
else
|
||||||
|
JsonSerializer.Serialize(writer, rt, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteEndObject();
|
writer.WriteEndObject();
|
||||||
|
@ -110,6 +110,10 @@ namespace Esiur.Data
|
|||||||
foreach (var p in pi)
|
foreach (var p in pi)
|
||||||
st[p.Name] = p.GetValue(obj);
|
st[p.Name] = p.GetValue(obj);
|
||||||
|
|
||||||
|
var fi = type.GetTypeInfo().GetFields().Where(x => x.IsPublic);
|
||||||
|
foreach (var f in fi)
|
||||||
|
st[f.Name] = f.GetValue(obj);
|
||||||
|
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
//else
|
//else
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<Description>Distributed Resources Platform</Description>
|
<Description>Distributed Resources Platform</Description>
|
||||||
<Copyright>Ahmed Kh. Zamil</Copyright>
|
<Copyright>Ahmed Kh. Zamil</Copyright>
|
||||||
<PackageLicenseUrl>https://github.com/Esiur/Esiur-dotnet/blob/master/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/Esiur/Esiur-dotnet/blob/master/LICENSE</PackageLicenseUrl>
|
||||||
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
|
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Version>1.5.1</Version>
|
<Version>1.6.1</Version>
|
||||||
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
|
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
|
||||||
<Authors>Ahmed Kh. Zamil</Authors>
|
<Authors>Ahmed Kh. Zamil</Authors>
|
||||||
<AssemblyVersion>1.3.1.0</AssemblyVersion>
|
<AssemblyVersion>1.6.0</AssemblyVersion>
|
||||||
<Company>Esiur Foundation</Company>
|
<Company>Esiur Foundation</Company>
|
||||||
<FileVersion>1.3.1.0</FileVersion>
|
<FileVersion>1.6.0</FileVersion>
|
||||||
<AssemblyName>Esiur</AssemblyName>
|
<AssemblyName>Esiur</AssemblyName>
|
||||||
<RootNamespace>Esiur</RootNamespace>
|
<RootNamespace>Esiur</RootNamespace>
|
||||||
<PackageId>Esiur</PackageId>
|
<PackageId>Esiur</PackageId>
|
||||||
<Product>Esiur</Product>
|
<Product>Esiur</Product>
|
||||||
|
<LangVersion>9.0</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
@ -55,6 +56,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.9.0" />
|
||||||
<PackageReference Include="System.Diagnostics.StackTrace" Version="4.3.0" />
|
<PackageReference Include="System.Diagnostics.StackTrace" Version="4.3.0" />
|
||||||
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
|
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
|
||||||
<PackageReference Include="System.Interactive.Async" Version="5.0.0" />
|
<PackageReference Include="System.Interactive.Async" Version="5.0.0" />
|
||||||
@ -62,8 +64,12 @@
|
|||||||
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
|
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
|
||||||
<PackageReference Include="System.Net.Security" Version="4.3.2" />
|
<PackageReference Include="System.Net.Security" Version="4.3.2" />
|
||||||
<PackageReference Include="System.Reflection.Emit" Version="4.7.0" />
|
<PackageReference Include="System.Reflection.Emit" Version="4.7.0" />
|
||||||
<PackageReference Include="System.Text.Json" Version="5.0.1" />
|
<PackageReference Include="System.Text.Json" Version="5.0.2" />
|
||||||
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
|
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
|
||||||
|
|
||||||
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.9.0" PrivateAssets="all" />
|
||||||
|
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2" PrivateAssets="all" />
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
@ -69,7 +69,7 @@ namespace Esiur.Misc
|
|||||||
}catch (Exception ex)
|
}catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine(ex.ToString());
|
Console.WriteLine(ex.ToString());
|
||||||
return "";
|
return "{}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,9 +433,9 @@ namespace Esiur.Misc
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static byte[] GenerateBytes(int Length)
|
public static byte[] GenerateBytes(int length)
|
||||||
{
|
{
|
||||||
var b = new byte[Length];
|
var b = new byte[length];
|
||||||
rand.NextBytes(b);
|
rand.NextBytes(b);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ namespace Esiur.Net.DataLink
|
|||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
|
OnDestroy?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ namespace Esiur.Net.DataLink
|
|||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
OnDestroy?.Invoke(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
||||||
|
@ -69,7 +69,7 @@ namespace Esiur.Net.DataLink
|
|||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
OnDestroy?.Invoke(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -76,7 +76,7 @@ namespace Esiur.Net.HTTP
|
|||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
OnDestroy?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -112,7 +112,7 @@ namespace Esiur.Net.HTTP
|
|||||||
|
|
||||||
private void IipConnection_OnReady(DistributedConnection sender)
|
private void IipConnection_OnReady(DistributedConnection sender)
|
||||||
{
|
{
|
||||||
Warehouse.Put(sender, sender.RemoteUsername, null, sender.Server);
|
Warehouse.Put(sender.RemoteUsername, sender, null, sender.Server).Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
public override AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
||||||
|
@ -197,11 +197,20 @@ namespace Esiur.Net.IIP
|
|||||||
|
|
||||||
if (socket.State == SocketState.Established &&
|
if (socket.State == SocketState.Established &&
|
||||||
session.LocalAuthentication.Type == AuthenticationType.Client)
|
session.LocalAuthentication.Type == AuthenticationType.Client)
|
||||||
|
{
|
||||||
|
Declare();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Declare()
|
||||||
|
{
|
||||||
|
var dmn = DC.ToBytes(session.LocalAuthentication.Domain);// domain);
|
||||||
|
|
||||||
|
if (session.LocalAuthentication.Method == AuthenticationMethod.Credentials)
|
||||||
{
|
{
|
||||||
// declare (Credentials -> No Auth, No Enctypt)
|
// declare (Credentials -> No Auth, No Enctypt)
|
||||||
|
|
||||||
var un = DC.ToBytes(session.LocalAuthentication.Username);
|
var un = DC.ToBytes(session.LocalAuthentication.Username);
|
||||||
var dmn = DC.ToBytes(session.LocalAuthentication.Domain);// domain);
|
|
||||||
|
|
||||||
SendParams()
|
SendParams()
|
||||||
.AddUInt8(0x60)
|
.AddUInt8(0x60)
|
||||||
@ -212,8 +221,27 @@ namespace Esiur.Net.IIP
|
|||||||
.AddUInt8Array(un)
|
.AddUInt8Array(un)
|
||||||
.Done();//, dmn, localNonce, (byte)un.Length, un);
|
.Done();//, dmn, localNonce, (byte)un.Length, un);
|
||||||
}
|
}
|
||||||
}
|
else if (session.LocalAuthentication.Method == AuthenticationMethod.Token)
|
||||||
|
{
|
||||||
|
|
||||||
|
SendParams()
|
||||||
|
.AddUInt8(0x70)
|
||||||
|
.AddUInt8((byte)dmn.Length)
|
||||||
|
.AddUInt8Array(dmn)
|
||||||
|
.AddUInt8Array(localNonce)
|
||||||
|
.AddUInt64(session.LocalAuthentication.TokenIndex)
|
||||||
|
.Done();//, dmn, localNonce, token
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (session.LocalAuthentication.Method == AuthenticationMethod.None)
|
||||||
|
{
|
||||||
|
SendParams()
|
||||||
|
.AddUInt8(0x40)
|
||||||
|
.AddUInt8((byte)dmn.Length)
|
||||||
|
.AddUInt8Array(dmn)
|
||||||
|
.Done();//, dmn, localNonce, token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new distributed connection.
|
/// Create a new distributed connection.
|
||||||
@ -451,12 +479,21 @@ namespace Esiur.Net.IIP
|
|||||||
IIPRequestInvokeFunctionNamedArguments(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.Content);
|
IIPRequestInvokeFunctionNamedArguments(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.Content);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IIPPacket.IIPPacketAction.GetProperty:
|
//case IIPPacket.IIPPacketAction.GetProperty:
|
||||||
IIPRequestGetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex);
|
// IIPRequestGetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex);
|
||||||
|
// break;
|
||||||
|
//case IIPPacket.IIPPacketAction.GetPropertyIfModified:
|
||||||
|
// IIPRequestGetPropertyIfModifiedSince(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.ResourceAge);
|
||||||
|
// break;
|
||||||
|
|
||||||
|
case IIPPacket.IIPPacketAction.Listen:
|
||||||
|
IIPRequestListen(packet.CallbackId, packet.ResourceId, packet.MethodIndex);
|
||||||
break;
|
break;
|
||||||
case IIPPacket.IIPPacketAction.GetPropertyIfModified:
|
|
||||||
IIPRequestGetPropertyIfModifiedSince(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.ResourceAge);
|
case IIPPacket.IIPPacketAction.Unlisten:
|
||||||
|
IIPRequestUnlisten(packet.CallbackId, packet.ResourceId, packet.MethodIndex);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IIPPacket.IIPPacketAction.SetProperty:
|
case IIPPacket.IIPPacketAction.SetProperty:
|
||||||
IIPRequestSetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.Content);
|
IIPRequestSetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.Content);
|
||||||
break;
|
break;
|
||||||
@ -531,14 +568,17 @@ namespace Esiur.Net.IIP
|
|||||||
IIPReplyInvoke(packet.CallbackId, packet.Content);
|
IIPReplyInvoke(packet.CallbackId, packet.Content);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IIPPacket.IIPPacketAction.GetProperty:
|
//case IIPPacket.IIPPacketAction.GetProperty:
|
||||||
IIPReply(packet.CallbackId, packet.Content);
|
// IIPReply(packet.CallbackId, packet.Content);
|
||||||
break;
|
// break;
|
||||||
|
|
||||||
case IIPPacket.IIPPacketAction.GetPropertyIfModified:
|
//case IIPPacket.IIPPacketAction.GetPropertyIfModified:
|
||||||
IIPReply(packet.CallbackId, packet.Content);
|
// IIPReply(packet.CallbackId, packet.Content);
|
||||||
break;
|
// break;
|
||||||
case IIPPacket.IIPPacketAction.SetProperty:
|
|
||||||
|
case IIPPacketAction.Listen:
|
||||||
|
case IIPPacketAction.Unlisten:
|
||||||
|
case IIPPacketAction.SetProperty:
|
||||||
IIPReply(packet.CallbackId);
|
IIPReply(packet.CallbackId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -753,24 +793,34 @@ namespace Esiur.Net.IIP
|
|||||||
session.Id = new byte[32];
|
session.Id = new byte[32];
|
||||||
r.NextBytes(session.Id);
|
r.NextBytes(session.Id);
|
||||||
//SendParams((byte)0x28, session.Id);
|
//SendParams((byte)0x28, session.Id);
|
||||||
SendParams()
|
SendParams().AddUInt8(0x28)
|
||||||
.AddUInt8(0x28)
|
.AddUInt8Array(session.Id)
|
||||||
.AddUInt8Array(session.Id)
|
.Done();
|
||||||
.Done();
|
|
||||||
|
|
||||||
ready = true;
|
if (this.Instance == null)
|
||||||
Warehouse.Put(this, this.LocalUsername, null, Server).Then(x =>
|
|
||||||
{
|
{
|
||||||
|
Warehouse.Put(this.RemoteUsername, this, null, Server).Then(x =>
|
||||||
|
{
|
||||||
|
|
||||||
|
ready = true;
|
||||||
|
openReply?.Trigger(true);
|
||||||
|
OnReady?.Invoke(this);
|
||||||
|
|
||||||
|
Server?.Membership.Login(session);
|
||||||
|
loginDate = DateTime.Now;
|
||||||
|
|
||||||
|
}).Error(x =>
|
||||||
|
{
|
||||||
|
openReply?.TriggerError(x);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ready = true;
|
||||||
openReply?.Trigger(true);
|
openReply?.Trigger(true);
|
||||||
OnReady?.Invoke(this);
|
OnReady?.Invoke(this);
|
||||||
|
|
||||||
Server?.Membership.Login(session);
|
Server?.Membership.Login(session);
|
||||||
|
}
|
||||||
}).Error(x=>
|
|
||||||
{
|
|
||||||
openReply?.TriggerError(x);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
//Global.Log("auth", LogType.Warning, "U:" + RemoteUsername + " IP:" + Socket.RemoteEndPoint.Address.ToString() + " S:AUTH");
|
//Global.Log("auth", LogType.Warning, "U:" + RemoteUsername + " IP:" + Socket.RemoteEndPoint.Address.ToString() + " S:AUTH");
|
||||||
|
|
||||||
@ -841,13 +891,21 @@ namespace Esiur.Net.IIP
|
|||||||
|
|
||||||
ready = true;
|
ready = true;
|
||||||
// put it in the warehouse
|
// put it in the warehouse
|
||||||
Warehouse.Put(this, this.LocalUsername, null, Server).Then(x =>
|
|
||||||
|
if (this.Instance == null)
|
||||||
|
{
|
||||||
|
Warehouse.Put(this.LocalUsername, this, null, Server).Then(x =>
|
||||||
|
{
|
||||||
|
openReply?.Trigger(true);
|
||||||
|
OnReady?.Invoke(this);
|
||||||
|
|
||||||
|
}).Error(x => openReply?.TriggerError(x));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
openReply?.Trigger(true);
|
openReply?.Trigger(true);
|
||||||
OnReady?.Invoke(this);
|
OnReady?.Invoke(this);
|
||||||
|
}
|
||||||
}).Error(x=> openReply?.TriggerError(x));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Error)
|
else if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Error)
|
||||||
@ -957,28 +1015,7 @@ namespace Esiur.Net.IIP
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void NetworkClose()
|
|
||||||
{
|
|
||||||
// clean up
|
|
||||||
ready = false;
|
|
||||||
readyToEstablish = false;
|
|
||||||
|
|
||||||
foreach (var x in requests.Values)
|
|
||||||
x.TriggerError(new AsyncException(ErrorType.Management, 0, "Connection closed"));
|
|
||||||
|
|
||||||
foreach (var x in resourceRequests.Values)
|
|
||||||
x.TriggerError(new AsyncException(ErrorType.Management, 0, "Connection closed"));
|
|
||||||
|
|
||||||
foreach (var x in templateRequests.Values)
|
|
||||||
x.TriggerError(new AsyncException(ErrorType.Management, 0, "Connection closed"));
|
|
||||||
|
|
||||||
requests.Clear();
|
|
||||||
resourceRequests.Clear();
|
|
||||||
templateRequests.Clear();
|
|
||||||
|
|
||||||
foreach (var x in resources.Values)
|
|
||||||
x.Suspend();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncReply<bool> Connect(AuthenticationMethod method = AuthenticationMethod.Certificate, Sockets.ISocket socket = null, string hostname = null, ushort port = 0, string username = null, ulong tokenIndex = 0, byte[] passwordOrToken = null, string domain = null)
|
public AsyncReply<bool> Connect(AuthenticationMethod method = AuthenticationMethod.Certificate, Sockets.ISocket socket = null, string hostname = null, ushort port = 0, string username = null, ulong tokenIndex = 0, byte[] passwordOrToken = null, string domain = null)
|
||||||
{
|
{
|
||||||
@ -1128,32 +1165,38 @@ namespace Esiur.Net.IIP
|
|||||||
protected override void Connected()
|
protected override void Connected()
|
||||||
{
|
{
|
||||||
if (session.LocalAuthentication.Type == AuthenticationType.Client)
|
if (session.LocalAuthentication.Type == AuthenticationType.Client)
|
||||||
{
|
Declare();
|
||||||
// declare (Credentials -> No Auth, No Enctypt)
|
|
||||||
|
|
||||||
var un = DC.ToBytes(session.LocalAuthentication.Username);
|
|
||||||
var dmn = DC.ToBytes(session.LocalAuthentication.Domain);// domain);
|
|
||||||
|
|
||||||
SendParams()
|
|
||||||
.AddUInt8(0x60)
|
|
||||||
.AddUInt8((byte)dmn.Length)
|
|
||||||
.AddUInt8Array(dmn)
|
|
||||||
.AddUInt8Array(localNonce)
|
|
||||||
.AddUInt8((byte)un.Length)
|
|
||||||
.AddUInt8Array(un)
|
|
||||||
.Done();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Disconencted()
|
protected override void Disconencted()
|
||||||
{
|
{
|
||||||
|
// clean up
|
||||||
|
readyToEstablish = false;
|
||||||
|
|
||||||
|
foreach (var x in requests.Values)
|
||||||
|
x.TriggerError(new AsyncException(ErrorType.Management, 0, "Connection closed"));
|
||||||
|
|
||||||
|
foreach (var x in resourceRequests.Values)
|
||||||
|
x.TriggerError(new AsyncException(ErrorType.Management, 0, "Connection closed"));
|
||||||
|
|
||||||
|
foreach (var x in templateRequests.Values)
|
||||||
|
x.TriggerError(new AsyncException(ErrorType.Management, 0, "Connection closed"));
|
||||||
|
|
||||||
|
requests.Clear();
|
||||||
|
resourceRequests.Clear();
|
||||||
|
templateRequests.Clear();
|
||||||
|
|
||||||
|
foreach (var x in resources.Values)
|
||||||
|
x.Suspend();
|
||||||
|
|
||||||
|
UnsubscribeAll();
|
||||||
|
|
||||||
|
Warehouse.Remove(this);
|
||||||
|
|
||||||
if (ready)
|
if (ready)
|
||||||
{
|
|
||||||
Server?.Membership.Logout(session);
|
Server?.Membership.Logout(session);
|
||||||
Warehouse.Remove(this);
|
|
||||||
ready = false;
|
ready = false;
|
||||||
UnsubscribeAll();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -36,6 +36,7 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
|
||||||
namespace Esiur.Net.IIP
|
namespace Esiur.Net.IIP
|
||||||
{
|
{
|
||||||
@ -54,7 +55,9 @@ namespace Esiur.Net.IIP
|
|||||||
|
|
||||||
volatile uint callbackCounter = 0;
|
volatile uint callbackCounter = 0;
|
||||||
|
|
||||||
List<IResource> subscriptions = new List<IResource>();
|
//List<IResource> subscriptions = new List<IResource>();
|
||||||
|
Dictionary<IResource, List<byte>> subscriptions = new Dictionary<IResource, List<byte>>();// new List<IResource>();
|
||||||
|
|
||||||
object subscriptionsLock = new object();
|
object subscriptionsLock = new object();
|
||||||
|
|
||||||
AsyncQueue<DistributedResourceQueueItem> queue = new AsyncQueue<DistributedResourceQueueItem>();
|
AsyncQueue<DistributedResourceQueueItem> queue = new AsyncQueue<DistributedResourceQueueItem>();
|
||||||
@ -108,13 +111,40 @@ namespace Esiur.Net.IIP
|
|||||||
|
|
||||||
internal SendList SendEvent(IIPPacket.IIPPacketEvent evt)
|
internal SendList SendEvent(IIPPacket.IIPPacketEvent evt)
|
||||||
{
|
{
|
||||||
//var bl = new BinaryList((byte)(evt));
|
|
||||||
//bl.AddRange(args);
|
|
||||||
//Send(bl.ToArray());
|
|
||||||
|
|
||||||
return (SendList)SendParams().AddUInt8((byte)(evt));
|
return (SendList)SendParams().AddUInt8((byte)(evt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal AsyncReply SendListenRequest(uint instanceId, byte index)
|
||||||
|
{
|
||||||
|
var reply = new AsyncReply<object>();
|
||||||
|
var c = callbackCounter++;
|
||||||
|
requests.Add(c, reply);
|
||||||
|
|
||||||
|
SendParams().AddUInt8((byte)(0x40 | (byte)Packets.IIPPacket.IIPPacketAction.Listen))
|
||||||
|
.AddUInt32(c)
|
||||||
|
.AddUInt32(instanceId)
|
||||||
|
.AddUInt8(index)
|
||||||
|
.Done();
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal AsyncReply SendUnlistenRequest(uint instanceId, byte index)
|
||||||
|
{
|
||||||
|
var reply = new AsyncReply<object>();
|
||||||
|
var c = callbackCounter++;
|
||||||
|
requests.Add(c, reply);
|
||||||
|
|
||||||
|
SendParams().AddUInt8((byte)(0x40 | (byte)Packets.IIPPacket.IIPPacketAction.Unlisten))
|
||||||
|
.AddUInt32(c)
|
||||||
|
.AddUInt32(instanceId)
|
||||||
|
.AddUInt8(index)
|
||||||
|
.Done();
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
internal AsyncReply<object> SendInvokeByArrayArguments(uint instanceId, byte index, object[] parameters)
|
internal AsyncReply<object> SendInvokeByArrayArguments(uint instanceId, byte index, object[] parameters)
|
||||||
{
|
{
|
||||||
var pb = Codec.ComposeVarArray(parameters, this, true);
|
var pb = Codec.ComposeVarArray(parameters, this, true);
|
||||||
@ -593,6 +623,7 @@ namespace Esiur.Net.IIP
|
|||||||
var r = res as IResource;
|
var r = res as IResource;
|
||||||
// unsubscribe
|
// unsubscribe
|
||||||
Unsubscribe(r);
|
Unsubscribe(r);
|
||||||
|
Subscribe(r);
|
||||||
|
|
||||||
//r.Instance.ResourceEventOccurred -= Instance_EventOccurred;
|
//r.Instance.ResourceEventOccurred -= Instance_EventOccurred;
|
||||||
//r.Instance.CustomResourceEventOccurred -= Instance_CustomEventOccurred;
|
//r.Instance.CustomResourceEventOccurred -= Instance_CustomEventOccurred;
|
||||||
@ -610,7 +641,6 @@ namespace Esiur.Net.IIP
|
|||||||
//r.Instance.ResourceModified += Instance_PropertyModified;
|
//r.Instance.ResourceModified += Instance_PropertyModified;
|
||||||
//r.Instance.ResourceDestroyed += Instance_ResourceDestroyed;
|
//r.Instance.ResourceDestroyed += Instance_ResourceDestroyed;
|
||||||
|
|
||||||
Subscribe(r);
|
|
||||||
//r.Instance.Children.OnAdd += Children_OnAdd;
|
//r.Instance.Children.OnAdd += Children_OnAdd;
|
||||||
//r.Instance.Children.OnRemoved += Children_OnRemoved;
|
//r.Instance.Children.OnRemoved += Children_OnRemoved;
|
||||||
|
|
||||||
@ -770,7 +800,7 @@ namespace Esiur.Net.IIP
|
|||||||
// create the resource
|
// create the resource
|
||||||
var resource = Activator.CreateInstance(type, args) as IResource;
|
var resource = Activator.CreateInstance(type, args) as IResource;
|
||||||
|
|
||||||
Warehouse.Put(resource, name, store as IStore, parent).Then(ok =>
|
Warehouse.Put( name, resource, store as IStore, parent).Then(ok =>
|
||||||
{
|
{
|
||||||
SendReply(IIPPacket.IIPPacketAction.CreateResource, callback)
|
SendReply(IIPPacket.IIPPacketAction.CreateResource, callback)
|
||||||
.AddUInt32(resource.Instance.Id)
|
.AddUInt32(resource.Instance.Id)
|
||||||
@ -1126,7 +1156,7 @@ namespace Esiur.Net.IIP
|
|||||||
if (Server?.EntryPoint != null)
|
if (Server?.EntryPoint != null)
|
||||||
Server.EntryPoint.Query(resourceLink, this).Then(queryCallback);
|
Server.EntryPoint.Query(resourceLink, this).Then(queryCallback);
|
||||||
else
|
else
|
||||||
Warehouse.Query(resourceLink).Then(x => queryCallback(x));
|
Warehouse.Query(resourceLink).Then(queryCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IIPRequestResourceAttribute(uint callback, uint resourceId)
|
void IIPRequestResourceAttribute(uint callback, uint resourceId)
|
||||||
@ -1469,53 +1499,161 @@ namespace Esiur.Net.IIP
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void IIPRequestGetProperty(uint callback, uint resourceId, byte index)
|
void IIPRequestListen(uint callback, uint resourceId, byte index)
|
||||||
{
|
{
|
||||||
Warehouse.GetById(resourceId).Then((r) =>
|
Warehouse.GetById(resourceId).Then((r) =>
|
||||||
{
|
{
|
||||||
if (r != null)
|
if (r != null)
|
||||||
{
|
{
|
||||||
var pt = r.Instance.Template.GetFunctionTemplateByIndex(index);
|
var et = r.Instance.Template.GetEventTemplateByIndex(index);
|
||||||
if (pt != null)
|
|
||||||
|
if (et != null)
|
||||||
{
|
{
|
||||||
if (r is DistributedResource)
|
if (r is DistributedResource)
|
||||||
{
|
{
|
||||||
SendReply(IIPPacket.IIPPacketAction.GetProperty, callback)
|
(r as DistributedResource).Listen(et).Then(x =>
|
||||||
.AddUInt8Array(Codec.Compose((r as DistributedResource)._Get(pt.Index), this))
|
{
|
||||||
.Done();
|
SendReply(IIPPacket.IIPPacketAction.Listen, callback).Done();
|
||||||
|
}).Error(x => SendError(ErrorType.Exception, callback, (ushort)ExceptionCode.GeneralFailure));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if NETSTANDARD
|
lock(subscriptionsLock)
|
||||||
var pi = r.GetType().GetTypeInfo().GetProperty(pt.Name);
|
{
|
||||||
#else
|
if (!subscriptions.ContainsKey(r))
|
||||||
var pi = r.GetType().GetProperty(pt.Name);
|
{
|
||||||
#endif
|
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.NotAttached);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (pi != null)
|
if (subscriptions[r].Contains(index))
|
||||||
{
|
{
|
||||||
SendReply(IIPPacket.IIPPacketAction.GetProperty, callback)
|
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.AlreadyListened);
|
||||||
.AddUInt8Array(Codec.Compose(pi.GetValue(r), this))
|
return;
|
||||||
.Done();
|
}
|
||||||
}
|
|
||||||
else
|
subscriptions[r].Add(index);
|
||||||
{
|
|
||||||
// pt found, pi not found, this should never happen
|
SendReply(IIPPacket.IIPPacketAction.Listen, callback).Done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// pt not found
|
// pt not found
|
||||||
|
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.MethodNotFound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// resource not found
|
// resource not found
|
||||||
|
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IIPRequestUnlisten(uint callback, uint resourceId, byte index)
|
||||||
|
{
|
||||||
|
Warehouse.GetById(resourceId).Then((r) =>
|
||||||
|
{
|
||||||
|
if (r != null)
|
||||||
|
{
|
||||||
|
var et = r.Instance.Template.GetEventTemplateByIndex(index);
|
||||||
|
|
||||||
|
if (et != null)
|
||||||
|
{
|
||||||
|
if (r is DistributedResource)
|
||||||
|
{
|
||||||
|
(r as DistributedResource).Unlisten(et).Then(x =>
|
||||||
|
{
|
||||||
|
SendReply(IIPPacket.IIPPacketAction.Unlisten, callback).Done();
|
||||||
|
}).Error(x => SendError(ErrorType.Exception, callback, (ushort)ExceptionCode.GeneralFailure));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lock (subscriptionsLock)
|
||||||
|
{
|
||||||
|
if (!subscriptions.ContainsKey(r))
|
||||||
|
{
|
||||||
|
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.NotAttached);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!subscriptions[r].Contains(index))
|
||||||
|
{
|
||||||
|
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.AlreadyUnlistened);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
subscriptions[r].Remove(index);
|
||||||
|
|
||||||
|
SendReply(IIPPacket.IIPPacketAction.Unlisten, callback).Done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// pt not found
|
||||||
|
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.MethodNotFound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// resource not found
|
||||||
|
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// void IIPRequestGetProperty(uint callback, uint resourceId, byte index)
|
||||||
|
// {
|
||||||
|
// Warehouse.GetById(resourceId).Then((r) =>
|
||||||
|
// {
|
||||||
|
// if (r != null)
|
||||||
|
// {
|
||||||
|
// var pt = r.Instance.Template.GetPropertyTemplateByIndex(index);
|
||||||
|
// if (pt != null)
|
||||||
|
// {
|
||||||
|
// if (r is DistributedResource)
|
||||||
|
// {
|
||||||
|
// SendReply(IIPPacket.IIPPacketAction.GetProperty, callback)
|
||||||
|
// .AddUInt8Array(Codec.Compose((r as DistributedResource)._Get(pt.Index), this))
|
||||||
|
// .Done();
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
//#if NETSTANDARD
|
||||||
|
// var pi = r.GetType().GetTypeInfo().GetProperty(pt.Name);
|
||||||
|
//#else
|
||||||
|
// var pi = r.GetType().GetProperty(pt.Name);
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
// if (pi != null)
|
||||||
|
// {
|
||||||
|
// SendReply(IIPPacket.IIPPacketAction.GetProperty, callback)
|
||||||
|
// .AddUInt8Array(Codec.Compose(pi.GetValue(r), this))
|
||||||
|
// .Done();
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // pt found, pi not found, this should never happen
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // pt not found
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // resource not found
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
void IIPRequestInquireResourceHistory(uint callback, uint resourceId, DateTime fromDate, DateTime toDate)
|
void IIPRequestInquireResourceHistory(uint callback, uint resourceId, DateTime fromDate, DateTime toDate)
|
||||||
{
|
{
|
||||||
Warehouse.GetById(resourceId).Then((r) =>
|
Warehouse.GetById(resourceId).Then((r) =>
|
||||||
@ -1552,51 +1690,51 @@ namespace Esiur.Net.IIP
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void IIPRequestGetPropertyIfModifiedSince(uint callback, uint resourceId, byte index, ulong age)
|
// void IIPRequestGetPropertyIfModifiedSince(uint callback, uint resourceId, byte index, ulong age)
|
||||||
{
|
// {
|
||||||
Warehouse.GetById(resourceId).Then((r) =>
|
// Warehouse.GetById(resourceId).Then((r) =>
|
||||||
{
|
// {
|
||||||
if (r != null)
|
// if (r != null)
|
||||||
{
|
// {
|
||||||
var pt = r.Instance.Template.GetFunctionTemplateByIndex(index);
|
// var pt = r.Instance.Template.GetFunctionTemplateByIndex(index);
|
||||||
if (pt != null)
|
// if (pt != null)
|
||||||
{
|
// {
|
||||||
if (r.Instance.GetAge(index) > age)
|
// if (r.Instance.GetAge(index) > age)
|
||||||
{
|
// {
|
||||||
#if NETSTANDARD
|
//#if NETSTANDARD
|
||||||
var pi = r.GetType().GetTypeInfo().GetProperty(pt.Name);
|
// var pi = r.GetType().GetTypeInfo().GetProperty(pt.Name);
|
||||||
#else
|
//#else
|
||||||
var pi = r.GetType().GetProperty(pt.Name);
|
// var pi = r.GetType().GetProperty(pt.Name);
|
||||||
#endif
|
//#endif
|
||||||
if (pi != null)
|
// if (pi != null)
|
||||||
{
|
// {
|
||||||
SendReply(IIPPacket.IIPPacketAction.GetPropertyIfModified, callback)
|
// SendReply(IIPPacket.IIPPacketAction.GetPropertyIfModified, callback)
|
||||||
.AddUInt8Array(Codec.Compose(pi.GetValue(r), this))
|
// .AddUInt8Array(Codec.Compose(pi.GetValue(r), this))
|
||||||
.Done();
|
// .Done();
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
// pt found, pi not found, this should never happen
|
// // pt found, pi not found, this should never happen
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
SendReply(IIPPacket.IIPPacketAction.GetPropertyIfModified, callback)
|
// SendReply(IIPPacket.IIPPacketAction.GetPropertyIfModified, callback)
|
||||||
.AddUInt8((byte)DataType.NotModified)
|
// .AddUInt8((byte)DataType.NotModified)
|
||||||
.Done();
|
// .Done();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
// pt not found
|
// // pt not found
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
// resource not found
|
// // resource not found
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
void IIPRequestSetProperty(uint callback, uint resourceId, byte index, byte[] content)
|
void IIPRequestSetProperty(uint callback, uint resourceId, byte index, byte[] content)
|
||||||
{
|
{
|
||||||
@ -1973,7 +2111,7 @@ namespace Esiur.Net.IIP
|
|||||||
// ClassId, ResourceAge, ResourceLink, Content
|
// ClassId, ResourceAge, ResourceLink, Content
|
||||||
if (resource == null)
|
if (resource == null)
|
||||||
{
|
{
|
||||||
Warehouse.Put(dr, id.ToString(), this, null, tmp).Then((ok) =>
|
Warehouse.Put(id.ToString(), dr, this, null, tmp).Then((ok) =>
|
||||||
{
|
{
|
||||||
Codec.ParsePropertyValueArray((byte[])rt[3], this).Then((ar) =>
|
Codec.ParsePropertyValueArray((byte[])rt[3], this).Then((ar) =>
|
||||||
{
|
{
|
||||||
@ -2242,7 +2380,7 @@ namespace Esiur.Net.IIP
|
|||||||
resource.Instance.ResourceModified += Instance_PropertyModified;
|
resource.Instance.ResourceModified += Instance_PropertyModified;
|
||||||
resource.Instance.ResourceDestroyed += Instance_ResourceDestroyed;
|
resource.Instance.ResourceDestroyed += Instance_ResourceDestroyed;
|
||||||
|
|
||||||
subscriptions.Add(resource);
|
subscriptions.Add(resource, new List<byte>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2265,7 +2403,7 @@ namespace Esiur.Net.IIP
|
|||||||
{
|
{
|
||||||
lock(subscriptionsLock)
|
lock(subscriptionsLock)
|
||||||
{
|
{
|
||||||
foreach(var resource in subscriptions)
|
foreach(var resource in subscriptions.Keys)
|
||||||
{
|
{
|
||||||
resource.Instance.ResourceEventOccurred -= Instance_EventOccurred;
|
resource.Instance.ResourceEventOccurred -= Instance_EventOccurred;
|
||||||
resource.Instance.CustomResourceEventOccurred -= Instance_CustomEventOccurred;
|
resource.Instance.CustomResourceEventOccurred -= Instance_CustomEventOccurred;
|
||||||
@ -2313,12 +2451,26 @@ namespace Esiur.Net.IIP
|
|||||||
if (et == null)
|
if (et == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (et.Listenable)
|
||||||
|
{
|
||||||
|
lock (subscriptionsLock)
|
||||||
|
{
|
||||||
|
// check the client requested listen
|
||||||
|
if (!subscriptions.ContainsKey(resource))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!subscriptions[resource].Contains(et.Index))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!receivers(this.session))
|
if (!receivers(this.session))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (resource.Instance.Applicable(this.session, ActionType.ReceiveEvent, et, issuer) == Ruling.Denied)
|
if (resource.Instance.Applicable(this.session, ActionType.ReceiveEvent, et, issuer) == Ruling.Denied)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
// compose the packet
|
// compose the packet
|
||||||
SendEvent(IIPPacket.IIPPacketEvent.EventOccurred)
|
SendEvent(IIPPacket.IIPPacketEvent.EventOccurred)
|
||||||
.AddUInt32(resource.Instance.Id)
|
.AddUInt32(resource.Instance.Id)
|
||||||
@ -2334,6 +2486,18 @@ namespace Esiur.Net.IIP
|
|||||||
if (et == null)
|
if (et == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (et.Listenable)
|
||||||
|
{
|
||||||
|
lock (subscriptionsLock)
|
||||||
|
{
|
||||||
|
// check the client requested listen
|
||||||
|
if (!subscriptions.ContainsKey(resource))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!subscriptions[resource].Contains(et.Index))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (resource.Instance.Applicable(this.session, ActionType.ReceiveEvent, et, null) == Ruling.Denied)
|
if (resource.Instance.Applicable(this.session, ActionType.ReceiveEvent, et, null) == Ruling.Denied)
|
||||||
return;
|
return;
|
||||||
|
@ -105,7 +105,7 @@ namespace Esiur.Net.IIP
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint Id
|
public uint Id
|
||||||
{
|
{
|
||||||
get { return instanceId; }
|
get { return instanceId; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -138,18 +138,18 @@ namespace Esiur.Net.IIP
|
|||||||
internal bool Suspended => suspended;
|
internal bool Suspended => suspended;
|
||||||
|
|
||||||
|
|
||||||
// public DistributedResourceStack Stack
|
// public DistributedResourceStack Stack
|
||||||
//{
|
//{
|
||||||
// get { return stack; }
|
// get { return stack; }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new distributed resource.
|
/// Create a new distributed resource.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="connection">Connection responsible for the distributed resource.</param>
|
/// <param name="connection">Connection responsible for the distributed resource.</param>
|
||||||
/// <param name="template">Resource template.</param>
|
/// <param name="template">Resource template.</param>
|
||||||
/// <param name="instanceId">Instance Id given by the other end.</param>
|
/// <param name="instanceId">Instance Id given by the other end.</param>
|
||||||
/// <param name="age">Resource age.</param>
|
/// <param name="age">Resource age.</param>
|
||||||
public DistributedResource(DistributedConnection connection, uint instanceId, ulong age, string link)
|
public DistributedResource(DistributedConnection connection, uint instanceId, ulong age, string link)
|
||||||
{
|
{
|
||||||
this.link = link;
|
this.link = link;
|
||||||
@ -207,7 +207,7 @@ namespace Esiur.Net.IIP
|
|||||||
attached = true;
|
attached = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void _EmitEventByIndex(byte index, object args)
|
internal void _EmitEventByIndex(byte index, object args)
|
||||||
@ -232,6 +232,7 @@ namespace Esiur.Net.IIP
|
|||||||
return connection.SendInvokeByNamedArguments(instanceId, index, namedArgs);
|
return connection.SendInvokeByNamedArguments(instanceId, index, namedArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public AsyncReply<object> _InvokeByArrayArguments(byte index, object[] args)
|
public AsyncReply<object> _InvokeByArrayArguments(byte index, object[] args)
|
||||||
{
|
{
|
||||||
if (destroyed)
|
if (destroyed)
|
||||||
@ -248,13 +249,51 @@ namespace Esiur.Net.IIP
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public AsyncReply Listen(EventTemplate et)
|
||||||
|
{
|
||||||
|
if (et == null)
|
||||||
|
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.MethodNotFound, ""));
|
||||||
|
|
||||||
|
if (!et.Listenable)
|
||||||
|
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.NotListenable, ""));
|
||||||
|
|
||||||
|
return connection.SendListenRequest(instanceId, et.Index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncReply Listen(string eventName)
|
||||||
|
{
|
||||||
|
var et = Instance.Template.GetEventTemplateByName(eventName);
|
||||||
|
|
||||||
|
return Listen(et);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public AsyncReply Unlisten(EventTemplate et)
|
||||||
|
{
|
||||||
|
if (et == null)
|
||||||
|
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.MethodNotFound, ""));
|
||||||
|
|
||||||
|
if (!et.Listenable)
|
||||||
|
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.NotListenable, ""));
|
||||||
|
|
||||||
|
return connection.SendUnlistenRequest(instanceId, et.Index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncReply Unlisten(string eventName)
|
||||||
|
{
|
||||||
|
var et = Instance.Template.GetEventTemplateByName(eventName);
|
||||||
|
|
||||||
|
return Unlisten(et);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
|
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
|
||||||
{
|
{
|
||||||
var ft = Instance.Template.GetFunctionTemplateByName(binder.Name);
|
var ft = Instance.Template.GetFunctionTemplateByName(binder.Name);
|
||||||
|
|
||||||
var reply = new AsyncReply<object>();
|
var reply = new AsyncReply<object>();
|
||||||
|
|
||||||
if (attached && ft!=null)
|
if (attached && ft != null)
|
||||||
{
|
{
|
||||||
if (args.Length == 1)
|
if (args.Length == 1)
|
||||||
{
|
{
|
||||||
@ -397,7 +436,7 @@ namespace Esiur.Net.IIP
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
public async void InvokeMethod(byte index, object[] arguments, DistributedConnection sender)
|
public async void InvokeMethod(byte index, object[] arguments, DistributedConnection sender)
|
||||||
@ -427,9 +466,9 @@ namespace Esiur.Net.IIP
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resource interface.
|
/// Resource interface.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Instance Instance
|
public Instance Instance
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
@ -32,7 +32,7 @@ namespace Esiur.Net.IIP
|
|||||||
{
|
{
|
||||||
public class DistributedSession : NetworkSession
|
public class DistributedSession : NetworkSession
|
||||||
{
|
{
|
||||||
Source Source { get; }
|
public Source Source { get; set; }
|
||||||
Authentication Authentication;
|
public Authentication Authentication { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ using System.Text;
|
|||||||
using Esiur.Misc;
|
using Esiur.Misc;
|
||||||
using Esiur.Data;
|
using Esiur.Data;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Esiur.Net.Packets
|
namespace Esiur.Net.Packets
|
||||||
{
|
{
|
||||||
@ -246,7 +247,7 @@ namespace Esiur.Net.Packets
|
|||||||
if (
|
if (
|
||||||
Headers["content-type"] == null
|
Headers["content-type"] == null
|
||||||
|| Headers["content-type"] == ""
|
|| Headers["content-type"] == ""
|
||||||
|| Headers["content-type"].StartsWith("application/x-www-form-urlencoded"))
|
|| Headers["content-type"].StartsWith("application/x-www-form-urlencoded"))
|
||||||
{
|
{
|
||||||
string[] PostVars = null;
|
string[] PostVars = null;
|
||||||
PostVars = Encoding.UTF8.GetString(data, (int)headerSize, (int)postSize).Split('&');
|
PostVars = Encoding.UTF8.GetString(data, (int)headerSize, (int)postSize).Split('&');
|
||||||
@ -265,10 +266,10 @@ namespace Esiur.Net.Packets
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (PostForms.Contains("unknown"))
|
if (PostForms.Contains("unknown"))
|
||||||
PostForms["unknown"] = PostForms["unknown"]
|
PostForms["unknown"] = PostForms["unknown"]
|
||||||
+ "&" + WebUtility.HtmlDecode(WebUtility.UrlDecode(PostVars[J]));
|
+ "&" + WebUtility.HtmlDecode(WebUtility.UrlDecode(PostVars[J]));
|
||||||
else
|
else
|
||||||
PostForms.Add("unknown", WebUtility.HtmlDecode(WebUtility.UrlDecode(PostVars[J])));
|
PostForms.Add("unknown", WebUtility.HtmlDecode(WebUtility.UrlDecode(PostVars[J])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Headers["content-type"].StartsWith("multipart/form-data"))
|
else if (Headers["content-type"].StartsWith("multipart/form-data"))
|
||||||
@ -291,6 +292,10 @@ namespace Esiur.Net.Packets
|
|||||||
PostForms.Add(ps[0].Substring(st, ed - st), ps[1]);
|
PostForms.Add(ps[0].Substring(st, ed - st), ps[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//else if (Headers["content-type"] == "application/json")
|
||||||
|
//{
|
||||||
|
// var json = DC.Clip(data, headerSize, postSize);
|
||||||
|
//}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//PostForms.Add(Headers["content-type"], Encoding.Default.GetString( ));
|
//PostForms.Add(Headers["content-type"], Encoding.Default.GetString( ));
|
||||||
|
@ -110,10 +110,10 @@ namespace Esiur.Net.Packets
|
|||||||
|
|
||||||
// Request Invoke
|
// Request Invoke
|
||||||
InvokeFunctionArrayArguments = 0x10,
|
InvokeFunctionArrayArguments = 0x10,
|
||||||
GetProperty,
|
|
||||||
GetPropertyIfModified,
|
|
||||||
SetProperty,
|
|
||||||
InvokeFunctionNamedArguments,
|
InvokeFunctionNamedArguments,
|
||||||
|
Listen,
|
||||||
|
Unlisten,
|
||||||
|
SetProperty,
|
||||||
|
|
||||||
// Request Attribute
|
// Request Attribute
|
||||||
GetAllAttributes = 0x18,
|
GetAllAttributes = 0x18,
|
||||||
@ -543,7 +543,8 @@ namespace Esiur.Net.Packets
|
|||||||
offset += cl;
|
offset += cl;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.GetProperty)
|
else if (Action == IIPPacketAction.Listen
|
||||||
|
|| Action == IIPPacketAction.Unlisten)// .GetProperty)
|
||||||
{
|
{
|
||||||
if (NotEnough(offset, ends, 5))
|
if (NotEnough(offset, ends, 5))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
@ -554,20 +555,20 @@ namespace Esiur.Net.Packets
|
|||||||
MethodIndex = data[offset++];
|
MethodIndex = data[offset++];
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.GetPropertyIfModified)
|
//else if (Action == IIPPacketAction.GetPropertyIfModified)
|
||||||
{
|
//{
|
||||||
if (NotEnough(offset, ends, 9))
|
// if (NotEnough(offset, ends, 9))
|
||||||
return -dataLengthNeeded;
|
// return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
// ResourceId = data.GetUInt32(offset);
|
||||||
offset += 4;
|
// offset += 4;
|
||||||
|
|
||||||
MethodIndex = data[offset++];
|
// MethodIndex = data[offset++];
|
||||||
|
|
||||||
ResourceAge = data.GetUInt64(offset);
|
// ResourceAge = data.GetUInt64(offset);
|
||||||
offset += 8;
|
// offset += 8;
|
||||||
|
|
||||||
}
|
//}
|
||||||
else if (Action == IIPPacketAction.SetProperty)
|
else if (Action == IIPPacketAction.SetProperty)
|
||||||
{
|
{
|
||||||
if (NotEnough(offset, ends, 6))
|
if (NotEnough(offset, ends, 6))
|
||||||
@ -707,9 +708,9 @@ namespace Esiur.Net.Packets
|
|||||||
offset += cl;
|
offset += cl;
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.InvokeFunctionArrayArguments
|
else if (Action == IIPPacketAction.InvokeFunctionArrayArguments
|
||||||
|| Action == IIPPacketAction.InvokeFunctionNamedArguments
|
|| Action == IIPPacketAction.InvokeFunctionNamedArguments)
|
||||||
|| Action == IIPPacketAction.GetProperty
|
//|| Action == IIPPacketAction.GetProperty
|
||||||
|| Action == IIPPacketAction.GetPropertyIfModified)
|
//|| Action == IIPPacketAction.GetPropertyIfModified)
|
||||||
{
|
{
|
||||||
if (NotEnough(offset, ends, 1))
|
if (NotEnough(offset, ends, 1))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
@ -740,7 +741,9 @@ namespace Esiur.Net.Packets
|
|||||||
offset += (uint)size;
|
offset += (uint)size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.SetProperty)
|
else if (Action == IIPPacketAction.SetProperty
|
||||||
|
|| Action == IIPPacketAction.Listen
|
||||||
|
|| Action == IIPPacketAction.Unlisten)
|
||||||
{
|
{
|
||||||
// nothing to do
|
// nothing to do
|
||||||
}
|
}
|
||||||
|
@ -329,7 +329,7 @@ namespace Esiur.Net.Packets
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PosixTime Timeval;
|
//PosixTime Timeval;
|
||||||
public byte[] Header;
|
public byte[] Header;
|
||||||
public byte[] Preamble;
|
public byte[] Preamble;
|
||||||
//public byte[] Payload;
|
//public byte[] Payload;
|
||||||
|
@ -165,7 +165,7 @@ namespace Esiur.Net.Sockets
|
|||||||
{
|
{
|
||||||
ssl.BeginWrite(kv.Value, 0, kv.Value.Length, SendCallback, kv.Key);
|
ssl.BeginWrite(kv.Value, 0, kv.Value.Length, SendCallback, kv.Key);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch //(Exception ex)
|
||||||
{
|
{
|
||||||
asyncSending = false;
|
asyncSending = false;
|
||||||
try
|
try
|
||||||
@ -179,7 +179,7 @@ namespace Esiur.Net.Sockets
|
|||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex2)
|
catch //(Exception ex2)
|
||||||
{
|
{
|
||||||
//state = SocketState.Closed;// .Terminated;
|
//state = SocketState.Closed;// .Terminated;
|
||||||
Close();
|
Close();
|
||||||
@ -439,7 +439,7 @@ namespace Esiur.Net.Sockets
|
|||||||
ssl.BeginRead(receiveBuffer, 0, receiveBuffer.Length, ReceiveCallback, this);
|
ssl.BeginRead(receiveBuffer, 0, receiveBuffer.Length, ReceiveCallback, this);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch //(Exception ex)
|
||||||
{
|
{
|
||||||
if (state != SocketState.Closed && !sock.Connected)
|
if (state != SocketState.Closed && !sock.Connected)
|
||||||
{
|
{
|
||||||
|
@ -126,7 +126,7 @@ namespace Esiur.Net.Sockets
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch //(Exception ex)
|
||||||
{
|
{
|
||||||
if (socket.state != SocketState.Closed && !socket.sock.Connected)
|
if (socket.state != SocketState.Closed && !socket.sock.Connected)
|
||||||
{
|
{
|
||||||
@ -500,7 +500,7 @@ namespace Esiur.Net.Sockets
|
|||||||
socket.Close();
|
socket.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex2)
|
catch //(Exception ex2)
|
||||||
{
|
{
|
||||||
socket.Close();
|
socket.Close();
|
||||||
//socket.state = SocketState.Closed;// .Terminated;
|
//socket.state = SocketState.Closed;// .Terminated;
|
||||||
|
@ -118,6 +118,7 @@ namespace Esiur.Net.Sockets
|
|||||||
|
|
||||||
public void Send(byte[] message)
|
public void Send(byte[] message)
|
||||||
{
|
{
|
||||||
|
|
||||||
lock (sendLock)
|
lock (sendLock)
|
||||||
{
|
{
|
||||||
if (held)
|
if (held)
|
||||||
@ -131,9 +132,8 @@ namespace Esiur.Net.Sockets
|
|||||||
|
|
||||||
pkt_send.Message = message;
|
pkt_send.Message = message;
|
||||||
|
|
||||||
|
|
||||||
if (pkt_send.Compose())
|
if (pkt_send.Compose())
|
||||||
sock.Send(pkt_send.Data);
|
sock?.Send(pkt_send.Data);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,8 +229,6 @@ namespace Esiur.Net.Sockets
|
|||||||
if (pkt_send.Compose())
|
if (pkt_send.Compose())
|
||||||
sock.Send(pkt_send.Data);
|
sock.Send(pkt_send.Data);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ namespace Esiur.Net.TCP
|
|||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
OnDestroy?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ namespace Esiur.Net.UDP
|
|||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
OnDestroy?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
20
Esiur/Proxy/GenerationInfo.cs
Normal file
20
Esiur/Proxy/GenerationInfo.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Proxy
|
||||||
|
{
|
||||||
|
public struct GenerationInfo
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public bool ImplementInterface { get; set; }
|
||||||
|
|
||||||
|
public bool ImplementTrigger { get; set; }
|
||||||
|
public IFieldSymbol[] Fields { get; set; }
|
||||||
|
public ITypeSymbol ClassSymbol { get; set; }
|
||||||
|
|
||||||
|
public ClassDeclarationSyntax ClassDeclaration { get; set; }
|
||||||
|
}
|
||||||
|
}
|
71
Esiur/Proxy/ResourceGenerator.cs
Normal file
71
Esiur/Proxy/ResourceGenerator.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
using Microsoft.CodeAnalysis.Text;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Esiur.Proxy
|
||||||
|
{
|
||||||
|
[Generator]
|
||||||
|
public class ResourceGenerator : ISourceGenerator
|
||||||
|
{
|
||||||
|
public void Initialize(GeneratorInitializationContext context)
|
||||||
|
{
|
||||||
|
// Register receiver
|
||||||
|
context.RegisterForSyntaxNotifications(() => new ResourceGeneratorReceiver());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(GeneratorExecutionContext context)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!(context.SyntaxContextReceiver is ResourceGeneratorReceiver receiver))
|
||||||
|
return;
|
||||||
|
|
||||||
|
//#if DEBUG
|
||||||
|
// if (!Debugger.IsAttached)
|
||||||
|
// {
|
||||||
|
// Debugger.Launch();
|
||||||
|
// }
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//var toImplement = receiver.Classes.Where(x => x.Fields.Length > 0);
|
||||||
|
|
||||||
|
foreach (var ci in receiver.Classes)
|
||||||
|
{
|
||||||
|
var code = @$"using Esiur.Resource;
|
||||||
|
using Esiur.Core;
|
||||||
|
namespace { ci.ClassSymbol.ContainingNamespace.ToDisplayString() } {{
|
||||||
|
";
|
||||||
|
|
||||||
|
if (ci.ImplementInterface)
|
||||||
|
code += $"public partial class {ci.Name} {{";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
code += @$"public partial class {ci.Name} : IResource {{
|
||||||
|
public Instance Instance {{ get; set; }}
|
||||||
|
public event DestroyedEvent OnDestroy;
|
||||||
|
public virtual void Destroy() {{ OnDestroy?.Invoke(this); }}
|
||||||
|
";
|
||||||
|
|
||||||
|
if (!ci.ImplementTrigger)
|
||||||
|
code += "public AsyncReply<bool> Trigger(ResourceTrigger trigger) => new AsyncReply<bool>(true);";
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var f in ci.Fields)
|
||||||
|
{
|
||||||
|
var fn = f.Name;
|
||||||
|
var pn = fn.Substring(0, 1).ToUpper() + fn.Substring(1);
|
||||||
|
code += $@"[Public] public {f.Type} {pn} {{ get => {fn}; set {{ {fn} = value; Instance.Modified(); }} }}";
|
||||||
|
}
|
||||||
|
|
||||||
|
code += "}}";
|
||||||
|
|
||||||
|
//System.IO.File.WriteAllText("C:\\www\\class.cs", code);
|
||||||
|
context.AddSource(ci.Name + "_esiur.cs", code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
61
Esiur/Proxy/ResourceGeneratorReceiver.cs
Normal file
61
Esiur/Proxy/ResourceGeneratorReceiver.cs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Proxy
|
||||||
|
{
|
||||||
|
public class ResourceGeneratorReceiver : ISyntaxContextReceiver
|
||||||
|
{
|
||||||
|
|
||||||
|
public List<GenerationInfo> Classes { get; } = new();
|
||||||
|
|
||||||
|
public void OnVisitSyntaxNode(GeneratorSyntaxContext context)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (context.Node is ClassDeclarationSyntax)
|
||||||
|
{
|
||||||
|
var cds = context.Node as ClassDeclarationSyntax;
|
||||||
|
var cls = context.SemanticModel.GetDeclaredSymbol(cds) as ITypeSymbol;
|
||||||
|
|
||||||
|
if (cls.GetAttributes().Any(a => a.AttributeClass.ToDisplayString() == "Esiur.Resource.ResourceAttribute"))
|
||||||
|
{
|
||||||
|
//if (!Debugger.IsAttached)
|
||||||
|
//{
|
||||||
|
// Debugger.Launch();
|
||||||
|
//}
|
||||||
|
|
||||||
|
var hasTrigger = cds.Members
|
||||||
|
.Where(x => x is MethodDeclarationSyntax)
|
||||||
|
.Select(x => context.SemanticModel.GetDeclaredSymbol(x) as IMethodSymbol)
|
||||||
|
.Any(x => x.Name == "Trigger"
|
||||||
|
&& x.Parameters.Length == 1
|
||||||
|
&& x.Parameters[0].Type.ToDisplayString() == "Esiur.Resource.ResourceTrigger");
|
||||||
|
|
||||||
|
var fields = cds.Members.Where(x => x is FieldDeclarationSyntax)
|
||||||
|
.Select(x => context.SemanticModel.GetDeclaredSymbol((x as FieldDeclarationSyntax).Declaration.Variables.First()) as IFieldSymbol)
|
||||||
|
.Where(x => x.GetAttributes().Any(a => a.AttributeClass.ToDisplayString() == "Esiur.Resource.PublicAttribute"))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
|
||||||
|
// get fields
|
||||||
|
Classes.Add(new GenerationInfo()
|
||||||
|
{
|
||||||
|
Name = cls.Name,
|
||||||
|
ClassDeclaration = cds,
|
||||||
|
ClassSymbol = cls,
|
||||||
|
Fields = fields,
|
||||||
|
ImplementInterface = cls.Interfaces.Any(x => x.ToDisplayString() == "Esiur.Resource.IResource"),
|
||||||
|
ImplementTrigger = hasTrigger
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,7 +12,6 @@ namespace Esiur.Proxy
|
|||||||
{
|
{
|
||||||
static Dictionary<Type, Type> cache = new Dictionary<Type, Type>();
|
static Dictionary<Type, Type> cache = new Dictionary<Type, Type>();
|
||||||
|
|
||||||
|
|
||||||
#if NETSTANDARD
|
#if NETSTANDARD
|
||||||
static MethodInfo modifyMethod = typeof(Instance).GetTypeInfo().GetMethod("Modified");
|
static MethodInfo modifyMethod = typeof(Instance).GetTypeInfo().GetMethod("Modified");
|
||||||
static MethodInfo instanceGet = typeof(IResource).GetTypeInfo().GetProperty("Instance").GetGetMethod();
|
static MethodInfo instanceGet = typeof(IResource).GetTypeInfo().GetProperty("Instance").GetGetMethod();
|
||||||
@ -34,14 +33,14 @@ namespace Esiur.Proxy
|
|||||||
else
|
else
|
||||||
return type;
|
return type;
|
||||||
|
|
||||||
if (type.FullName.Contains("Esiur.Proxy.T"))
|
// if (type.FullName.Contains("Esiur.Proxy.T"))
|
||||||
#if NETSTANDARD
|
//#if NETSTANDARD
|
||||||
return type.GetTypeInfo().BaseType;
|
// return type.GetTypeInfo().BaseType;
|
||||||
#else
|
//#else
|
||||||
return type.BaseType;
|
// return type.BaseType;
|
||||||
#endif
|
//#endif
|
||||||
else
|
// else
|
||||||
return type;
|
// return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type GetProxy(Type type)
|
public static Type GetProxy(Type type)
|
||||||
@ -50,6 +49,13 @@ namespace Esiur.Proxy
|
|||||||
if (cache.ContainsKey(type))
|
if (cache.ContainsKey(type))
|
||||||
return cache[type];
|
return cache[type];
|
||||||
|
|
||||||
|
// check if the type was made with code generation
|
||||||
|
if (type.GetCustomAttribute<ResourceAttribute>(false) != null)
|
||||||
|
{
|
||||||
|
cache.Add(type, type);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
#if NETSTANDARD
|
#if NETSTANDARD
|
||||||
var typeInfo = type.GetTypeInfo();
|
var typeInfo = type.GetTypeInfo();
|
||||||
|
|
||||||
|
@ -41,7 +41,6 @@ namespace Esiur.Resource
|
|||||||
{
|
{
|
||||||
|
|
||||||
AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
||||||
|
|
||||||
Instance Instance
|
Instance Instance
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
42
Esiur/Resource/ListenableAttribute.cs
Normal file
42
Esiur/Resource/ListenableAttribute.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2021 Ahmed Kh. Zamil
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Esiur.Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Event)]
|
||||||
|
public class ListenableAttribute : System.Attribute
|
||||||
|
{
|
||||||
|
|
||||||
|
public ListenableAttribute()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ using System.Text;
|
|||||||
|
|
||||||
namespace Esiur.Resource
|
namespace Esiur.Resource
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Class)]
|
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Class)]
|
||||||
|
|
||||||
public class PublicAttribute : Attribute
|
public class PublicAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
@ -47,6 +47,7 @@ namespace Esiur.Resource
|
|||||||
return new AsyncReply<bool>(true);
|
return new AsyncReply<bool>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected virtual bool Create()
|
protected virtual bool Create()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
15
Esiur/Resource/ResourceAttribute.cs
Normal file
15
Esiur/Resource/ResourceAttribute.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Resource
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
|
||||||
|
public class ResourceAttribute : Attribute
|
||||||
|
{
|
||||||
|
public ResourceAttribute()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,8 @@ namespace Esiur.Resource.Template
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Listenable { get; set; }
|
||||||
|
|
||||||
public EventInfo Info { get; set; }
|
public EventInfo Info { get; set; }
|
||||||
|
|
||||||
public override byte[] Compose()
|
public override byte[] Compose()
|
||||||
@ -24,9 +26,10 @@ namespace Esiur.Resource.Template
|
|||||||
|
|
||||||
if (Expansion != null)
|
if (Expansion != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
var exp = DC.ToBytes(Expansion);
|
var exp = DC.ToBytes(Expansion);
|
||||||
return new BinaryList()
|
return new BinaryList()
|
||||||
.AddUInt8(0x50)
|
.AddUInt8(Listenable ? (byte) 0x58 : (byte) 0x50)
|
||||||
.AddUInt8((byte)name.Length)
|
.AddUInt8((byte)name.Length)
|
||||||
.AddUInt8Array(name)
|
.AddUInt8Array(name)
|
||||||
.AddInt32(exp.Length)
|
.AddInt32(exp.Length)
|
||||||
@ -35,17 +38,18 @@ namespace Esiur.Resource.Template
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
return new BinaryList()
|
return new BinaryList()
|
||||||
.AddUInt8(0x40)
|
.AddUInt8(Listenable ? (byte) 0x48 : (byte) 0x40)
|
||||||
.AddUInt8((byte)name.Length)
|
.AddUInt8((byte)name.Length)
|
||||||
.AddUInt8Array(name)
|
.AddUInt8Array(name)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public EventTemplate(ResourceTemplate template, byte index, string name, string expansion = null)
|
public EventTemplate(ResourceTemplate template, byte index, string name, string expansion = null, bool listenable=false)
|
||||||
:base(template, MemberType.Property, index, name)
|
:base(template, MemberType.Property, index, name)
|
||||||
{
|
{
|
||||||
this.Expansion = expansion;
|
this.Expansion = expansion;
|
||||||
|
this.Listenable = listenable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ namespace Esiur.Resource.Template
|
|||||||
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
|
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
|
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
|
||||||
|
|
||||||
var pt = new PropertyTemplate(this, i++, pi.Name);//, rp.ReadExpansion, rp.WriteExpansion, rp.Storage);
|
var pt = new PropertyTemplate(this, i++, pi.Name);
|
||||||
if (storageAttr != null)
|
if (storageAttr != null)
|
||||||
pt.Recordable = storageAttr.Mode == StorageMode.Recordable;
|
pt.Recordable = storageAttr.Mode == StorageMode.Recordable;
|
||||||
|
|
||||||
@ -209,6 +209,7 @@ namespace Esiur.Resource.Template
|
|||||||
if (privateAttr == null)
|
if (privateAttr == null)
|
||||||
{
|
{
|
||||||
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
|
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
||||||
|
|
||||||
var et = new EventTemplate(this, i++, ei.Name);
|
var et = new EventTemplate(this, i++, ei.Name);
|
||||||
et.Info = ei;
|
et.Info = ei;
|
||||||
@ -216,6 +217,9 @@ namespace Esiur.Resource.Template
|
|||||||
if (annotationAttr != null)
|
if (annotationAttr != null)
|
||||||
et.Expansion = annotationAttr.Annotation;
|
et.Expansion = annotationAttr.Annotation;
|
||||||
|
|
||||||
|
if (listenableAttr != null)
|
||||||
|
et.Listenable = true;
|
||||||
|
|
||||||
events.Add(et);
|
events.Add(et);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,6 +287,7 @@ namespace Esiur.Resource.Template
|
|||||||
if (publicAttr != null)
|
if (publicAttr != null)
|
||||||
{
|
{
|
||||||
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
|
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
||||||
|
|
||||||
var et = new EventTemplate(this, i++, ei.Name);
|
var et = new EventTemplate(this, i++, ei.Name);
|
||||||
et.Info = ei;
|
et.Info = ei;
|
||||||
@ -290,6 +295,9 @@ namespace Esiur.Resource.Template
|
|||||||
if (annotationAttr != null)
|
if (annotationAttr != null)
|
||||||
et.Expansion = annotationAttr.Annotation;
|
et.Expansion = annotationAttr.Annotation;
|
||||||
|
|
||||||
|
if (listenableAttr != null)
|
||||||
|
et.Listenable = true;
|
||||||
|
|
||||||
events.Add(et);
|
events.Add(et);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -340,6 +348,7 @@ namespace Esiur.Resource.Template
|
|||||||
b.AddUInt8Array(et.Compose());
|
b.AddUInt8Array(et.Compose());
|
||||||
|
|
||||||
content = b.ToArray();
|
content = b.ToArray();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResourceTemplate Parse(byte[] data)
|
public static ResourceTemplate Parse(byte[] data)
|
||||||
@ -436,7 +445,8 @@ namespace Esiur.Resource.Template
|
|||||||
{
|
{
|
||||||
|
|
||||||
string expansion = null;
|
string expansion = null;
|
||||||
var hasExpansion = ((data[offset++] & 0x10) == 0x10);
|
var hasExpansion = ((data[offset] & 0x10) == 0x10);
|
||||||
|
var listenable = ((data[offset++] & 0x8) == 0x8);
|
||||||
|
|
||||||
var name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, (int)data[offset]);
|
var name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, (int)data[offset]);
|
||||||
offset += (uint)data[offset] + 1;
|
offset += (uint)data[offset] + 1;
|
||||||
@ -449,7 +459,7 @@ namespace Esiur.Resource.Template
|
|||||||
offset += cs;
|
offset += cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
var et = new EventTemplate(od, eventIndex++, name, expansion);
|
var et = new EventTemplate(od, eventIndex++, name, expansion, listenable);
|
||||||
|
|
||||||
od.events.Add(et);
|
od.events.Add(et);
|
||||||
|
|
||||||
|
@ -57,11 +57,12 @@ namespace Esiur.Resource
|
|||||||
|
|
||||||
static bool warehouseIsOpen = false;
|
static bool warehouseIsOpen = false;
|
||||||
|
|
||||||
public delegate void StoreConnectedEvent(IStore store, string name);
|
public delegate void StoreEvent(IStore store);//, string name);
|
||||||
public delegate void StoreDisconnectedEvent(IStore store);
|
// public delegate void StoreDisconnectedEvent(IStore store);
|
||||||
|
|
||||||
public static event StoreConnectedEvent StoreConnected;
|
public static event StoreEvent StoreConnected;
|
||||||
public static event StoreDisconnectedEvent StoreDisconnected;
|
//public static event StoreEvent StoreOpen;
|
||||||
|
public static event StoreEvent StoreDisconnected;
|
||||||
|
|
||||||
public delegate AsyncReply<IStore> ProtocolInstance(string name, object properties);
|
public delegate AsyncReply<IStore> ProtocolInstance(string name, object properties);
|
||||||
|
|
||||||
@ -476,18 +477,43 @@ namespace Esiur.Resource
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//public static async AsyncReply<T> Push<T>(string path, T resource) where T : IResource
|
||||||
|
//{
|
||||||
|
// await Put(path, resource);
|
||||||
|
// return resource;
|
||||||
|
//}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Put a resource in the warehouse.
|
/// Put a resource in the warehouse.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="resource">Resource instance.</param>
|
|
||||||
/// <param name="name">Resource name.</param>
|
/// <param name="name">Resource name.</param>
|
||||||
|
/// <param name="resource">Resource instance.</param>
|
||||||
/// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param>
|
/// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param>
|
||||||
/// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param>
|
/// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param>
|
||||||
public static async AsyncReply<bool> Put(IResource resource, string name, IStore store = null, IResource parent = null, ResourceTemplate customTemplate = null, ulong age = 0, IPermissionsManager manager = null, object attributes = null)
|
public static async AsyncReply<T> Put<T>(string name, T resource, IStore store = null, IResource parent = null, ResourceTemplate customTemplate = null, ulong age = 0, IPermissionsManager manager = null, object attributes = null) where T:IResource
|
||||||
{
|
{
|
||||||
if (resource.Instance != null)
|
if (resource.Instance != null)
|
||||||
throw new Exception("Resource has a store.");
|
throw new Exception("Resource has a store.");
|
||||||
|
|
||||||
|
var path = name.TrimStart('/').Split('/');
|
||||||
|
|
||||||
|
if (path.Length > 1)
|
||||||
|
{
|
||||||
|
if (parent != null)
|
||||||
|
throw new Exception("Parent can't be set when using path in instance name");
|
||||||
|
|
||||||
|
parent = await Warehouse.Get(string.Join("/", path.Take(path.Length - 1)));
|
||||||
|
|
||||||
|
if (parent == null)
|
||||||
|
throw new Exception("Can't find parent");
|
||||||
|
|
||||||
|
store = store ?? parent.Instance.Store;
|
||||||
|
}
|
||||||
|
|
||||||
|
var instanceName = path.Last();
|
||||||
|
|
||||||
|
|
||||||
var resourceReference = new WeakReference<IResource>(resource);
|
var resourceReference = new WeakReference<IResource>(resource);
|
||||||
|
|
||||||
if (store == null)
|
if (store == null)
|
||||||
@ -523,7 +549,7 @@ namespace Esiur.Resource
|
|||||||
throw new Exception("Can't find a store for the resource.");
|
throw new Exception("Can't find a store for the resource.");
|
||||||
}
|
}
|
||||||
|
|
||||||
resource.Instance = new Instance(resourceCounter++, name, resource, store, customTemplate, age);
|
resource.Instance = new Instance(resourceCounter++, instanceName, resource, store, customTemplate, age);
|
||||||
|
|
||||||
if (attributes != null)
|
if (attributes != null)
|
||||||
resource.Instance.SetAttributes(Structure.FromObject(attributes));
|
resource.Instance.SetAttributes(Structure.FromObject(attributes));
|
||||||
@ -537,42 +563,52 @@ namespace Esiur.Resource
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (resource is IStore)
|
try
|
||||||
stores.TryAdd(resource as IStore, new List<WeakReference<IResource>>());
|
|
||||||
|
|
||||||
|
|
||||||
if (!await store.Put(resource))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
|
||||||
if (parent != null)
|
|
||||||
{
|
{
|
||||||
await parent.Instance.Store.AddChild(parent, resource);
|
|
||||||
await store.AddParent(resource, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
var t = resource.GetType();
|
|
||||||
Global.Counters["T-" + t.Namespace + "." + t.Name]++;
|
|
||||||
|
|
||||||
|
|
||||||
resources.TryAdd(resource.Instance.Id, resourceReference);
|
|
||||||
|
|
||||||
if (warehouseIsOpen)
|
|
||||||
{
|
|
||||||
await resource.Trigger(ResourceTrigger.Initialize);
|
|
||||||
if (resource is IStore)
|
if (resource is IStore)
|
||||||
await resource.Trigger(ResourceTrigger.Open);
|
stores.TryAdd(resource as IStore, new List<WeakReference<IResource>>());
|
||||||
|
|
||||||
|
|
||||||
|
if (!await store.Put(resource))
|
||||||
|
throw new Exception("Store failed to put the resource");
|
||||||
|
//return default(T);
|
||||||
|
|
||||||
|
|
||||||
|
if (parent != null)
|
||||||
|
{
|
||||||
|
await parent.Instance.Store.AddChild(parent, resource);
|
||||||
|
await store.AddParent(resource, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
var t = resource.GetType();
|
||||||
|
Global.Counters["T-" + t.Namespace + "." + t.Name]++;
|
||||||
|
|
||||||
|
|
||||||
|
resources.TryAdd(resource.Instance.Id, resourceReference);
|
||||||
|
|
||||||
|
if (warehouseIsOpen)
|
||||||
|
{
|
||||||
|
await resource.Trigger(ResourceTrigger.Initialize);
|
||||||
|
if (resource is IStore)
|
||||||
|
await resource.Trigger(ResourceTrigger.Open);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource is IStore)
|
||||||
|
StoreConnected?.Invoke(resource as IStore);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Warehouse.Remove(resource);
|
||||||
|
throw ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resource is IStore)
|
return resource;
|
||||||
StoreConnected?.Invoke(resource as IStore, name);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async AsyncReply<IResource> New(Type type, string name = null, IStore store = null, IResource parent = null, IPermissionsManager manager = null, object attributes = null, object properties = null)
|
public static async AsyncReply<IResource> New(Type type, string name = null, IStore store = null, IResource parent = null, IPermissionsManager manager = null, object attributes = null, object properties = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
type = ResourceProxy.GetProxy(type);
|
type = ResourceProxy.GetProxy(type);
|
||||||
|
|
||||||
|
|
||||||
@ -618,15 +654,33 @@ namespace Esiur.Resource
|
|||||||
{
|
{
|
||||||
|
|
||||||
var pi = type.GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
var pi = type.GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
||||||
if (pi != null && pi.CanWrite)
|
if (pi != null)
|
||||||
{
|
{
|
||||||
try
|
if (pi.CanWrite)
|
||||||
{
|
{
|
||||||
pi.SetValue(res, p.Value);
|
try
|
||||||
|
{
|
||||||
|
pi.SetValue(res, p.Value);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Global.Log(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var fi = type.GetField(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
||||||
|
if (fi != null)
|
||||||
{
|
{
|
||||||
Global.Log(ex);
|
try
|
||||||
|
{
|
||||||
|
fi.SetValue(res, p.Value);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Global.Log(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -634,8 +688,10 @@ namespace Esiur.Resource
|
|||||||
|
|
||||||
if (store != null || parent != null || res is IStore)
|
if (store != null || parent != null || res is IStore)
|
||||||
{
|
{
|
||||||
if (!await Put(res, name, store, parent, null, 0, manager, attributes))
|
//if (!await Put(name, res, store, parent, null, 0, manager, attributes))
|
||||||
return null;
|
// return null;
|
||||||
|
|
||||||
|
await Put(name, res, store, parent, null, 0, manager, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -35,11 +35,11 @@ using Esiur.Resource;
|
|||||||
|
|
||||||
namespace Esiur.Security.Membership
|
namespace Esiur.Security.Membership
|
||||||
{
|
{
|
||||||
public interface IMembership : IResource
|
public interface IMembership
|
||||||
{
|
{
|
||||||
AsyncReply<bool> UserExists(string username, string domain);
|
AsyncReply<bool> UserExists(string username, string domain);
|
||||||
AsyncReply<byte[]> GetPassword(string username, string domain);
|
AsyncReply<byte[]> GetPassword(string username, string domain);
|
||||||
AsyncReply<byte[]> GetToken(ulong TokenIndex, string domain);
|
AsyncReply<byte[]> GetToken(ulong tokenIndex, string domain);
|
||||||
AsyncReply<bool> Login(Session session);
|
AsyncReply<bool> Login(Session session);
|
||||||
AsyncReply<bool> Logout(Session session);
|
AsyncReply<bool> Logout(Session session);
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ namespace Esiur.Security.Permissions
|
|||||||
|
|
||||||
public bool Initialize(Structure settings, IResource resource)
|
public bool Initialize(Structure settings, IResource resource)
|
||||||
{
|
{
|
||||||
|
this.settings = settings;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ namespace Esiur.Stores
|
|||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
|
OnDestroy?.Invoke(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Link(IResource resource)
|
public string Link(IResource resource)
|
||||||
@ -41,14 +41,14 @@ namespace Esiur.Stores
|
|||||||
return new AsyncReply<IResource>(null);
|
return new AsyncReply<IResource>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async AsyncReply<bool> Put(IResource resource)
|
public AsyncReply<bool> Put(IResource resource)
|
||||||
{
|
{
|
||||||
|
|
||||||
resources.Add(resource.Instance.Id, resource);// new WeakReference<IResource>(resource));
|
resources.Add(resource.Instance.Id, resource);// new WeakReference<IResource>(resource));
|
||||||
resource.Instance.Variables["children"] = new AutoList<IResource, Instance>(resource.Instance);
|
resource.Instance.Variables["children"] = new AutoList<IResource, Instance>(resource.Instance);
|
||||||
resource.Instance.Variables["parents"] = new AutoList<IResource, Instance>(resource.Instance);
|
resource.Instance.Variables["parents"] = new AutoList<IResource, Instance>(resource.Instance);
|
||||||
|
|
||||||
return true;
|
return new AsyncReply<bool>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncReply<IResource> Retrieve(uint iid)
|
public AsyncReply<IResource> Retrieve(uint iid)
|
||||||
|
@ -20,6 +20,7 @@ namespace Esiur.Stores
|
|||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
|
OnDestroy?.Invoke(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,19 +32,19 @@ namespace Esiur.Stores
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async AsyncReply<IResource> Get(string path)
|
public AsyncReply<IResource> Get(string path)
|
||||||
{
|
{
|
||||||
foreach (var r in resources)
|
foreach (var r in resources)
|
||||||
if (r.Value.IsAlive && (r.Value.Target as IResource).Instance.Name == path)
|
if (r.Value.IsAlive && (r.Value.Target as IResource).Instance.Name == path)
|
||||||
return r.Value.Target as IResource;
|
return new AsyncReply<IResource>(r.Value.Target as IResource);
|
||||||
|
|
||||||
return null;
|
return new AsyncReply<IResource>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async AsyncReply<bool> Put(IResource resource)
|
public AsyncReply<bool> Put(IResource resource)
|
||||||
{
|
{
|
||||||
resources.Add(resource.Instance.Id, new WeakReference( resource));// new WeakReference<IResource>(resource));
|
resources.Add(resource.Instance.Id, new WeakReference( resource));// new WeakReference<IResource>(resource));
|
||||||
return true;
|
return new AsyncReply<bool>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncReply<IResource> Retrieve(uint iid)
|
public AsyncReply<IResource> Retrieve(uint iid)
|
||||||
|
Reference in New Issue
Block a user