using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Threading.Tasks;
using System.Text.Json;
using Microsoft.AspNetCore.Http;
using LC.Newtonsoft.Json;
using Microsoft.Extensions.Primitives;
using Microsoft.Extensions.DependencyInjection;
using LeanCloud.Common;
namespace LeanCloud.Engine {
///
/// LCEngine provides the initialization of LeanEngine.
///
public class LCEngine {
public const string LCEngineCORS = "LCEngineCORS";
const string LCMasterKeyName = "x-avoscloud-master-key";
const string LCHookKeyName = "x-lc-hook-key";
const string BeforeSave = "__before_save_for_";
const string AfterSave = "__after_save_for_";
const string BeforeUpdate = "__before_update_for_";
const string AfterUpdate = "__after_update_for_";
const string BeforeDelete = "__before_delete_for_";
const string AfterDelete = "__after_delete_for_";
internal const string OnSMSVerified = "__on_verified_sms";
internal const string OnEmailVerified = "__on_verified_email";
internal const string OnLogin = "__on_login__User";
const string ClientOnline = "_clientOnline";
const string ClientOffline = "_clientOffline";
const string MessageSent = "_messageSent";
const string MessageReceived = "_messageReceived";
const string ReceiversOffline = "_receiversOffline";
const string MessageUpdate = "_messageUpdate";
const string ConversationStart = "_conversationStart";
const string ConversationStarted = "_conversationStarted";
const string ConversationAdd = "_conversationAdd";
const string ConversationAdded = "_conversationAdded";
const string ConversationRemove = "_conversationRemove";
const string ConversationRemoved = "_conversationRemoved";
const string ConversationUpdate = "_conversationUpdate";
static readonly string[] LCEngineCORSMethods = new string[] {
"PUT",
"GET",
"POST",
"DELETE",
"OPTIONS"
};
static readonly string[] LCEngineCORSHeaders = new string[] {
"Content-Type",
"X-AVOSCloud-Application-Id",
"X-AVOSCloud-Application-Key",
"X-AVOSCloud-Application-Production",
"X-AVOSCloud-Client-Version",
"X-AVOSCloud-Request-Sign",
"X-AVOSCloud-Session-Token",
"X-AVOSCloud-Super-Key",
"X-LC-Hook-Key",
"X-LC-Id",
"X-LC-Key",
"X-LC-Prod",
"X-LC-Session",
"X-LC-Sign",
"X-LC-UA",
"X-Requested-With",
"X-Uluru-Application-Id",
"X-Uluru-Application-Key",
"X-Uluru-Application-Production",
"X-Uluru-Client-Version",
"X-Uluru-Session-Token"
};
public static Dictionary Functions = new Dictionary();
public static Dictionary ClassHooks = new Dictionary();
public static Dictionary UserHooks = new Dictionary();
///
/// Initializes the engine with the given services.
///
///
public static void Initialize(IServiceCollection services) {
// 获取环境变量
LCLogger.Debug("-------------------------------------------------");
PrintEnvironmentVar("LEANCLOUD_APP_ID");
PrintEnvironmentVar("LEANCLOUD_APP_KEY");
PrintEnvironmentVar("LEANCLOUD_APP_MASTER_KEY");
PrintEnvironmentVar("LEANCLOUD_APP_HOOK_KEY");
PrintEnvironmentVar("LEANCLOUD_API_SERVER");
PrintEnvironmentVar("LEANCLOUD_APP_PROD");
PrintEnvironmentVar("LEANCLOUD_APP_ENV");
PrintEnvironmentVar("LEANCLOUD_APP_INSTANCE");
PrintEnvironmentVar("LEANCLOUD_REGION");
PrintEnvironmentVar("LEANCLOUD_APP_ID");
PrintEnvironmentVar("LEANCLOUD_APP_DOMAIN");
PrintEnvironmentVar("LEANCLOUD_APP_PORT");
LCLogger.Debug("-------------------------------------------------");
LCApplication.Initialize(Environment.GetEnvironmentVariable("LEANCLOUD_APP_ID"),
Environment.GetEnvironmentVariable("LEANCLOUD_APP_KEY"),
Environment.GetEnvironmentVariable("LEANCLOUD_API_SERVER"));
LCCore.HttpClient.AddAddtionalHeader(LCHookKeyName, Environment.GetEnvironmentVariable("LEANCLOUD_APP_HOOK_KEY"));
Assembly assembly = Assembly.GetCallingAssembly();
ClassHooks = assembly.GetTypes()
.SelectMany(t => t.GetMethods())
.Where(m => m.GetCustomAttribute() != null)
.ToDictionary(mi => {
LCEngineClassHookAttribute attr = mi.GetCustomAttribute();
switch (attr.HookType) {
case LCEngineObjectHookType.BeforeSave:
return $"{BeforeSave}{attr.ClassName}";
case LCEngineObjectHookType.AfterSave:
return $"{AfterSave}{attr.ClassName}";
case LCEngineObjectHookType.BeforeUpdate:
return $"{BeforeUpdate}{attr.ClassName}";
case LCEngineObjectHookType.AfterUpdate:
return $"{AfterUpdate}{attr.ClassName}";
case LCEngineObjectHookType.BeforeDelete:
return $"{BeforeDelete}{attr.ClassName}";
case LCEngineObjectHookType.AfterDelete:
return $"{AfterDelete}{attr.ClassName}";
default:
throw new Exception($"Error hook type: {attr.HookType}");
}
});
UserHooks = assembly.GetTypes()
.SelectMany(t => t.GetMethods())
.Where(m => m.GetCustomAttribute() != null)
.ToDictionary(mi => {
LCEngineUserHookAttribute attr = mi.GetCustomAttribute();
switch (attr.HookType) {
case LCEngineUserHookType.OnSMSVerified:
return OnSMSVerified;
case LCEngineUserHookType.OnEmailVerified:
return OnEmailVerified;
case LCEngineUserHookType.OnLogin:
return OnLogin;
default:
throw new Exception($"Error hook type: {attr.HookType}");
}
});
Functions = assembly.GetTypes()
.SelectMany(t => t.GetMethods())
.Where(m => m.GetCustomAttribute() != null)
.ToDictionary(mi => mi.GetCustomAttribute().FunctionName);
assembly.GetTypes()
.SelectMany(t => t.GetMethods())
.Where(m => m.GetCustomAttribute() != null)
.ToDictionary(mi => {
LCEngineRealtimeHookAttribute attr = mi.GetCustomAttribute();
switch (attr.HookType) {
case LCEngineRealtimeHookType.ClientOnline:
return ClientOnline;
case LCEngineRealtimeHookType.ClientOffline:
return ClientOffline;
case LCEngineRealtimeHookType.MessageSent:
return MessageSent;
case LCEngineRealtimeHookType.MessageReceived:
return MessageReceived;
case LCEngineRealtimeHookType.ReceiversOffline:
return ReceiversOffline;
case LCEngineRealtimeHookType.MessageUpdate:
return MessageUpdate;
case LCEngineRealtimeHookType.ConversationStart:
return ConversationStart;
case LCEngineRealtimeHookType.ConversationStarted:
return ConversationStarted;
case LCEngineRealtimeHookType.ConversationAdd:
return ConversationAdd;
case LCEngineRealtimeHookType.ConversationAdded:
return ConversationAdded;
case LCEngineRealtimeHookType.ConversationRemove:
return ConversationRemove;
case LCEngineRealtimeHookType.ConversationRemoved:
return ConversationRemoved;
case LCEngineRealtimeHookType.ConversationUpdate:
return ConversationUpdate;
default:
throw new Exception($"Error hook type: {attr.HookType}");
}
})
.ToList()
.ForEach(item => {
Functions.TryAdd(item.Key, item.Value);
});
services.AddCors(options => {
options.AddPolicy(LCEngineCORS, builder => {
builder.AllowAnyOrigin()
.WithMethods(LCEngineCORSMethods)
.WithHeaders(LCEngineCORSHeaders)
.SetPreflightMaxAge(TimeSpan.FromSeconds(86400));
});
});
}
private static void PrintEnvironmentVar(string key) {
LCLogger.Debug($"{key} : {Environment.GetEnvironmentVariable(key)}");
}
internal static async Task