2015-05-13 23:42:35 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* 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-03-19 23:48:04 +00:00
|
|
|
|
2015-08-07 19:13:15 +00:00
|
|
|
/**
|
|
|
|
* This bundle implements a persistence service which uses ElasticSearch to
|
|
|
|
* store documents.
|
|
|
|
* @namespace platform/persistence/elastic
|
|
|
|
*/
|
2015-03-19 23:48:04 +00:00
|
|
|
define(
|
2015-03-20 00:04:16 +00:00
|
|
|
[],
|
|
|
|
function () {
|
2015-03-19 23:48:04 +00:00
|
|
|
|
2015-03-20 00:04:16 +00:00
|
|
|
// JSLint doesn't like underscore-prefixed properties,
|
|
|
|
// so hide them here.
|
|
|
|
var SRC = "_source",
|
|
|
|
REV = "_version",
|
2015-03-20 20:40:53 +00:00
|
|
|
ID = "_id",
|
|
|
|
CONFLICT = 409;
|
2015-03-19 23:48:04 +00:00
|
|
|
|
|
|
|
/**
|
2015-03-20 00:04:16 +00:00
|
|
|
* The ElasticPersistenceProvider reads and writes JSON documents
|
|
|
|
* (more specifically, domain object models) to/from an ElasticSearch
|
2015-03-19 23:48:04 +00:00
|
|
|
* instance.
|
2015-08-07 18:44:54 +00:00
|
|
|
* @memberof platform/persistence/elastic
|
2015-03-19 23:48:04 +00:00
|
|
|
* @constructor
|
2015-08-14 22:20:46 +00:00
|
|
|
* @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
|
2015-03-19 23:48:04 +00:00
|
|
|
*/
|
2015-08-14 22:20:46 +00:00
|
|
|
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) {
|
2015-08-18 00:00:21 +00:00
|
|
|
return this.$http({
|
2015-08-14 22:20:46 +00:00
|
|
|
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);
|
2015-03-19 23:48:04 +00:00
|
|
|
});
|
|
|
|
}
|
2015-08-14 22:20:46 +00:00
|
|
|
// Reject the promise
|
|
|
|
return this.$q.reject(error);
|
|
|
|
};
|
2015-03-19 23:48:04 +00:00
|
|
|
|
2015-08-24 16:04:03 +00:00
|
|
|
// Get a domain object model out of ElasticSearch's response
|
2016-03-04 19:18:25 +00:00
|
|
|
ElasticPersistenceProvider.prototype.getModel = function (response) {
|
2015-08-14 22:20:46 +00:00
|
|
|
if (response && response[SRC]) {
|
|
|
|
this.revs[response[ID]] = response[REV];
|
|
|
|
return response[SRC];
|
|
|
|
} else {
|
|
|
|
return undefined;
|
2015-03-19 23:48:04 +00:00
|
|
|
}
|
2016-03-04 19:18:25 +00:00
|
|
|
};
|
2015-03-19 23:48:04 +00:00
|
|
|
|
2015-08-14 22:20:46 +00:00
|
|
|
// 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);
|
2015-03-19 23:48:04 +00:00
|
|
|
}
|
2015-08-14 22:20:46 +00:00
|
|
|
};
|
2015-03-19 23:48:04 +00:00
|
|
|
|
2015-08-14 22:20:46 +00:00
|
|
|
// Public API
|
|
|
|
ElasticPersistenceProvider.prototype.listSpaces = function () {
|
|
|
|
return this.$q.when(this.spaces);
|
|
|
|
};
|
2015-03-20 20:40:53 +00:00
|
|
|
|
2015-08-14 22:20:46 +00:00
|
|
|
ElasticPersistenceProvider.prototype.listObjects = function () {
|
|
|
|
// Not yet implemented
|
|
|
|
return this.$q.when([]);
|
|
|
|
};
|
2015-03-19 23:48:04 +00:00
|
|
|
|
|
|
|
|
2015-08-14 22:20:46 +00:00
|
|
|
ElasticPersistenceProvider.prototype.createObject = function (space, key, value) {
|
2016-04-08 23:25:32 +00:00
|
|
|
return this.put(key, value).then(this.checkResponse.bind(this));
|
2015-08-14 22:20:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
ElasticPersistenceProvider.prototype.readObject = function (space, key) {
|
2016-04-08 23:25:32 +00:00
|
|
|
return this.get(key).then(this.getModel.bind(this));
|
2015-08-14 22:20:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
ElasticPersistenceProvider.prototype.updateObject = function (space, key, value) {
|
2016-03-04 19:18:25 +00:00
|
|
|
var self = this;
|
2015-08-14 22:20:46 +00:00
|
|
|
function checkUpdate(response) {
|
2016-03-04 19:18:25 +00:00
|
|
|
return self.checkResponse(response, key);
|
2015-08-14 22:20:46 +00:00
|
|
|
}
|
|
|
|
return this.put(key, value, { version: this.revs[key] })
|
2016-03-04 19:18:25 +00:00
|
|
|
.then(checkUpdate);
|
2015-08-14 22:20:46 +00:00
|
|
|
};
|
|
|
|
|
2016-03-04 19:41:48 +00:00
|
|
|
ElasticPersistenceProvider.prototype.deleteObject = function (space, key) {
|
2016-04-08 23:25:32 +00:00
|
|
|
return this.del(key).then(this.checkResponse.bind(this));
|
2015-08-14 22:20:46 +00:00
|
|
|
};
|
2015-03-19 23:48:04 +00:00
|
|
|
|
|
|
|
return ElasticPersistenceProvider;
|
|
|
|
}
|
2015-08-07 18:44:54 +00:00
|
|
|
);
|