azurite
Version:
An open source Azure Storage API compatible server
154 lines • 7.23 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const http = tslib_1.__importStar(require("http"));
const https = tslib_1.__importStar(require("https"));
const AccountDataStore_1 = tslib_1.__importDefault(require("../common/AccountDataStore"));
const ConfigurationBase_1 = require("../common/ConfigurationBase");
const Logger_1 = tslib_1.__importDefault(require("../common/Logger"));
const FSExtentStore_1 = tslib_1.__importDefault(require("../common/persistence/FSExtentStore"));
const SqlExtentMetadataStore_1 = tslib_1.__importDefault(require("../common/persistence/SqlExtentMetadataStore"));
const ServerBase_1 = tslib_1.__importStar(require("../common/ServerBase"));
const BlobRequestListenerFactory_1 = tslib_1.__importDefault(require("./BlobRequestListenerFactory"));
const BlobGCManager_1 = tslib_1.__importDefault(require("./gc/BlobGCManager"));
const SqlBlobMetadataStore_1 = tslib_1.__importDefault(require("./persistence/SqlBlobMetadataStore"));
const BEFORE_CLOSE_MESSAGE = `Azurite Blob service is closing...`;
const BEFORE_CLOSE_MESSAGE_GC_ERROR = `Azurite Blob service is closing... Critical error happens during GC.`;
const AFTER_CLOSE_MESSAGE = `Azurite Blob service successfully closed`;
/**
* Default implementation of Azurite Blob HTTP server.
* This implementation provides a HTTP service based on express framework and LokiJS in memory database.
*
* We can create other blob servers by extending abstract Server class and initialize different httpServer,
* dataStore or requestListenerFactory fields.
*
* For example, creating a HTTPS server to accept HTTPS requests, or using other
* Node.js HTTP frameworks like Koa, or just using another SQL database.
*
* @export
* @class Server
*/
class SqlBlobServer extends ServerBase_1.default {
/**
* Creates an instance of Server.
*
* @param {BlobConfiguration} configuration
* @memberof Server
*/
constructor(configuration) {
const host = configuration.host;
const port = configuration.port;
// We can crate a HTTP server or a HTTPS server here
let httpServer;
const certOption = configuration.hasCert();
switch (certOption) {
case ConfigurationBase_1.CertOptions.PEM:
case ConfigurationBase_1.CertOptions.PFX:
httpServer = https.createServer(configuration.getCert(certOption));
break;
default:
httpServer = http.createServer();
}
const metadataStore = new SqlBlobMetadataStore_1.default(configuration.sqlURL, configuration.sequelizeOptions);
const extentMetadataStore = new SqlExtentMetadataStore_1.default(
// Currently, extent metadata and blob metadata share same database
// But they can use separate databases per future requirements
configuration.sqlURL, configuration.sequelizeOptions);
const extentStore = new FSExtentStore_1.default(extentMetadataStore, configuration.persistenceArray, Logger_1.default);
const accountDataStore = new AccountDataStore_1.default(Logger_1.default);
// We can also change the HTTP framework here by
// creating a new XXXListenerFactory implementing IRequestListenerFactory interface
// and replace the default Express based request listener
const requestListenerFactory = new BlobRequestListenerFactory_1.default(metadataStore, extentStore, accountDataStore, configuration.enableAccessLog, // Access log includes every handled HTTP request
configuration.accessLogWriteStream, configuration.loose, configuration.skipApiVersionCheck, configuration.getOAuthLevel(), configuration.disableProductStyleUrl);
super(host, port, httpServer, requestListenerFactory, configuration);
// Default Blob GC Manager
// Will close service when any critical GC error happens
const gcManager = new BlobGCManager_1.default(metadataStore, extentMetadataStore, extentStore, error => {
// tslint:disable-next-line:no-console
console.log(BEFORE_CLOSE_MESSAGE_GC_ERROR, error);
Logger_1.default.info(BEFORE_CLOSE_MESSAGE_GC_ERROR + JSON.stringify(error));
// TODO: Bring this back when GC based on SQL implemented
this.close().then(() => {
// tslint:disable-next-line:no-console
console.log(AFTER_CLOSE_MESSAGE);
Logger_1.default.info(AFTER_CLOSE_MESSAGE);
});
}, Logger_1.default);
this.metadataStore = metadataStore;
this.extentMetadataStore = extentMetadataStore;
this.extentStore = extentStore;
this.accountDataStore = accountDataStore;
this.gcManager = gcManager;
}
/**
* Clean up server persisted extent data.
*
* @returns {Promise<void>}
* @memberof BlobServer
*/
async clean() {
if (this.getStatus() === ServerBase_1.ServerStatus.Closed) {
if (this.extentStore !== undefined) {
await this.extentStore.clean();
}
if (this.extentMetadataStore !== undefined) {
await this.extentMetadataStore.clean();
}
if (this.metadataStore !== undefined) {
await this.metadataStore.clean();
}
if (this.accountDataStore !== undefined) {
await this.accountDataStore.clean();
}
return;
}
throw Error(`Cannot clean up blob server in status ${this.getStatus()}.`);
}
async beforeStart() {
const msg = `Azurite Blob service is starting on ${this.host}:${this.port}`;
Logger_1.default.info(msg);
if (this.accountDataStore !== undefined) {
await this.accountDataStore.init();
}
if (this.metadataStore !== undefined) {
await this.metadataStore.init();
}
if (this.extentMetadataStore !== undefined) {
await this.extentMetadataStore.init();
}
if (this.extentStore !== undefined) {
await this.extentStore.init();
}
if (this.gcManager !== undefined) {
await this.gcManager.start();
}
}
async afterStart() {
const msg = `Azurite Blob service successfully listens on ${this.getHttpServerAddress()}`;
Logger_1.default.info(msg);
}
async beforeClose() {
Logger_1.default.info(BEFORE_CLOSE_MESSAGE);
}
async afterClose() {
if (this.gcManager !== undefined) {
await this.gcManager.close();
}
if (this.extentStore !== undefined) {
await this.extentStore.close();
}
if (this.extentMetadataStore !== undefined) {
await this.extentMetadataStore.close();
}
if (this.metadataStore !== undefined) {
await this.metadataStore.close();
}
if (this.accountDataStore !== undefined) {
await this.accountDataStore.close();
}
Logger_1.default.info(AFTER_CLOSE_MESSAGE);
}
}
exports.default = SqlBlobServer;
//# sourceMappingURL=SqlBlobServer.js.map