Remove unused doc source code (#13756)

* Remove unused doc source code

Ever since the saved object api was introduced, we’ve been using that,
or querying es directly, for mget data.

* Remove commented out code
This commit is contained in:
Stacey Gammon 2017-09-18 11:24:06 -04:00 committed by GitHub
parent 2ab28f2abb
commit c9123a4426
14 changed files with 7 additions and 612 deletions

View file

@ -4,15 +4,13 @@ import sinon from 'sinon';
import { requestQueue } from '../_request_queue';
import { SearchStrategyProvider } from '../fetch/strategy/search';
import { DocDataStrategyProvider } from '../fetch/strategy/doc_data';
describe('Courier Request Queue', function () {
let docStrategy;
let searchStrategy;
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
docStrategy = Private(DocDataStrategyProvider);
searchStrategy = Private(SearchStrategyProvider);
}));
beforeEach(requestQueue.clear);
@ -29,29 +27,26 @@ describe('Courier Request Queue', function () {
describe('#getStartable(strategy)', function () {
it('only returns requests that match one of the passed strategies', function () {
requestQueue.push(
new MockReq(docStrategy),
new MockReq(searchStrategy),
new MockReq(searchStrategy),
new MockReq(searchStrategy)
);
expect(requestQueue.getStartable(docStrategy)).to.have.length(1);
expect(requestQueue.getStartable(searchStrategy)).to.have.length(3);
});
it('returns all requests when no strategy passed', function () {
requestQueue.push(
new MockReq(docStrategy),
new MockReq(searchStrategy)
);
expect(requestQueue.getStartable()).to.have.length(2);
expect(requestQueue.getStartable()).to.have.length(1);
});
it('returns only startable requests', function () {
requestQueue.push(
new MockReq(docStrategy, true),
new MockReq(searchStrategy, false)
new MockReq(searchStrategy, false),
new MockReq(searchStrategy, true)
);
expect(requestQueue.getStartable()).to.have.length(1);
@ -61,28 +56,25 @@ describe('Courier Request Queue', function () {
describe('#get(strategy)', function () {
it('only returns requests that match one of the passed strategies', function () {
requestQueue.push(
new MockReq(docStrategy),
new MockReq(searchStrategy),
new MockReq(searchStrategy),
new MockReq(searchStrategy)
);
expect(requestQueue.get(docStrategy)).to.have.length(1);
expect(requestQueue.get(searchStrategy)).to.have.length(3);
});
it('returns all requests when no strategy passed', function () {
requestQueue.push(
new MockReq(docStrategy),
new MockReq(searchStrategy)
);
expect(requestQueue.get()).to.have.length(2);
expect(requestQueue.get()).to.have.length(1);
});
it('returns startable and not-startable requests', function () {
requestQueue.push(
new MockReq(docStrategy, true),
new MockReq(searchStrategy, true),
new MockReq(searchStrategy, false)
);

View file

@ -6,12 +6,10 @@ import 'ui/index_patterns';
import { uiModules } from 'ui/modules';
import { Notifier } from 'ui/notify/notifier';
import { DocSourceProvider } from './data_source/doc_source';
import { SearchSourceProvider } from './data_source/search_source';
import { SearchStrategyProvider } from './fetch/strategy/search';
import { requestQueue } from './_request_queue';
import { FetchProvider } from './fetch';
import { DocDataLooperProvider } from './looper/doc_data';
import { SearchLooperProvider } from './looper/search';
import { RootSearchSourceProvider } from './data_source/_root_search_source';
import { SavedObjectProvider } from './saved_object';
@ -22,13 +20,10 @@ uiModules.get('kibana/courier')
.service('courier', function ($rootScope, Private, Promise, indexPatterns) {
function Courier() {
const self = this;
const DocSource = Private(DocSourceProvider);
const SearchSource = Private(SearchSourceProvider);
const searchStrategy = Private(SearchStrategyProvider);
const fetch = Private(FetchProvider);
const docDataLooper = self.docLooper = Private(DocDataLooperProvider);
const searchLooper = self.searchLooper = Private(SearchLooperProvider);
// expose some internal modules
@ -38,7 +33,6 @@ uiModules.get('kibana/courier')
self.indexPatterns = indexPatterns;
self.redirectWhenMissing = Private(RedirectWhenMissingProvider);
self.DocSource = DocSource;
self.SearchSource = SearchSource;
/**
@ -57,7 +51,6 @@ uiModules.get('kibana/courier')
*/
self.start = function () {
searchLooper.start();
docDataLooper.start();
return this;
};
@ -95,28 +88,12 @@ uiModules.get('kibana/courier')
return this;
};
/**
* create a source object that is a child of this courier
*
* @param {string} type - the type of Source to create
*/
self.createSource = function (type) {
switch (type) {
case 'doc':
return new DocSource();
case 'search':
return new SearchSource();
}
};
/**
* Abort all pending requests
* @return {[type]} [description]
*/
self.close = function () {
searchLooper.stop();
docDataLooper.stop();
_.invoke(requestQueue, 'abort');

View file

@ -1,59 +0,0 @@
import ngMock from 'ng_mock';
import expect from 'expect.js';
import sinon from 'sinon';
import { requestQueue } from '../../_request_queue';
import { DocSourceProvider } from '../doc_source';
describe('DocSource', function () {
require('test_utils/no_digest_promises').activateForSuite();
let DocSource;
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
DocSource = Private(DocSourceProvider);
}));
beforeEach(requestQueue.clear);
after(requestQueue.clear);
describe('#onUpdate()', function () {
it('adds a request to the requestQueue', function () {
const source = new DocSource();
expect(requestQueue).to.have.length(0);
source.onUpdate();
expect(requestQueue).to.have.length(1);
});
it('returns a promise that is resolved with the results', function () {
const source = new DocSource();
const fakeResults = {};
const promise = source.onUpdate().then((results) => {
expect(results).to.be(fakeResults);
});
requestQueue[0].defer.resolve(fakeResults);
return promise;
});
});
describe('#destroy()', function () {
it('aborts all startable requests', function () {
const source = new DocSource();
source.onUpdate();
sinon.stub(requestQueue[0], 'canStart').returns(true);
source.destroy();
expect(requestQueue).to.have.length(0);
});
it('aborts all non-startable requests', function () {
const source = new DocSource();
source.onUpdate();
sinon.stub(requestQueue[0], 'canStart').returns(false);
source.destroy();
expect(requestQueue).to.have.length(0);
});
});
});

View file

@ -1,168 +0,0 @@
/**
* @name AbstractDocSource
*
* NOTE: This class is tightly coupled with _doc_send_to_es. Its primary
* methods (`doUpdate`, `doIndex`, `doCreate`) are all proxies for methods
* exposed by _doc_send_to_es (`update`, `index`, `create`). These methods are
* called with AbstractDocSource as the context. When called, they depend on private
* AbstractDocSource methods within their execution.
*/
import _ from 'lodash';
import 'ui/es';
import 'ui/storage';
import { DocSendToEsProvider } from './_doc_send_to_es';
import { AbstractDataSourceProvider } from './_abstract';
import { AbstractDocRequestProvider } from '../fetch/request/_abstract_doc';
export function AbstractDocSourceProvider(Private, Promise, es, sessionStorage) {
const sendToEs = Private(DocSendToEsProvider);
const SourceAbstract = Private(AbstractDataSourceProvider);
const DocRequest = Private(AbstractDocRequestProvider);
_.class(AbstractDocSource).inherits(SourceAbstract);
function AbstractDocSource(initialState, strategy) {
AbstractDocSource.Super.call(this, initialState, strategy);
}
AbstractDocSource.prototype.onUpdate = SourceAbstract.prototype.onResults;
AbstractDocSource.prototype.onResults = void 0;
/*****
* PUBLIC API
*****/
AbstractDocSource.prototype._createRequest = function (defer) {
return new DocRequest(this, defer);
};
/**
* List of methods that is turned into a chainable API in the constructor
* @type {Array}
*/
AbstractDocSource.prototype._methods = [
'index',
'type',
'id',
'sourceInclude',
'sourceExclude'
];
/**
* Applies a partial update to the document
* @param {object} fields - The fields to change and their new values (es doc field)
* @return {undefined}
*/
AbstractDocSource.prototype.doUpdate = function (fields) {
if (!this._state.id) return this.doIndex(fields);
return sendToEs.call(this, 'update', false, { doc: fields });
};
/**
* Update the document stored
* @param {[type]} body [description]
* @return {[type]} [description]
*/
AbstractDocSource.prototype.doIndex = function (body) {
return sendToEs.call(this, 'index', false, body);
};
AbstractDocSource.prototype.doCreate = function (body) {
return sendToEs.call(this, 'create', false, body, []);
};
/*****
* PRIVATE API
*****/
/**
* Get the type of this SourceAbstract
* @return {string} - 'doc'
*/
AbstractDocSource.prototype._getType = function () {
return 'doc';
};
/**
* Used to merge properties into the state within ._flatten().
* The state is passed in and modified by the function
*
* @param {object} state - the current merged state
* @param {*} val - the value at `key`
* @param {*} key - The key of `val`
* @return {undefined}
*/
AbstractDocSource.prototype._mergeProp = function (state, val, key) {
const flatKey = '_' + key;
if (val != null && state[flatKey] == null) {
state[flatKey] = val;
}
};
/**
* Creates a key based on the doc's index/type/id
* @return {string}
*/
AbstractDocSource.prototype._versionKey = function () {
const state = this._state;
if (!state.index || !state.type || !state.id) return;
return 'DocVersion:' + (
[ state.index, state.type, state.id ]
.map(encodeURIComponent)
.join('/')
);
};
/**
* Get the cached version number, not the version that is
* stored/shared with other tabs
*
* @return {number} - the version number, or undefined
*/
AbstractDocSource.prototype._getVersion = function () {
if (this._version) return this._version;
else return this._getStoredVersion();
};
/**
* Fetches the stored version from storage
* @return {[type]} [description]
*/
AbstractDocSource.prototype._getStoredVersion = function () {
const key = this._versionKey();
if (!key) return;
const v = sessionStorage.get(key);
this._version = v ? _.parseInt(v) : void 0;
return this._version;
};
/**
* Stores the version into storage
* @param {number, NaN} version - the current version number, NaN works well forcing a refresh
* @return {undefined}
*/
AbstractDocSource.prototype._storeVersion = function (version) {
if (!version) return this._clearVersion();
const key = this._versionKey();
if (!key) return;
this._version = version;
sessionStorage.set(key, version);
};
/**
* Clears the stored version for a AbstractDocSource
*/
AbstractDocSource.prototype._clearVersion = function () {
const key = this._versionKey();
if (!key) return;
sessionStorage.remove(key);
};
return AbstractDocSource;
}

View file

@ -1,89 +0,0 @@
/**
* @name _doc_send_to_es
*
* NOTE: Depends upon the es object to make ES requests, and also interacts
* with courier objects.
*/
import _ from 'lodash';
import { VersionConflict, RequestFailure } from 'ui/errors';
import { requestQueue } from 'ui/courier/_request_queue';
import { FetchProvider } from 'ui/courier/fetch/fetch';
export function DocSendToEsProvider(Promise, Private, es) {
const courierFetch = Private(FetchProvider);
/**
* Backend for doUpdate and doIndex
* @param {String} method - the client method to call
* @param {Boolean} validateVersion - should our knowledge
* of the the docs current version be sent to es?
* @param {String} body - HTTP request body
*/
return function (method, validateVersion, body, ignore) {
const doc = this;
// straight assignment will causes undefined values
const params = _.pick(this._state, ['id', 'type', 'index']);
params.body = body;
params.ignore = ignore || [409];
if (validateVersion && params.id) {
params.version = doc._getVersion();
}
return es[method](params)
.then(function (resp) {
if (resp.status === 409) throw new VersionConflict(resp);
doc._storeVersion(resp._version);
doc.id(resp._id);
let docFetchProm;
if (method !== 'index') {
docFetchProm = doc.fetch();
} else {
// we already know what the response will be
docFetchProm = Promise.resolve({
_id: resp._id,
_index: params.index,
_source: body,
_type: params.type,
_version: doc._getVersion(),
found: true
});
}
// notify pending request for this same document that we have updates
docFetchProm.then(function (fetchResp) {
// use the key to compair sources
const key = doc._versionKey();
// clear the queue and filter out the removed items, pushing the
// unmatched ones back in.
const respondTo = requestQueue.splice(0).filter(function (req) {
const isDoc = req.source._getType() === 'doc';
const keyMatches = isDoc && req.source._versionKey() === key;
// put some request back into the queue
if (!keyMatches) {
requestQueue.push(req);
return false;
}
return true;
});
return courierFetch.fakeFetchThese(respondTo, respondTo.map(function () {
return _.cloneDeep(fetchResp);
}));
});
return resp._id;
})
.catch(function (err) {
// cast the error
throw new RequestFailure(err);
});
};
}

View file

@ -1,21 +0,0 @@
import { AbstractDocSourceProvider } from './_abstract_doc_source';
import { DocDataStrategyProvider } from '../fetch/strategy/doc_data';
import { DocDataRequestProvider } from '../fetch/request/doc_data';
export function DocSourceProvider(Private) {
const AbstractDocSource = Private(AbstractDocSourceProvider);
const docStrategy = Private(DocDataStrategyProvider);
const DocRequest = Private(DocDataRequestProvider);
class DocSource extends AbstractDocSource {
constructor(initialState) {
super(initialState, docStrategy);
}
_createRequest(defer) {
return new DocRequest(this, defer);
}
}
return DocSource;
}

View file

@ -1,105 +0,0 @@
import sinon from 'sinon';
import expect from 'expect.js';
import ngMock from 'ng_mock';
import { DocSourceProvider } from '../../data_source/doc_source';
import { DocDataRequestProvider } from '../request/doc_data';
describe('Courier DocFetchRequest class', function () {
let storage;
let source;
let defer;
let req;
let setVersion;
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private, Promise, $injector) {
const DocSource = Private(DocSourceProvider);
const DocFetchRequest = Private(DocDataRequestProvider);
storage =
$injector.get('localStorage').store =
$injector.get('sessionStorage').store = {
getItem: sinon.stub(),
setItem: sinon.stub(),
removeItem: sinon.stub(),
clear: sinon.stub()
};
source = new DocSource({})
.set('index', 'doc-index')
.set('type', 'doc-type')
.set('id', 'doc-id');
defer = Promise.defer();
req = new DocFetchRequest(source, defer);
/**
* Setup the version numbers for tests. There are two versions for the
* purposes of these tests.
*
* @param {number} mine - the version that the DocSource most
* recently received from elasticsearch.
* @param {number} theirs - the version that other DocSources have
* received from elasticsearfch.
*/
setVersion = function (mine, theirs) {
source._version = mine;
storage.getItem.withArgs(source._versionKey()).returns(theirs);
};
}));
describe('#canStart', function () {
it('can if the doc is unknown', function () {
setVersion(undefined, undefined);
expect(req.canStart()).to.be(true);
});
it('cannot if the doc is unknown but the request is already in progress', function () {
setVersion(undefined, undefined);
req.start();
expect(req.canStart()).to.be(false);
});
it('can if the doc is out of date', function () {
setVersion(1, 2);
expect(req.canStart()).to.be(true);
});
it('can if the doc is out of date and the request is in progress', function () {
setVersion(1, 2);
req.start();
expect(req.canStart()).to.be(true);
});
it('cannot if the doc is up to date', function () {
setVersion(2, 2);
expect(req.canStart()).to.be(false);
});
it('can if the doc is overdated', function () {
setVersion(5, 2);
expect(req.canStart()).to.be(true);
});
it('can if shared version is cleared', function () {
setVersion(10, undefined);
expect(req.canStart()).to.be(true);
});
it('can if everyone else has a doc', function () {
setVersion(undefined, 10);
expect(req.canStart()).to.be(true);
});
});
});

View file

@ -7,7 +7,6 @@ import searchResp from 'fixtures/search_response';
import { requestQueue } from '../../_request_queue';
import { FetchProvider } from '../fetch';
import { DocSourceProvider } from '../../data_source/doc_source';
import { SearchSourceProvider } from '../../data_source/search_source';
describe('Fetch service', function () {
@ -16,7 +15,6 @@ describe('Fetch service', function () {
let es;
let fetch;
let Promise;
let DocSource;
let SearchSource;
let indexPattern;
@ -26,36 +24,11 @@ describe('Fetch service', function () {
Promise = $injector.get('Promise');
fetch = Private(FetchProvider);
indexPattern = Private(IndexPatternProvider);
DocSource = Private(DocSourceProvider);
SearchSource = Private(SearchSourceProvider);
}));
beforeEach(requestQueue.clear);
after(requestQueue.clear);
describe('#doc(docSource)', function () {
it('fetches a single doc source', function () {
const doc = {
_index: 'test-index',
_type: 'test-type',
_id: 'test-id',
};
const source = new DocSource({
index: doc._index,
type: doc._type,
id: doc._id
});
sinon.stub(es, 'mget').returns(Promise.resolve({
docs: [doc]
}));
return fetch.doc(source).then(function (resp) {
expect(resp).to.be(doc);
});
});
});
describe('#search(searchSource)', function () {
it('fetches a single search source', function () {
const resp = searchResp;

View file

@ -39,13 +39,6 @@ export function FetchProvider(Private, Promise) {
return defer.promise;
}
/**
* Fetch a single doc source
* @param {DocSource} source - The DocSource to request
* @async
*/
this.doc = fetchASource;
/**
* Fetch a single search source
* @param {SearchSource} source - The SearchSource to request

View file

@ -1,40 +0,0 @@
import { AbstractRequestProvider } from './request';
export function AbstractDocRequestProvider(Private) {
const AbstractRequest = Private(AbstractRequestProvider);
class AbstractDocRequest extends AbstractRequest {
constructor(...args) {
super(...args);
this.type = 'doc';
}
canStart() {
const parent = super.canStart();
if (!parent) return false;
const version = this.source._version;
const storedVersion = this.source._getStoredVersion();
// conditions that equal "fetch This DOC!"
const unknown = !version && !storedVersion;
const mismatch = version !== storedVersion;
return Boolean(mismatch || (unknown && !this.started));
}
handleResponse(resp) {
if (resp.found) {
this.source._storeVersion(resp._version);
} else {
this.source._clearVersion();
}
return super.handleResponse(resp);
}
}
return AbstractDocRequest;
}

View file

@ -1,14 +0,0 @@
import { DocDataStrategyProvider } from '../strategy/doc_data';
import { AbstractDocRequestProvider } from './_abstract_doc';
export function DocDataRequestProvider(Private) {
const docStrategy = Private(DocDataStrategyProvider);
const AbstractDocRequest = Private(AbstractDocRequestProvider);
class DataDocRequest extends AbstractDocRequest {
strategy = docStrategy;
}
return DataDocRequest;
}

View file

@ -1,25 +0,0 @@
export function DocDataStrategyProvider(Promise) {
return {
clientMethod: 'mget',
/**
* Flatten a series of requests into as ES request body
* @param {array} requests - an array of flattened requests
* @return {Promise} - a promise that is fulfilled by the request body
*/
reqsFetchParamsToBody: function (reqsFetchParams) {
return Promise.resolve({
docs: reqsFetchParams
});
},
/**
* Fetch the multiple responses from the ES Response
* @param {object} resp - The response sent from Elasticsearch
* @return {array} - the list of responses
*/
getResponses: function (resp) {
return resp.docs;
}
};
}

View file

@ -1,19 +0,0 @@
import { FetchProvider } from '../fetch';
import { LooperProvider } from './_looper';
import { DocDataStrategyProvider } from '../fetch/strategy/doc_data';
export function DocDataLooperProvider(Private) {
const fetch = Private(FetchProvider);
const Looper = Private(LooperProvider);
const DocStrategy = Private(DocDataStrategyProvider);
/**
* The Looper which will manage the doc fetch interval
* @type {Looper}
*/
const docLooper = new Looper(1500, function () {
fetch.fetchQueued(DocStrategy);
});
return docLooper;
}

View file

@ -6,7 +6,7 @@
* similar to how Backbone Models work.
*
* This class seems to interface with ES primarily through the es Angular
* service and a DocSource instance.
* service and the saved object api.
*/
import angular from 'angular';