public HttpResponseMessage Get(string id) { if (IsSystemDatabase(id)) { //fetch fake (empty) system database document var systemDatabaseDocument = new DatabaseDocument { Id = Constants.SystemDatabase }; return(GetMessageWithObject(systemDatabaseDocument)); } var docKey = Constants.Database.Prefix + id; var document = Database.Documents.Get(docKey, null); if (document == null) { return(GetMessageWithString("Database " + id + " wasn't found", HttpStatusCode.NotFound)); } var dbDoc = document.DataAsJson.JsonDeserialization <DatabaseDocument>(); dbDoc.Id = id; DatabasesLandlord.Unprotect(dbDoc); string activeBundles; if (dbDoc.Settings.TryGetValue(Constants.ActiveBundles, out activeBundles)) { dbDoc.Settings[Constants.ActiveBundles] = BundlesHelper.ProcessActiveBundles(activeBundles); } return(GetMessageWithObject(dbDoc, HttpStatusCode.OK, document.Etag)); }
public HttpResponseMessage DatabaseToggleDisable(string id, bool isSettingDisabled) { if (IsSystemDatabase(id)) { return(GetMessageWithString("System Database document cannot be disabled", HttpStatusCode.Forbidden)); } var docKey = "Raven/Databases/" + id; var document = Database.Documents.Get(docKey, null); if (document == null) { return(GetMessageWithString("Database " + id + " wasn't found", HttpStatusCode.NotFound)); } var dbDoc = document.DataAsJson.JsonDeserialization <DatabaseDocument>(); if (dbDoc.Disabled == isSettingDisabled) { string state = isSettingDisabled ? "disabled" : "enabled"; return(GetMessageWithString("Database " + id + " is already " + state, HttpStatusCode.BadRequest)); } DatabasesLandlord.Unprotect(dbDoc); dbDoc.Disabled = !dbDoc.Disabled; var json = RavenJObject.FromObject(dbDoc); json.Remove("Id"); Database.Documents.Put(docKey, document.Etag, json, new RavenJObject(), null); return(GetEmptyMessage()); }
private MessageWithStatusCode ToggeleDatabase(string databaseId, bool isSettingDisabled) { if (IsSystemDatabase(databaseId)) { return new MessageWithStatusCode { ErrorCode = HttpStatusCode.Forbidden, Message = "System Database document cannot be disabled" } } ; var docKey = "Raven/Databases/" + databaseId; var document = Database.Documents.Get(docKey, null); if (document == null) { return new MessageWithStatusCode { ErrorCode = HttpStatusCode.NotFound, Message = "Database " + databaseId + " wasn't found" } } ; var dbDoc = document.DataAsJson.JsonDeserialization <DatabaseDocument>(); if (dbDoc.Disabled == isSettingDisabled) { string state = isSettingDisabled ? "disabled" : "enabled"; return(new MessageWithStatusCode { ErrorCode = HttpStatusCode.BadRequest, Message = "Database " + databaseId + " is already " + state }); } DatabasesLandlord.Unprotect(dbDoc); dbDoc.Disabled = !dbDoc.Disabled; var json = RavenJObject.FromObject(dbDoc); json.Remove("Id"); Database.Documents.Put(docKey, document.Etag, json, new RavenJObject(), null); return(new MessageWithStatusCode()); }
public async Task <HttpResponseMessage> Backup() { var backupRequest = await ReadJsonObjectAsync <DatabaseBackupRequest>(); var incrementalString = InnerRequest.RequestUri.ParseQueryString()["incremental"]; bool incrementalBackup; if (bool.TryParse(incrementalString, out incrementalBackup) == false) { incrementalBackup = false; } if (backupRequest.DatabaseDocument == null) { if (Database.Name == null || Database.Name.Equals(Constants.SystemDatabase, StringComparison.OrdinalIgnoreCase)) { backupRequest.DatabaseDocument = new DatabaseDocument { Id = Constants.SystemDatabase }; } else { var jsonDocument = DatabasesLandlord.SystemDatabase.Documents.Get("Raven/Databases/" + Database.Name, null); if (jsonDocument != null) { backupRequest.DatabaseDocument = jsonDocument.DataAsJson.JsonDeserialization <DatabaseDocument>(); DatabasesLandlord.Unprotect(backupRequest.DatabaseDocument); backupRequest.DatabaseDocument.Id = Database.Name; } } } Database.Maintenance.StartBackup(backupRequest.BackupLocation, incrementalBackup, backupRequest.DatabaseDocument); return(GetEmptyMessage(HttpStatusCode.Created)); }
public async Task <HttpResponseMessage> PeriodicExportSettingsPut() { if (Database == null) { return(GetEmptyMessage(HttpStatusCode.NotFound)); } if (Database.Configuration.Studio.AllowNonAdminUsersToSetupPeriodicExport == false) { return(GetMessageWithString("You can set periodic export settings using this endpoint only if AllowNonAdminUsersToSetupPeriodicExport config is enabled", HttpStatusCode.Unauthorized)); } var docKey = Constants.Database.Prefix + DatabaseName; var databaseDocument = SystemDatabase.Documents.Get(docKey, null); var dbDoc = databaseDocument.DataAsJson.JsonDeserialization <DatabaseDocument>(); DatabasesLandlord.Unprotect(dbDoc); dbDoc.SecuredSettings.Remove(Constants.PeriodicExport.AwsSecretKey); dbDoc.SecuredSettings.Remove(Constants.PeriodicExport.AzureStorageKey); dbDoc.Settings.Remove(Constants.PeriodicExport.AwsAccessKey); dbDoc.Settings.Remove(Constants.PeriodicExport.AzureStorageAccount); var newConfiguration = await ReadJsonAsync().ConfigureAwait(false); var awsAccessKey = newConfiguration.Value <string>(Constants.PeriodicExport.AwsAccessKey); var awsSecretKey = newConfiguration.Value <string>(Constants.PeriodicExport.AwsSecretKey); var azureStorageAccount = newConfiguration.Value <string>(Constants.PeriodicExport.AzureStorageAccount); var azureStorageKey = newConfiguration.Value <string>(Constants.PeriodicExport.AzureStorageKey); if (awsAccessKey != null) { dbDoc.Settings[Constants.PeriodicExport.AwsAccessKey] = awsAccessKey; } if (awsSecretKey != null) { dbDoc.SecuredSettings[Constants.PeriodicExport.AwsSecretKey] = awsSecretKey; } if (azureStorageAccount != null) { dbDoc.Settings[Constants.PeriodicExport.AzureStorageAccount] = azureStorageAccount; } if (azureStorageKey != null) { dbDoc.Settings[Constants.PeriodicExport.AzureStorageKey] = azureStorageKey; } DatabasesLandlord.Protect(dbDoc); var json = RavenJObject.FromObject(dbDoc); json.Remove("Id"); SystemDatabase.Documents.Put(docKey, databaseDocument.Etag, json, new RavenJObject(), null); return(GetEmptyMessage()); }
public async Task <HttpResponseMessage> Put(string id) { if (IsSystemDatabase(id)) { return(GetMessageWithString("System database document cannot be changed!", HttpStatusCode.Forbidden)); } MessageWithStatusCode nameFormatErrorMessage; if (IsValidName(id, Database.Configuration.DataDirectory, out nameFormatErrorMessage) == false) { return(GetMessageWithString(nameFormatErrorMessage.Message, nameFormatErrorMessage.ErrorCode)); } Etag etag = GetEtag(); string error = CheckExistingDatabaseName(id, etag); if (error != null) { return(GetMessageWithString(error, HttpStatusCode.BadRequest)); } var dbDoc = await ReadJsonObjectAsync <DatabaseDocument>().ConfigureAwait(false); //Preventing the modification of the database document when it is not actually changed //And it happens, see http://issues.hibernatingrhinos.com/issue/RavenDB-7820 var docKey = Constants.Database.Prefix + id; var databaseDocument = SystemDatabase.Documents.Get(docKey, null); var existingDbDoc = databaseDocument?.DataAsJson.JsonDeserialization <DatabaseDocument>(); if (existingDbDoc != null) { DatabasesLandlord.Unprotect(existingDbDoc); if (DatabaseDocument.CompareDatabaseDocumentWithoutId(existingDbDoc, dbDoc)) { return(GetEmptyMessage(HttpStatusCode.NotModified)); } } string bundles; if (dbDoc.Settings.TryGetValue(Constants.ActiveBundles, out bundles) && bundles.Contains("Encryption")) { if (dbDoc.SecuredSettings == null || !dbDoc.SecuredSettings.ContainsKey(Constants.EncryptionKeySetting) || !dbDoc.SecuredSettings.ContainsKey(Constants.AlgorithmTypeSetting)) { return(GetMessageWithString(string.Format("Failed to create '{0}' database, because of invalid encryption configuration.", id), HttpStatusCode.BadRequest)); } } //TODO: check if paths in document are legal if (dbDoc.IsClusterDatabase() && ClusterManager.IsActive()) { string dataDir; if (dbDoc.Settings.TryGetValue("Raven/DataDir", out dataDir) == false || string.IsNullOrEmpty(dataDir)) { return(GetMessageWithString(string.Format("Failed to create '{0}' database, because 'Raven/DataDir' setting is missing.", id), HttpStatusCode.BadRequest)); } dataDir = dataDir.ToFullPath(SystemConfiguration.DataDirectory); // if etag is not null, it means we want to update existing database if (Directory.Exists(dataDir) && etag == null) { return(GetMessageWithString(string.Format("Failed to create '{0}' database, because data directory '{1}' exists and it is forbidden to create non-empty cluster-wide databases.", id, dataDir), HttpStatusCode.BadRequest)); } var changesAppliedMre = new ManualResetEventSlim(false); Etag newEtag = null; var documentKey = Constants.Database.Prefix + id; Action <DocumentDatabase, DocumentChangeNotification, RavenJObject> onDocumentAction = (database, notification, jObject) => { if (notification.Type == DocumentChangeTypes.Put && notification.Id == documentKey) { newEtag = notification.Etag; changesAppliedMre.Set(); } }; Database.Notifications.OnDocumentChange += onDocumentAction; try { await ClusterManager.Client.SendDatabaseUpdateAsync(id, dbDoc).ConfigureAwait(false); changesAppliedMre.Wait(TimeSpan.FromSeconds(15)); } finally { Database.Notifications.OnDocumentChange -= onDocumentAction; } var clusterPutResult = new PutResult { ETag = newEtag, Key = documentKey }; return((etag == null) ? GetEmptyMessage() : GetMessageWithObject(clusterPutResult)); } DatabasesLandlord.Protect(dbDoc); var json = RavenJObject.FromObject(dbDoc); json.Remove("Id"); var metadata = (etag != null) ? ReadInnerHeaders.FilterHeadersToObject() : new RavenJObject(); var putResult = Database.Documents.Put(docKey, etag, json, metadata, null); return((etag == null) ? GetEmptyMessage() : GetMessageWithObject(putResult)); }