internal static void FlushCallBuffer() { DataTable tblCallLogBuffer = GetCallLogBufferTable(); LogMethodParams callLog; while (_bufferedCallLogQueue.TryDequeue(out callLog)) { DataRow row = tblCallLogBuffer.NewRow(); row["MethodId"] = callLog.MethodId; row["ExecutionDuration"] = callLog.ExecutionDuration; row["CalledAt"] = callLog.CalledAt; row["ApplicationId"] = callLog.ApplicationId; row["HandledByIpAddress"] = callLog.HandledByIpAddress; row["HostIpAddress"] = callLog.HostIpAddress; row["UserIpAddress"] = callLog.UserIpAddress; tblCallLogBuffer.Rows.Add(row); } using (LegionLinqDataContext db = new LegionLinqDataContext(ConfigurationManager.ConnectionStrings["LegionConnectionString"].ToString())) using (SqlBulkCopy bulkCopy = new SqlBulkCopy(ConfigurationManager.ConnectionStrings["LegionConnectionString"].ToString())) { bulkCopy.DestinationTableName = "dbo.tblCallLogBuffer"; try { bulkCopy.WriteToServer(tblCallLogBuffer); } catch (Exception ex) { Console.WriteLine(ex.Message); } } }
internal static CachedResult GetCachedResult(int methodid, Binary key) { CachedResult result = new CachedResult() { Found = false }; object oResult = Cache.Get(CACHE_TYPE, GetCacheKey(methodid, key)); if (oResult == null) { using (LegionLinqDataContext legion = new LegionLinqDataContext(ConfigurationManager.ConnectionStrings["LegionConnectionString"].ToString())) { xspGetCachedResultResult cachedResult = legion.xspGetCachedResult(methodid, key).FirstOrDefault(); if (cachedResult != default(xspGetCachedResultResult)) { result.Result = cachedResult.Result; result.UpdatedOn = cachedResult.UpdatedOn; result.ExpiresOn = cachedResult.ExpiresOn; result.Found = true; CacheResultLocally(methodid, key, result); } } } else { result = (CachedResult)oResult; } return(result); }
private static string GetSettingFromDatabase(string key) { string value = null; using (LegionLinqDataContext db = new LegionLinqDataContext(ConfigurationManager.ConnectionStrings["LegionConnectionString"].ToString())) { db.xspGetSettingByKey(key, ref value); } return(value); }
private void GetSettings() { if (_settings == null) { Regex credentialsRegex = new Regex(Legion.Core.Settings.GetString("SettingsCredentialInsertionRegex")); string setting; object oSettings = Cache.Get(CACHE_TYPE, _serviceKey); if (oSettings != null) { _settings = (Dictionary <string, string>)oSettings; } else { _settings = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); string resultcode = null; using (LegionLinqDataContext db = new LegionLinqDataContext(ConfigurationManager.ConnectionStrings["LegionConnectionString"].ToString())) { ISingleResult <xspGetServiceSettingsResult> settings = db.xspGetServiceSettings(_serviceKey, null, ref resultcode); foreach (xspGetServiceSettingsResult s in settings) { if (s.IsEncrypted) { Encryption.Packet packet = Modules.Encryption.Module.DecryptString(new Encryption.Packet() { IV = s.IV, CipherText = s.Value, }); setting = packet.ClearText; } else { setting = s.Value; } MatchCollection credentials = credentialsRegex.Matches(setting); foreach (Match credential in credentials) { setting = setting.Replace( credential.Groups["Credential"].Value, Credentials.Module.GetServiceCredential(_serviceId, credential.Groups["Name"].Value) ?? credential.Groups["Credential"].Value ); } _settings.Add(s.Name, setting); } } Cache.Add(CACHE_TYPE, _serviceKey, _settings); } } }
/// <summary> /// Refreshes the cache if there have been updates to the database /// </summary> /// <returns>The number of exceptions that were thrown while loading the cache</returns> public static int Refresh() { System.Web.Caching.Cache cache = HttpRuntime.Cache; while (IsLoading) { Logging.Module.WriteEvent(new LoggedEvent(EventLevel.Info, "CacheLoadWait", Settings.GetString("LogFormatCacheLoadWait", new Dictionary <string, string>() { { "Interval", Settings.GetInt("CacheLoadingSleepInterval").ToString() } }), true)); System.Threading.Thread.Sleep(Settings.GetInt("CacheLoadingSleepInterval")); } if (!IsLoaded) { return(ForceRefresh()); } else { DateTime lastCacheRefreshCheck = (HttpContext.Current.Application["LastComponentCacheRefreshCheck"] == null ? DateTime.MinValue : (DateTime)HttpContext.Current.Application["LastComponentCacheRefreshCheck"]); if (lastCacheRefreshCheck <= DateTime.Now.Subtract(new TimeSpan(0, 0, Settings.GetInt("CacheRefreshCheckInterval")))) { using (LegionLinqDataContext db = new LegionLinqDataContext(ConfigurationManager.ConnectionStrings["LegionConnectionString"].ToString())) { string ipaddress = ServerDetails.IPv4Addresses.First().ToString(); bool? refreshCache = null; db.xspGetCacheStatus(ipaddress, ref refreshCache); HttpContext.Current.Application["LastComponentCacheRefreshCheck"] = DateTime.Now; if (refreshCache == true) { return(ForceRefresh()); } else { return(-1); } } } else { return(-1); } } }
/// <summary> /// Trys to expire the results cache if needed. /// NOT THREAD SAFE /// </summary> internal static void TryExpire() { DateTime lastCacheRefreshCheck = (HttpContext.Current.Application["LastCacheResultsExpireCheck"] == null ? DateTime.MinValue : (DateTime)HttpContext.Current.Application["LastCacheResultsExpireCheck"]); if (lastCacheRefreshCheck <= DateTime.Now.Subtract(new TimeSpan(0, 0, Settings.GetInt("CacheRefreshCheckInterval")))) { using (LegionLinqDataContext db = new LegionLinqDataContext(ConfigurationManager.ConnectionStrings["LegionConnectionString"].ToString())) { ISingleResult <xspGetExpiredCachedResultsResult> expiredResults = db.xspGetExpiredCachedResults(Settings.GetInt("CacheRefreshCheckInterval")); TimeSpan cachePadding = new TimeSpan(0, 0, Settings.GetInt("ResultCachingDurationPadding")); foreach (xspGetExpiredCachedResultsResult expiredResult in expiredResults) { ExpireResult(expiredResult.MethodId, expiredResult.CacheKey, cachePadding); } HttpContext.Current.Application["LastCacheResultsExpireCheck"] = DateTime.Now; } } }
/// <summary> /// Determins whether or not the application has access to the specificed Server,Method /// </summary> /// <param name="serviceKey">The key of the service to which access is being requested</param> /// <param name="methodKey">The key of the method to which access is being requested</param> /// <returns>true if the application has access to the method, false otherwise</returns> public bool HasPermissionTo(string serviceKey, string methodKey) { bool? authorized = false; string permissionsKey = string.Format(PERMISSIONS_KEY_FORMAT, serviceKey, methodKey); if (_permissions.ContainsKey(permissionsKey)) { return(_permissions[permissionsKey]); } else { using (LegionLinqDataContext legion = new LegionLinqDataContext(ConfigurationManager.ConnectionStrings["LegionConnectionString"].ToString())) { legion.xspCheckPermission(_id, serviceKey, methodKey, ref authorized); } //TODO: Should there be locking here? _permissions.Add(permissionsKey, (bool)authorized); Cache.Add(CACHE_TYPE, this.APIKey, this); return((bool)authorized); } }
private static void LogMethodCallThread(object oParameters) { LogMethodParams parameters = (LogMethodParams)oParameters; try { using (LegionLinqDataContext legion = new LegionLinqDataContext(ConfigurationManager.ConnectionStrings["LegionConnectionString"].ToString())) { legion.xspLogMethodCall( parameters.MethodId, parameters.ExecutionDuration, parameters.CalledAt, parameters.ApplicationId, parameters.HandledByIpAddress, parameters.HostIpAddress, parameters.UserIpAddress, parameters.PermanentLog ); } } catch (SqlException) { //TODO: Log to flat file } }
internal static void CacheResult(int methodid, Binary key, XElement parameters, XElement resultset) { DateTime?expiresOn = null; using (LegionLinqDataContext legion = new LegionLinqDataContext(ConfigurationManager.ConnectionStrings["LegionConnectionString"].ToString())) { legion.xspInsertCachedResult( methodid, parameters, resultset, key, ref expiresOn ); } CachedResult cachedResult = new CachedResult() { Result = resultset, UpdatedOn = DateTime.Now, ExpiresOn = (expiresOn == null ? DateTime.Now : (DateTime)expiresOn), Found = true }; CacheResultLocally(methodid, key, cachedResult); }
/// <summary> /// Constructor /// </summary> /// <param name="apiKey">The API key of the application</param> public Application(string apiKey) { if (apiKey != null && apiKey.Length > 0) { object oApplication = Cache.Get(CACHE_TYPE, apiKey); if (oApplication != null) { Application application = (Application)oApplication; _apikey = application._apikey; _name = application._name; _description = application._description; _id = application._id; _isPublic = application._isPublic; _isLogged = application._isLogged; _sourceIpRange = application._sourceIpRange; _permissions = application._permissions; _rateLimit = application._rateLimit; _rateInterval = application._rateInterval; _rateType = application._rateType; } else { string sourceIpRange = null, rateType = null; bool? isLogged = null, isPublic = null; int? rateLimitId = null, rateLimit = null, rateInterval = null; using (LegionLinqDataContext legion = new LegionLinqDataContext(ConfigurationManager.ConnectionStrings["LegionConnectionString"].ToString())) { legion.xspGetApplication(apiKey, ref _id, ref _name, ref sourceIpRange, ref _description, ref rateLimitId, ref rateType, ref rateLimit, ref rateInterval, ref isPublic, ref isLogged); } _apikey = apiKey; _rateLimit = rateLimit ?? Settings.GetInt("RateLimitDefault"); _rateInterval = rateInterval ?? Settings.GetInt("RateLimitIntervalDefault"); _rateType = (rateType == null ? RateType.Default : (RateType)Enum.Parse(typeof(RateType), rateType, true)); _isPublic = (isPublic == true ? true : false); _isLogged = (isLogged == true ? true : false); if (sourceIpRange != null && sourceIpRange != string.Empty) { try { _sourceIpRange = new IpAddressRange(sourceIpRange); } catch { string message = Settings.GetString("ExceptionMessageApplicationInvalidIpRange", new Dictionary <string, string>() { { "IpRange", sourceIpRange }, { "ApplicationName", _name }, { "ApiKey", apiKey } }); Logging.Module.WriteException(new LoggedException() { Type = "BadIPRange", Message = message }); throw new Exception(message); } } Cache.Add(CACHE_TYPE, apiKey, this); } } else { _apikey = null; _name = Settings.GetString("SymbolUnknown"); _description = string.Empty; _id = 0; _isPublic = false; _isLogged = false; _sourceIpRange = null; _permissions = null; _rateLimit = Settings.GetInt("RateLimitDefault"); _rateInterval = Settings.GetInt("RateLimitIntervalDefault"); _rateType = RateType.Default; } }
/// <summary> /// Loads the Legion Services from the database into memory /// </summary> /// <returns>The number of exceptions that were thrown while loading the cache</returns> public static int Load() { Logging.Module.WriteEvent(new LoggedEvent(EventLevel.Info, "CacheLoadStart", Settings.GetString("LogFormatCacheLoadStart"), true)); Insert(CACHE_KEYS.CacheLoading, "true"); System.Web.Caching.Cache cache = HttpRuntime.Cache; Dictionary <string, Service> legion = new Dictionary <string, Service>(); List <string> keyRevocationList = new List <string>(); int exceptionCount = 0; string assemblyDirectory = null; bool loadMethod, isAutheticatedUserRequired, isAuthorizedUserRequired; Assembly assembly; Type t; Service service; MethodInfo mi; IpAddressRange consumerIPRange; Version version; Dictionary <string, Method> serviceMethods; Dictionary <string, Method> systemMethods = new Dictionary <string, Method>(); Dictionary <string, Method> statusMethods = new Dictionary <string, Method>(); Dictionary <string, string> systemMethodKeys = Settings.GetDictionary("SystemMethods"); using (LegionLinqDataContext db = new LegionLinqDataContext(ConfigurationManager.ConnectionStrings["LegionConnectionString"].ToString())) { assemblyDirectory = Settings.GetString("AssemblyDirectory"); if (Directory.Exists(assemblyDirectory)) { //load services Logging.Module.WriteEvent(new LoggedEvent(EventLevel.Info, "ServiceLoadStart", Settings.GetString("LogFormatCacheServiceLoadStart"), true)); ISingleResult <xspGetServicesResult> services = db.xspGetServices(); foreach (xspGetServicesResult result in services) { isAutheticatedUserRequired = false; isAuthorizedUserRequired = false; if (!legion.ContainsKey(result.ServiceKey)) { if (!result.ServiceKey.StartsWith("__")) { try { assembly = Assembly.LoadFile(string.Format(@"{0}\{1}.dll", assemblyDirectory, result.AssemblyName)); t = assembly.GetType(result.AssemblyName + "." + result.ClassName); if (t != null && t.IsClass) { Attribute[] attributes = Attribute.GetCustomAttributes(t); foreach (Attribute attribute in attributes) { LegionAttribute lAttribute = attribute as LegionAttribute; if (lAttribute != null) { if (!isAutheticatedUserRequired && lAttribute.IsAuthenticatedUserRequired) { isAutheticatedUserRequired = true; } if (!isAuthorizedUserRequired && lAttribute.IsAuthorizedUserRequired) { isAuthorizedUserRequired = true; } } } consumerIPRange = (result.ConsumerIPRange == null || result.ConsumerIPRange == string.Empty ? null : new IpAddressRange(result.ConsumerIPRange)); version = assembly.GetName().Version; legion.Add( result.ServiceKey.ToLower(), new Service( result.ServiceId, result.ServiceKey, t, consumerIPRange, string.Format("{0}.{1}.{2}.{3}", version.Major, version.Minor, version.Build, version.Revision ), Settings.FormatDateTime(assembly.GetCompileDate()), result.IsPublic, result.IsLogged, isAutheticatedUserRequired, isAuthorizedUserRequired ) ); } else { Logging.Module.WriteException(new LoggedException() { Type = "CacheClassNotFound", Message = Settings.GetString("ExceptionMessageCacheClassNotFound", new Dictionary <string, string>() { { "AssemblyName", result.AssemblyName }, { "ClassName", result.ClassName } }) }); } } catch (System.IO.FileNotFoundException e) { Logging.Module.WriteException(new LoggedException() { Type = "AssemblyNotFound", Message = Settings.GetString("ExceptionMessageCacheAssemblyNotFound", new Dictionary <string, string>() { { "AssemblyName", result.AssemblyName } }), StackTrace = e.StackTrace }); exceptionCount++; } catch (Exception) { Logging.Module.WriteException(new LoggedException() { Type = "BadIPRange", Message = Settings.GetString("ExceptionMessageCacheInvalidServiceIpRange", new Dictionary <string, string>() { { "IpRange", result.ConsumerIPRange }, { "ServiceKey", result.ServiceKey } }) }); exceptionCount++; } } else { Logging.Module.WriteException(new LoggedException() { Type = "CacheInvalidServiceKey", Message = Settings.GetString("ExceptionMessageCacheInvalidServiceKey", new Dictionary <string, string>() { { "ServiceKey", result.ServiceKey } }) }); } } } //add system service legion.Add( Settings.GetString("SystemServiceKey"), new Service( -1, Settings.GetString("SystemServiceKey"), null, null, "0.0.0.0", Settings.FormatDateTime(DateTime.Now), false, false, false, false ) ); Logging.Module.WriteEvent(new LoggedEvent(EventLevel.Info, "ServiceLoadFinish", Settings.GetString("LogFormatCacheServiceLoadFinish"), true)); //load methods Logging.Module.WriteEvent(new LoggedEvent(EventLevel.Info, "MethodLoadStart", Settings.GetString("LogFormatCacheMethodLoadStart"), true)); ISingleResult <xspGetMethodsResult> methods = db.xspGetMethods(); foreach (xspGetMethodsResult result in methods) { if (legion.ContainsKey(result.ServiceKey.ToLower())) { service = legion[result.ServiceKey.ToLower()]; } else { Logging.Module.WriteException(new LoggedException() { Type = "ServiceKeyNotFound", Message = Settings.GetString("ExceptionMessageCacheServiceKeyNotFound", new Dictionary <string, string>() { { "ServiceKey", result.ServiceKey.ToLower() }, { "MethodKey", result.MethodKey }, { "MethodId", result.MethodId.ToString() } }) }); continue; } serviceMethods = (result.IsRestricted == true ? service.Restricted : service.Open); string rc = null; mi = service.ServiceType.GetMethod(result.MethodName, BindingFlags.Public | BindingFlags.Static); if (mi != null) { loadMethod = true; isAutheticatedUserRequired = false; isAuthorizedUserRequired = false; Attribute[] attributes = Attribute.GetCustomAttributes(mi); foreach (Attribute attribute in attributes) { LegionAttribute lAttribute = attribute as LegionAttribute; if (lAttribute != null) { if (result.IsResultCacheable && !lAttribute.IsCacheable) { Logging.Module.WriteException(new LoggedException() { Type = "ExceptionMessageCacheMethodNotCacheable", Message = Settings.GetString("ExceptionMessageCacheMethodNotCacheable", new Dictionary <string, string>() { { "ServiceKey", result.ServiceKey }, { "MethodKey", result.MethodKey }, { "MethodId", result.MethodId.ToString() }, { "AttributeName", attribute.GetType().Name } }) }); exceptionCount++; loadMethod = false; break; } if (!isAutheticatedUserRequired && lAttribute.IsAuthenticatedUserRequired) { isAutheticatedUserRequired = true; } if (!isAuthorizedUserRequired && lAttribute.IsAuthorizedUserRequired) { isAuthorizedUserRequired = true; } } } if (loadMethod) { serviceMethods.Add( result.MethodKey.ToLower(), new Method( result.MethodId, result.MethodKey.ToLower(), result.MethodName, result.ServiceId, result.ServiceKey, result.IsPublic, result.IsLogged, isAutheticatedUserRequired, isAuthorizedUserRequired, result.IsResultCacheable, result.IsLogReplayDetailsOnException, result.CachedResultLifetime, mi ) ); //add system method handles foreach (KeyValuePair <string, string> systemMethod in systemMethodKeys.Where(k => k.Value.ToLower() == string.Format("{0}.{1}()", result.ServiceKey, result.MethodKey).ToLower())) { legion[Settings.GetString("SystemServiceKey")].Open.Add( systemMethod.Key.ToLower(), serviceMethods[result.MethodKey.ToLower()] ); } if (result.IsMissing) { db.xspUpdateMethodMissingFlag(result.MethodId, false, ref rc); } } } else { if (!result.IsMissing) { db.xspUpdateMethodMissingFlag(result.MethodId, true, ref rc); Logging.Module.WriteException(new LoggedException() { Type = "MethodNotFound", Message = Settings.GetString("", new Dictionary <string, string>() { { "ServiceKey", result.ServiceKey }, { "MethodKey", result.MethodKey }, { "MethodName", result.MethodName }, { "MethodId", result.MethodId.ToString() }, }) }); exceptionCount++; } } } Logging.Module.WriteEvent(new LoggedEvent(EventLevel.Info, "MethodLoadFinish", Settings.GetString("LogFormatCacheMethodLoadFinish"), true)); //load revocation list Logging.Module.WriteEvent(new LoggedEvent(EventLevel.Info, "KeyRevocationListLoadStart", Settings.GetString("LogFormatCacheKeyRevocationListLoadStart"), true)); ISingleResult <xspGetKeyRevocationListResult> revocations = db.xspGetKeyRevocationList(); foreach (xspGetKeyRevocationListResult result in revocations) { keyRevocationList.Add(result.Key); } Logging.Module.WriteEvent(new LoggedEvent(EventLevel.Info, "KeyRevocationListLoadFinish", Settings.GetString("LogFormatCacheKeyRevocationListLoadFinish"), true)); //cache service status methods Logging.Module.WriteEvent(new LoggedEvent(EventLevel.Info, "ServiceStatusListLoadStart", Settings.GetString("LogFormatCacheServiceStatusListLoadStart"), true)); foreach (KeyValuePair <string, Service> s in legion) { foreach (KeyValuePair <string, string> specialMethod in Method.SPECIAL_METHODS) { Type st = s.Value.ServiceType; if (st != null) { mi = st.GetMethod(specialMethod.Key, BindingFlags.Public | BindingFlags.Static); if (mi != null) { statusMethods.Add(s.Key, new Method(-1, specialMethod.Key.ToLower(), specialMethod.Value, -1, "Special", false, false, false, false, false, false, null, mi)); s.Value.Special.Add(specialMethod.Key.ToLower(), statusMethods[s.Key]); } } } } Logging.Module.WriteEvent(new LoggedEvent(EventLevel.Info, "ServiceStatusListLoadFinish", Settings.GetString("LogFormatCacheServiceStatusListLoadFinish"), true)); Insert(CACHE_KEYS.Services, legion); Insert(CACHE_KEYS.Statuses, statusMethods); Insert(CACHE_KEYS.SystemMethods, systemMethods); Insert(CACHE_KEYS.KeyRevocationList, keyRevocationList); Insert(CACHE_KEYS.AssemblyDirectory, assemblyDirectory); Insert(CACHE_KEYS.LastUpdated, DateTime.Now); string ipaddress = ServerDetails.IPv4Addresses.First().ToString(); string hostname = System.Environment.MachineName; bool? refresh = null; db.xspGetCacheStatus(ipaddress, ref refresh); db.xspGetAssemblyStatus(ipaddress, hostname, ref refresh); } else { Logging.Module.WriteException(new LoggedException() { Type = "BadAssemblyDirectory", Message = Settings.GetString("ExceptionMessageCacheInvalidAssemblyDirectory") }); exceptionCount++; } } HttpRuntime.Cache.Remove(CACHE_KEYS.CacheLoading); Logging.Module.WriteEvent(new LoggedEvent(EventLevel.Info, "CacheLoadFinish", Settings.GetString("LogFormatCacheLoadFinish"), true)); return(exceptionCount); }
/// <summary> /// /// </summary> /// <param name="eventid"></param> /// <param name="methodid"></param> /// <param name="xParameters"></param> /// <param name="exceptionName"></param> /// <param name="exceptionMessage"></param> /// <param name="exceptionStackTrace"></param> public static void LogException(int eventid, int methodid, XmlDocument xParameters, string exceptionName, string exceptionMessage, string exceptionStackTrace) { using (LegionLinqDataContext db = new LegionLinqDataContext(ConfigurationManager.ConnectionStrings["LegionConnectionString"].ToString())) { db.xspLogReplyException(eventid, methodid, xParameters.ToXElement(), exceptionName, exceptionMessage, exceptionStackTrace); } }