Пример #1
0
        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));
        }
Пример #2
0
        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());
        }
Пример #3
0
        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());
        }
Пример #4
0
        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));
        }
Пример #5
0
        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());
        }
Пример #6
0
        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));
        }