public RavenDBOptions(InMemoryRavenConfiguration configuration, DocumentDatabase db = null)
		{
			if (configuration == null)
				throw new ArgumentNullException("configuration");
			
			try
			{
				HttpEndpointRegistration.RegisterHttpEndpointTarget();
			    HttpEndpointRegistration.RegisterAdminLogsTarget();
				if (db == null)
				{
					configuration.UpdateDataDirForLegacySystemDb();
					systemDatabase = new DocumentDatabase(configuration);
					systemDatabase.SpinBackgroundWorkers();
				}
				else
				{
					systemDatabase = db;
				}
			    fileSystemLandlord = new FileSystemsLandlord(systemDatabase);
				databasesLandlord = new DatabasesLandlord(systemDatabase);
				countersLandlord = new CountersLandlord(systemDatabase);
				requestManager = new RequestManager(databasesLandlord);
				mixedModeRequestAuthorizer = new MixedModeRequestAuthorizer();
				mixedModeRequestAuthorizer.Initialize(systemDatabase, new RavenServer(databasesLandlord.SystemDatabase, configuration));
			}
			catch
			{
				if (systemDatabase != null)
					systemDatabase.Dispose();
				throw;
			}
		}
Example #2
0
        public RavenDBOptions(InMemoryRavenConfiguration configuration, DocumentDatabase db = null)
        {
            if (configuration == null)
                throw new ArgumentNullException("configuration");
            
            try
            {
                HttpEndpointRegistration.RegisterHttpEndpointTarget();
                HttpEndpointRegistration.RegisterAdminLogsTarget();
                ThreadPool.SetMinThreads(configuration.MinThreadPoolWorkerThreads, configuration.MinThreadPoolCompletionThreads);
                if (db == null)
                {
                    configuration.UpdateDataDirForLegacySystemDb();
                    systemDatabase = new DocumentDatabase(configuration);
                    systemDatabase.SpinBackgroundWorkers(false);
                }
                else
                {
                    systemDatabase = db;
                }

                WebSocketBufferPool.Initialize(configuration.WebSockets.InitialBufferPoolSize);
                fileSystemLandlord = new FileSystemsLandlord(systemDatabase);
                databasesLandlord = new DatabasesLandlord(systemDatabase);
                countersLandlord = new CountersLandlord(systemDatabase);
                requestManager = new RequestManager(databasesLandlord);
                mixedModeRequestAuthorizer = new MixedModeRequestAuthorizer();
                mixedModeRequestAuthorizer.Initialize(systemDatabase, new RavenServer(databasesLandlord.SystemDatabase, configuration));

                serverStartupTasks = configuration.Container.GetExportedValues<IServerStartupTask>();

                foreach (var task in serverStartupTasks)
                {
                    toDispose.Add(task);
                    task.Execute(this);
                }
            }
            catch
            {
                if (systemDatabase != null)
                    systemDatabase.Dispose();
                throw;
            }
        }
Example #3
0
		private static HttpConfiguration CreateHttpCfg(
            DatabasesLandlord databasesLandlord, 
            FileSystemsLandlord fileSystemsLandlord,
            MixedModeRequestAuthorizer mixedModeRequestAuthorizer, 
            RequestManager requestManager)
		{
			var cfg = new HttpConfiguration();
			cfg.Properties[typeof(DatabasesLandlord)] = databasesLandlord;
            cfg.Properties[typeof(FileSystemsLandlord)] = fileSystemsLandlord;
			cfg.Properties[typeof(MixedModeRequestAuthorizer)] = mixedModeRequestAuthorizer;
			cfg.Properties[typeof(RequestManager)] = requestManager;
			cfg.Formatters.Remove(cfg.Formatters.XmlFormatter);
			cfg.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new NaveValueCollectionJsonConverterOnlyForConfigFormatters());

			cfg.Services.Replace(typeof(IAssembliesResolver), new MyAssemblyResolver());
			cfg.Filters.Add(new RavenExceptionFilterAttribute());
			cfg.MapHttpAttributeRoutes();

			cfg.Routes.MapHttpRoute(
				"RavenFs", "ravenfs/{controller}/{action}",
				new {id = RouteParameter.Optional});

			cfg.Routes.MapHttpRoute(
				"API Default", "{controller}/{action}",
				new { id = RouteParameter.Optional });

			cfg.Routes.MapHttpRoute(
				"Database Route", "databases/{databaseName}/{controller}/{action}",
				new { id = RouteParameter.Optional });

			cfg.MessageHandlers.Add(new GZipToJsonAndCompressHandler());

			cfg.Services.Replace(typeof(IHostBufferPolicySelector), new SelectiveBufferPolicySelector());
			cfg.EnsureInitialized();
			return cfg;
		}
		public override bool SetupRequestToProperDatabase(RequestManager rm)
		{
			var tenantId = CountersName;

			if (string.IsNullOrWhiteSpace(tenantId))
			{
				throw new HttpException(503, "Could not find a counter with no name");
			}

			Task<CounterStorage> resourceStoreTask;
			bool hasDb;
			try
			{
				hasDb = landlord.TryGetOrCreateResourceStore(tenantId, out resourceStoreTask);
			}
			catch (Exception e)
			{
				var msg = "Could open counter named: " + tenantId;
				Logger.WarnException(msg, e);
				throw new HttpException(503, msg, e);
			}
			if (hasDb)
			{
				try
				{
					if (resourceStoreTask.Wait(TimeSpan.FromSeconds(30)) == false)
					{
						var msg = "The counter " + tenantId +
								  " is currently being loaded, but after 30 seconds, this request has been aborted. Please try again later, file system loading continues.";
						Logger.Warn(msg);
						throw new HttpException(503, msg);
					}
					var args = new BeforeRequestWebApiEventArgs
					{
						Controller = this,
						IgnoreRequest = false,
						TenantId = tenantId,
						Counters = resourceStoreTask.Result
					};
					rm.OnBeforeRequest(args);
					if (args.IgnoreRequest)
						return false;
				}
				catch (Exception e)
				{
					var msg = "Could open counters named: " + tenantId;
					Logger.WarnException(msg, e);
					throw new HttpException(503, msg, e);
				}

				landlord.LastRecentlyUsed.AddOrUpdate(tenantId, SystemTime.UtcNow, (s, time) => SystemTime.UtcNow);
			}
			else
			{
				var msg = "Could not find a counter named: " + tenantId;
				Logger.Warn(msg);
				throw new HttpException(503, msg);
			}
			return true;
		}
		protected override void InnerInitialization(HttpControllerContext controllerContext)
		{
			base.InnerInitialization(controllerContext);
			landlord = (CountersLandlord)controllerContext.Configuration.Properties[typeof(CountersLandlord)];
			requestManager = (RequestManager)controllerContext.Configuration.Properties[typeof(RequestManager)];

			var values = controllerContext.Request.GetRouteData().Values;
			if (values.ContainsKey("MS_SubRoutes"))
			{
				var routeDatas = (IHttpRouteData[])controllerContext.Request.GetRouteData().Values["MS_SubRoutes"];
				var selectedData = routeDatas.FirstOrDefault(data => data.Values.ContainsKey("counterName"));

				if (selectedData != null)
					CountersName = selectedData.Values["counterName"] as string;
			}
			else
			{
				if (values.ContainsKey("cou"))
					CountersName = values["counterName"] as string;
			}
			if (CountersName == null)
				throw new InvalidOperationException("Could not find counter name for this request");
		}
Example #6
0
        public static void CreateInfoPackageForDatabase(ZipArchive package, DocumentDatabase database, RequestManager requestManager, string zipEntryPrefix = null)
        {
            zipEntryPrefix = zipEntryPrefix ?? string.Empty;

            var databaseName = database.Name;
            if (string.IsNullOrWhiteSpace(databaseName))
                databaseName = Constants.SystemDatabase;

            var jsonSerializer = JsonExtensions.CreateDefaultJsonSerializer();
            jsonSerializer.Formatting=Formatting.Indented;

            if (database.StartupTasks.OfType<ReplicationTask>().Any())
            {
                var replication = package.CreateEntry(zipEntryPrefix + "replication.json", compressionLevel);

                using (var statsStream = replication.Open())
                using (var streamWriter = new StreamWriter(statsStream))
                {
                    jsonSerializer.Serialize(streamWriter, ReplicationUtils.GetReplicationInformation(database));
                    streamWriter.Flush();
                }
            }

            var sqlReplicationTask = database.StartupTasks.OfType<SqlReplicationTask>().FirstOrDefault();
            if (sqlReplicationTask != null)
            {
                var replication = package.CreateEntry(zipEntryPrefix + "sql_replication.json", compressionLevel);

                using (var statsStream = replication.Open())
                using (var streamWriter = new StreamWriter(statsStream))
                {
                    jsonSerializer.Serialize(streamWriter, sqlReplicationTask.Statistics);
                    streamWriter.Flush();
                }
            }

            var stats = package.CreateEntry(zipEntryPrefix + "stats.json", compressionLevel);

            using (var statsStream = stats.Open())
            using (var streamWriter = new StreamWriter(statsStream))
            {
                jsonSerializer.Serialize(streamWriter, database.Statistics);
                streamWriter.Flush();
            }

            var metrics = package.CreateEntry(zipEntryPrefix + "metrics.json", compressionLevel);

            using (var metricsStream = metrics.Open())
            using (var streamWriter = new StreamWriter(metricsStream))
            {
                jsonSerializer.Serialize(streamWriter, database.CreateMetrics());
                streamWriter.Flush();
            }

            var logs = package.CreateEntry(zipEntryPrefix + "logs.csv", compressionLevel);

            using (var logsStream = logs.Open())
            using (var streamWriter = new StreamWriter(logsStream))
            {
                var target = LogManager.GetTarget<DatabaseMemoryTarget>();

                if (target == null) streamWriter.WriteLine("DatabaseMemoryTarget was not registered in the log manager, logs are not available");
                else
                {
                    var boundedMemoryTarget = target[databaseName];
                    var log = boundedMemoryTarget.GeneralLog;

                    streamWriter.WriteLine("time,logger,level,message,exception");

                    foreach (var logEvent in log)
                    {
                        streamWriter.WriteLine("{0:O},{1},{2},{3},{4}", logEvent.TimeStamp, logEvent.LoggerName, logEvent.Level, logEvent.FormattedMessage, logEvent.Exception);
                    }
                }

                streamWriter.Flush();
            }

            var config = package.CreateEntry(zipEntryPrefix + "config.json", compressionLevel);

            using (var configStream = config.Open())
            using (var streamWriter = new StreamWriter(configStream))
            using (var jsonWriter = new JsonTextWriter(streamWriter) { Formatting = Formatting.Indented })
            {
                GetConfigForDebug(database).WriteTo(jsonWriter, new EtagJsonConverter());
                jsonWriter.Flush();
            }

            var indexes = package.CreateEntry(zipEntryPrefix + "indexes.json", compressionLevel);

            using (var indexesStream = indexes.Open())
            using (var streamWriter = new StreamWriter(indexesStream))
            {
                jsonSerializer.Serialize(streamWriter, database.IndexDefinitionStorage.IndexDefinitions.ToDictionary(x => x.Key, x => x.Value));
                streamWriter.Flush();
            }

            var currentlyIndexing = package.CreateEntry(zipEntryPrefix + "currently-indexing.json", compressionLevel);

            using (var currentlyIndexingStream = currentlyIndexing.Open())
            using (var streamWriter = new StreamWriter(currentlyIndexingStream))
            {
                jsonSerializer.Serialize(streamWriter, GetCurrentlyIndexingForDebug(database));
                streamWriter.Flush();
            }

            var queries = package.CreateEntry(zipEntryPrefix + "queries.json", compressionLevel);

            using (var queriesStream = queries.Open())
            using (var streamWriter = new StreamWriter(queriesStream))
            {
                jsonSerializer.Serialize(streamWriter, database.WorkContext.CurrentlyRunningQueries);
                streamWriter.Flush();
            }

            var version = package.CreateEntry(zipEntryPrefix + "version.json", compressionLevel);

            using (var versionStream = version.Open())
            using (var streamWriter = new StreamWriter(versionStream))
            {
                jsonSerializer.Serialize(streamWriter, new
                {
                    DocumentDatabase.ProductVersion,
                    DocumentDatabase.BuildVersion   
                });
                streamWriter.Flush();
            }

            var prefetchStatus = package.CreateEntry(zipEntryPrefix + "prefetch-status.json", compressionLevel);

            using (var prefetchStatusStream = prefetchStatus.Open())
            using (var streamWriter = new StreamWriter(prefetchStatusStream))
            {
                jsonSerializer.Serialize(streamWriter, GetPrefetchingQueueStatusForDebug(database));
                streamWriter.Flush();
            }

            var requestTracking = package.CreateEntry(zipEntryPrefix + "request-tracking.json", compressionLevel);

            using (var requestTrackingStream = requestTracking.Open())
            using (var streamWriter = new StreamWriter(requestTrackingStream))
            {
                jsonSerializer.Serialize(streamWriter, GetRequestTrackingForDebug(requestManager, databaseName));
                streamWriter.Flush();
            }

            var tasks = package.CreateEntry(zipEntryPrefix + "tasks.json", compressionLevel);

            using (var tasksStream = tasks.Open())
            using (var streamWriter = new StreamWriter(tasksStream))
            {
                jsonSerializer.Serialize(streamWriter, GetTasksForDebug(database));
                streamWriter.Flush();
            }

            var systemUtilization = package.CreateEntry(zipEntryPrefix + "system-utilization.json", compressionLevel);

            using (var systemUtilizationStream = systemUtilization.Open())
            using (var streamWriter = new StreamWriter(systemUtilizationStream))
            {
                long totalPhysicalMemory = -1;
                long availableMemory = -1;
                object cpuTimes = null;

                try
                {
                    totalPhysicalMemory = MemoryStatistics.TotalPhysicalMemory;
                    availableMemory = MemoryStatistics.AvailableMemoryInMb;

                    using (var searcher = new ManagementObjectSearcher("select * from Win32_PerfFormattedData_PerfOS_Processor"))
                    {
                        cpuTimes = searcher.Get()
                            .Cast<ManagementObject>()
                            .Select(mo => new
                            {
                                Name = mo["Name"],
                                Usage = string.Format("{0} %", mo["PercentProcessorTime"])
                            }).ToArray();	
                    }
                }
                catch (Exception e)
                {
                    cpuTimes = "Could not get CPU times" + Environment.NewLine + e;
                }

                jsonSerializer.Serialize(streamWriter, new
                {
                    TotalPhysicalMemory = string.Format("{0:#,#.##;;0} MB", totalPhysicalMemory),
                    AvailableMemory = string.Format("{0:#,#.##;;0} MB", availableMemory),
                    CurrentCpuUsage = cpuTimes
                });

                streamWriter.Flush();
            }
        }
Example #7
0
 internal static object GetRequestTrackingForDebug(RequestManager requestManager, string databaseName)
 {
     return requestManager.GetRecentRequests(databaseName).Select(x =>
     {
         var dic = new Dictionary<String, String>();
         foreach (var httpHeader in x.Headers.Value)
         {
             dic[httpHeader.Key] = httpHeader.Value.First();
         }
         dic.Remove("Authorization");
         dic.Remove("Proxy-Authorization");
         dic.Remove("WWW-Authenticate");
         dic.Remove("Proxy-Authenticate");
         
         return new
         {
             Uri = x.RequestUri,
             Method = x.HttpMethod,
             StatusCode = x.ResponseStatusCode,
             RequestHeaders = dic.Select(z=>new{Name = z.Key, Values= new[]{z.Value}}),
             ExecutionTime = string.Format("{0} ms", x.Stopwatch.ElapsedMilliseconds),
             AdditionalInfo = x.CustomInfo ?? string.Empty
         };
     });
 }
Example #8
0
        public override bool SetupRequestToProperDatabase(RequestManager rm)
        {
            var tenantId = DatabaseName;

            if (string.IsNullOrWhiteSpace(tenantId) || tenantId == "<system>")
            {
                landlord.LastRecentlyUsed.AddOrUpdate("System", SystemTime.UtcNow, (s, time) => SystemTime.UtcNow);
                var args = new BeforeRequestWebApiEventArgs
                {
                    Controller = this,
                    IgnoreRequest = false,
                    TenantId = "System",
                    Database = landlord.SystemDatabase
                };
                rm.OnBeforeRequest(args);
                if (args.IgnoreRequest)
                    return false;
                return true;
            }

            Task<DocumentDatabase> resourceStoreTask;
            bool hasDb;
            try
            {
                hasDb = landlord.TryGetOrCreateResourceStore(tenantId, out resourceStoreTask);
            }
            catch (Exception e)
            {
                var msg = "Could not open database named: " + tenantId;
                Logger.WarnException(msg, e);
                throw new HttpException(503, msg, e);
            }
            if (hasDb)
            {
                try
                {
                    if (resourceStoreTask.Wait(TimeSpan.FromSeconds(30)) == false)
                    {
                        var msg = "The database " + tenantId +
                                  " is currently being loaded, but after 30 seconds, this request has been aborted. Please try again later, database loading continues.";
                        Logger.Warn(msg);
                        throw new TimeoutException(msg);
                    }
                    var args = new BeforeRequestWebApiEventArgs()
                    {
                        Controller = this,
                        IgnoreRequest = false,
                        TenantId = tenantId,
                        Database = resourceStoreTask.Result
                    };
                    rm.OnBeforeRequest(args);
                    if (args.IgnoreRequest)
                        return false;
                }
                catch (Exception e)
                {
                    string exceptionMessage = e.Message;
                    var aggregateException = e as AggregateException;
                    if (aggregateException != null)
                    {
                        exceptionMessage = aggregateException.ExtractSingleInnerException().Message;
                    }
                    var msg = "Could not open database named: " + tenantId + Environment.NewLine + exceptionMessage;

                    Logger.WarnException(msg, e);
                    throw new HttpException(503, msg, e);
                }

                landlord.LastRecentlyUsed.AddOrUpdate(tenantId, SystemTime.UtcNow, (s, time) => SystemTime.UtcNow);
            }
            else
            {
                var msg = "Could not find a database named: " + tenantId;
                Logger.Warn(msg);
                throw new HttpException(503, msg);
            }
            return true;
        }
        public override bool SetupRequestToProperDatabase(RequestManager rm)
        {
            var tenantId = this.DatabaseName;
            var landlord = this.DatabasesLandlord;

            if (string.IsNullOrWhiteSpace(tenantId) || tenantId == "<system>")
            {                
                landlord.LastRecentlyUsed.AddOrUpdate("System", SystemTime.UtcNow, (s, time) => SystemTime.UtcNow);

                var args = new BeforeRequestWebApiEventArgs
                {
                    Controller = this,
                    IgnoreRequest = false,
                    TenantId = "System",
                    Database = landlord.SystemDatabase
                };

                rm.OnBeforeRequest(args);
                if (args.IgnoreRequest)
                    return false;
                return true;
            }

            Task<DocumentDatabase> resourceStoreTask;
            bool hasDb;
            try
            {
                hasDb = landlord.TryGetOrCreateResourceStore(tenantId, out resourceStoreTask);
            }
            catch (Exception e)
            {
                var msg = "Could not open database named: " + tenantId + " "  + e.Message;
                Logger.WarnException(msg, e);
                throw new HttpException(503, msg, e);
            }
            if (hasDb)
            {
                try
                {
					int TimeToWaitForDatabaseToLoad = MaxSecondsForTaskToWaitForDatabaseToLoad;
					if (resourceStoreTask.IsCompleted == false && resourceStoreTask.IsFaulted == false)
					{
						if (MaxNumberOfThreadsForDatabaseToLoad.Wait(0) == false)
						{
							var msg = string.Format("The database {0} is currently being loaded, but there are too many requests waiting for database load. Please try again later, database loading continues.", tenantId);
							Logger.Warn(msg);
							throw new TimeoutException(msg);
						}

						try
						{
							if (resourceStoreTask.Wait(TimeSpan.FromSeconds(TimeToWaitForDatabaseToLoad)) == false)
							{
								var msg = string.Format("The database {0} is currently being loaded, but after {1} seconds, this request has been aborted. Please try again later, database loading continues.", tenantId, TimeToWaitForDatabaseToLoad);
								Logger.Warn(msg);
								throw new TimeoutException(msg);
							}
						}
						finally
						{
							MaxNumberOfThreadsForDatabaseToLoad.Release();
						}
					}

                    var args = new BeforeRequestWebApiEventArgs()
                    {
                        Controller = this,
                        IgnoreRequest = false,
                        TenantId = tenantId,
                        Database = resourceStoreTask.Result
                    };

                    rm.OnBeforeRequest(args);
                    if (args.IgnoreRequest)
                        return false;
                }
                catch (Exception e)
                {
	                var msg = "Could not open database named: " + tenantId + Environment.NewLine + e;

                    Logger.WarnException(msg, e);
                    throw new HttpException(503, msg,e);
                }

                landlord.LastRecentlyUsed.AddOrUpdate(tenantId, SystemTime.UtcNow, (s, time) => SystemTime.UtcNow);
            }
            else
            {
                var msg = "Could not find a database named: " + tenantId;
                Logger.Warn(msg);
                throw new HttpException(503, msg);
            }
            return true;
        }
Example #10
0
		internal static object GetRequestTrackingForDebug(RequestManager requestManager, string databaseName)
		{
			return requestManager.GetRecentRequests(databaseName).Select(x => new
			{
				Uri = x.RequestUri,
				Method = x.HttpMethod,
				StatusCode = x.ResponseStatusCode,
				RequestHeaders = x.Headers.AllKeys.Select(k => new { Name = k, Values = x.Headers.GetValues(k) }),
				ExecutionTime = string.Format("{0} ms", x.Stopwatch.ElapsedMilliseconds),
				AdditionalInfo = x.CustomInfo ?? string.Empty
			});
		}