openmct/platform/persistence/elastic/src/ElasticPersistenceProvider.js

161 lines
6.2 KiB
JavaScript
Raw Normal View History

/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
2015-08-07 19:13:15 +00:00
/**
* This bundle implements a persistence service which uses ElasticSearch to
* store documents.
* @namespace platform/persistence/elastic
*/
define(
[],
function () {
// JSLint doesn't like underscore-prefixed properties,
// so hide them here.
var SRC = "_source",
REV = "_version",
ID = "_id",
CONFLICT = 409;
/**
* The ElasticPersistenceProvider reads and writes JSON documents
* (more specifically, domain object models) to/from an ElasticSearch
* instance.
* @memberof platform/persistence/elastic
* @constructor
* @implements {PersistenceService}
* @param $http Angular's $http service
* @param $interval Angular's $interval service
* @param {string} space the name of the persistence space being served
* @param {string} root the root of the path to ElasticSearch
* @param {stirng} path the path to domain objects within ElasticSearch
*/
function ElasticPersistenceProvider($http, $q, space, root, path) {
this.spaces = [ space ];
this.revs = {};
this.$http = $http;
this.$q = $q;
this.root = root;
this.path = path;
}
// Issue a request using $http; get back the plain JS object
// from the expected JSON response
ElasticPersistenceProvider.prototype.request = function (subpath, method, value, params) {
return this.$http({
method: method,
url: this.root + '/' + this.path + '/' + subpath,
params: params,
data: value
}).then(function (response) {
return response.data;
}, function (response) {
return (response || {}).data;
});
};
// Shorthand methods for GET/PUT methods
ElasticPersistenceProvider.prototype.get = function (subpath) {
return this.request(subpath, "GET");
};
ElasticPersistenceProvider.prototype.put = function (subpath, value, params) {
return this.request(subpath, "PUT", value, params);
};
ElasticPersistenceProvider.prototype.del = function (subpath) {
return this.request(subpath, "DELETE");
};
// Handle an update error
ElasticPersistenceProvider.prototype.handleError = function (response, key) {
var error = new Error("Persistence error."),
$q = this.$q;
if ((response || {}).status === CONFLICT) {
error.key = "revision";
// Load the updated model, then reject the promise
return this.get(key).then(function (response) {
error.model = response[SRC];
return $q.reject(error);
});
}
// Reject the promise
return this.$q.reject(error);
};
2015-08-24 16:04:03 +00:00
// Get a domain object model out of ElasticSearch's response
ElasticPersistenceProvider.prototype.getModel = function (response) {
if (response && response[SRC]) {
this.revs[response[ID]] = response[REV];
return response[SRC];
} else {
return undefined;
}
};
// Check the response to a create/update/delete request;
// track the rev if it's valid, otherwise return false to
// indicate that the request failed.
ElasticPersistenceProvider.prototype.checkResponse = function (response, key) {
if (response && !response.error) {
this.revs[key] = response[REV];
return response;
} else {
return this.handleError(response, key);
}
};
// Public API
ElasticPersistenceProvider.prototype.listSpaces = function () {
return this.$q.when(this.spaces);
};
ElasticPersistenceProvider.prototype.listObjects = function () {
// Not yet implemented
return this.$q.when([]);
};
ElasticPersistenceProvider.prototype.createObject = function (space, key, value) {
return this.put(key, value).then(this.checkResponse.bind(this));
};
ElasticPersistenceProvider.prototype.readObject = function (space, key) {
return this.get(key).then(this.getModel.bind(this));
};
ElasticPersistenceProvider.prototype.updateObject = function (space, key, value) {
var self = this;
function checkUpdate(response) {
return self.checkResponse(response, key);
}
return this.put(key, value, { version: this.revs[key] })
.then(checkUpdate);
};
ElasticPersistenceProvider.prototype.deleteObject = function (space, key) {
return this.del(key).then(this.checkResponse.bind(this));
};
return ElasticPersistenceProvider;
}
);