Skip to content
This repository has been archived by the owner on Mar 22, 2018. It is now read-only.

Commit

Permalink
intermediate #141 #129
Browse files Browse the repository at this point in the history
  • Loading branch information
arafato committed Feb 21, 2018
1 parent 34b77b1 commit fe5f77e
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 59 deletions.
2 changes: 1 addition & 1 deletion lib/AzuriteBlob.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class AzuriteBlob {
init(options) {
return env.init(options)
.then(() => {
return storageManager.init(env.localStoragePath)
return storageManager.init()
})
.then(() => {
const app = express();
Expand Down
4 changes: 4 additions & 0 deletions lib/AzuriteTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const express = require('express'),
env = require('./core/env'),
bodyParser = require('body-parser'),
morgan = require('morgan'),
tableStorageManager = require('./core/table/TableStorageManager'),
cli = require('./core/cli');

class AzuriteTable {
Expand All @@ -27,6 +28,9 @@ class AzuriteTable {

init(options) {
return env.init(options)
.then(() => {
return tableStorageManager.init()
})
.then(() => {
const app = express();
if (!env.silent) {
Expand Down
20 changes: 11 additions & 9 deletions lib/actions/table/CreateTable.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
'use strict';

const AzuriteTableResponse = require('./../../model/table/AzuriteTableResponse'),
tableStorageManager = require('./../../core/table/TableStorageManager'),
N = require('./../../core/HttpHeaderNames');

class CreateTable {
constructor() {
}

process(request, res) {
const response = new AzuriteTableResponse();
if (request.httpProps[N.PREFER] === 'return-no-content') {
response.addHttpProperty(N.PREFERENCE_APPLIED, 'return-no-content');
res.status(204).send();
return;
}

response.addHttpProperty(N.PREFERENCE_APPLIED, 'return-content');
res.status(201).send();
tableStorageManager.createTable(request)
.then((response) => {
if (request.httpProps[N.PREFER] === 'return-no-content') {
response.addHttpProperty(N.PREFERENCE_APPLIED, 'return-no-content');
res.status(204).send();
return;
}
response.addHttpProperty(N.PREFERENCE_APPLIED, 'return-content');
res.status(201).send(response.payload ? response.payload : '');
});
}
}

Expand Down
14 changes: 13 additions & 1 deletion lib/core/Constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ const StorageTables = {
Pages: 'Pages'
}

const TableStorageTables = {
Tables: 'Tables'
}

const StorageEntityType = {
Container: 'Container',
BlockBlob: 'BlockBlob',
Expand Down Expand Up @@ -134,6 +138,12 @@ const Keys = {
DecodedAccessKey: Buffer.from(_key, 'base64')
}

const ODataMode = {
NONE: 'nometadata',
MINIMAL: 'minimalmetadata',
FULL: 'fullmetadata'
}

module.exports = {
StorageTables: StorageTables,
StorageEntityType: StorageEntityType,
Expand All @@ -144,5 +154,7 @@ module.exports = {
CopyStatus: CopyStatus,
BlockListType: BlockListType,
ServiceSAS: ServiceSAS,
Keys: Keys
Keys: Keys,
ODataMode: ODataMode,
TableStorageTables: TableStorageTables
}
2 changes: 1 addition & 1 deletion lib/core/blob/StorageManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class StorageManager {
constructor() {
}

init(localStoragePath) {
init() {
this.db = BbPromise.promisifyAll(new Loki(env.azuriteDBPathBlob, { autosave: true, autosaveInterval: 5000 }));
return fsn.statAsync(env.azuriteDBPathBlob)
.then((stat) => {
Expand Down
44 changes: 44 additions & 0 deletions lib/core/table/TableStorageManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict';

const Loki = require('lokijs'),
BbPromise = require('bluebird'),
AzuriteTableResponse = require('./../../model/table/AzuriteTableResponse'),
Tables = require('./../Constants').TableStorageTables,
env = require('./../../core/env');



class TableStorageManager {
constructor() {
}

init() {
this.db = BbPromise.promisifyAll(new Loki(env.azuriteDBPathTable, { autosave: true, autosaveInterval: 5000 }));
return fsn.statAsync(env.azuriteDBPathTable)
.then((stat) => {
return this.db.loadDatabaseAsync({});
})
.then((data) => {
if (!this.db.getCollection(Tables.Tables)) {
this.db.addCollection(Tables.Tables);
}
return this.db.saveDatabaseAsync();
})
.catch((e) => {
if (e.code === 'ENOENT') {
// No DB has been persisted / initialized yet.
this.db.addCollection(Tables.Tables);
return this.db.saveDatabaseAsync();
}
// This should never happen!
console.error(`Failed to initialize database at "${env.azuriteDBPathTable}"`);
throw e;
});
}

createTable(request) {
return BbPromise.resolve(new AzuriteTableResponse());
}
}

module.exports = new TableStorageManager();
5 changes: 3 additions & 2 deletions lib/middleware/table/actions.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict';

const BbPromise = require('bluebird'),
Operations = require('./../../core/Constants').Operations.Table;
Operations = require('./../../core/Constants').Operations.Table,
createTable = require('./../../actions/table/CreateTable');

module.exports = (req, res) => {
BbPromise.try(() => {
Expand All @@ -19,5 +20,5 @@ actions[undefined] = (request, res) => {
}

actions[Operations.CREATE_TABLE] = (request, res) => {

createTable.process(request, res);
}
18 changes: 11 additions & 7 deletions lib/model/table/AzuriteTableRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const InternalAzuriteError = require('./../../core/InternalAzuriteError'),
RequestPayloadParser = require('./RequestPayloadParser'),
Constants = require('./../../core/Constants'),
N = require('./../../core/HttpHeaderNames');

class AzuriteTableRequest {
Expand All @@ -14,17 +15,20 @@ class AzuriteTableRequest {
}
this.httpProps = {};
this._initHttpProps(req.headers);
this.payload = RequestPayloadParser.parse(this.httpProps[N.ACCEPT]);





this.accept = this._parseAccept(this.httpProps[N.ACCEPT]);
this.payload = RequestPayloadParser.parse(this.httpProps[N.CONTENT_TYPE], req.body);
}

_initHttpProps(httpHeaders) {
this.httpProps[N.ACCEPT] = httpHeaders[N.ACCEPT] || `application/json;odata=nometadata`;
this.httpProps[N.PREFER] = httpHeaders[N.ACCEPT] || undefined;
this.httpProps[N.PREFER] = httpHeaders[N.PREFER] || `return-content`;
}

_parseAccept(value) {
if (value === undefined) return undefined;
if (value.includes(`odata=nometadata`)) return Constants.ODataMode.NONE;
if (value.includes(`odata=minimalmetadata`)) return Constants.ODataMode.MINIMAL;
if (value.includes(`odata=fullmetadata`)) return Constants.ODataMode.FULL;
}
}

Expand Down
3 changes: 2 additions & 1 deletion lib/model/table/AzuriteTableResponse.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict';

const uuidV1 = require('uuid/v1'),
N = require('./../../core/HttpHeaderNames');
N = require('./../../core/HttpHeaderNames'),
ResponsePayloadGenerator = require('./../../model/table/ResponsePayloadGenerator');

class AzuriteTableResponse {
constructor() {
Expand Down
25 changes: 12 additions & 13 deletions lib/model/table/RequestPayloadParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,19 @@ class RequestPayLoadParser {
constructor() {
}

parse(contentType) {
if (contentType === `application/atom+xml`) {
throw new IAError(`accept value of 'atom+xml' is currently not supported by Azurite`);
parse(contentType, body) {
switch (contentType) {
case 'application/atom+xml':
throw new IAError(`accept value of 'atom+xml' is currently not supported by Azurite`);
break;
case 'application/json':
const txt = body.toString('utf8');
return JSON.parse(txt);
break;
default:
// This should never happen! (should be catched by validation pipeline)
throw new IAError(`content-type value ${contentType} is not supported by Azurite.`)
}

// content-type must be application/json;odata={nometadata|minimalmetadata|fullnetadata} since different values
// are detected by validation pipeline

if (contentType.contains(`application/json`)) {
return 'json';
}

// This should never happen! (should be catched by validation pipeline)
throw new IAError(`content-type value ${contentType} is not supported by Azurite.`)
}
}

Expand Down
24 changes: 0 additions & 24 deletions lib/model/table/ResponsePayloadGenerator.js

This file was deleted.

20 changes: 20 additions & 0 deletions lib/model/table/TableProxy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';

class TableProxy {
constructor(entity) {
this._ = entity;
}

/**
* Returns the odata representation of the table entity.
*
* @param {any} odata is (nometadata|minimalmetadata|fullmetadata)
* @returns
* @memberof TableProxy
*/
odata(mode) {
return this._;
}
}

module.exports = TableProxy;

0 comments on commit fe5f77e

Please sign in to comment.