125 lines
4.3 KiB
JavaScript
125 lines
4.3 KiB
JavaScript
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you 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.
|
|
*/
|
|
|
|
/**
|
|
* Service which contains all REST API response caches.
|
|
*/
|
|
angular.module('rest').factory('dataSourceService', ['$injector',
|
|
function dataSourceService($injector) {
|
|
|
|
// Required types
|
|
var Error = $injector.get('Error');
|
|
|
|
// Required services
|
|
var $q = $injector.get('$q');
|
|
|
|
// Service containing all caches
|
|
var service = {};
|
|
|
|
/**
|
|
* Invokes the given function once for each of the given data sources,
|
|
* passing that data source as the first argument to each invocation,
|
|
* followed by any additional arguments passed to apply(). The results of
|
|
* each invocation are aggregated into a map by data source identifier,
|
|
* and handled through a single promise which is resolved or rejected
|
|
* depending on the success/failure of each resulting REST call. Any error
|
|
* results in rejection of the entire apply() operation, except 404 ("NOT
|
|
* FOUND") errors, which are ignored.
|
|
*
|
|
* @param {Function} fn
|
|
* The function to call for each of the given data sources. The data
|
|
* source identifier will be given as the first argument, followed by
|
|
* the rest of the arguments given to apply(), in order. The function
|
|
* must return a Promise which is resolved or rejected depending on the
|
|
* result of the REST call.
|
|
*
|
|
* @param {String[]} dataSources
|
|
* The array or data source identifiers against which the given
|
|
* function should be called.
|
|
*
|
|
* @param {...*} args
|
|
* Any additional arguments to pass to the given function each time it
|
|
* is called.
|
|
*
|
|
* @returns {Promise.<Object.<String, *>>}
|
|
* A Promise which resolves with a map of data source identifier to
|
|
* corresponding result. The result will be the exact object or value
|
|
* provided as the resolution to the Promise returned by calls to the
|
|
* given function.
|
|
*/
|
|
service.apply = function apply(fn, dataSources) {
|
|
|
|
var deferred = $q.defer();
|
|
|
|
var requests = [];
|
|
var results = {};
|
|
|
|
// Build array of arguments to pass to the given function
|
|
var args = [];
|
|
for (var i = 2; i < arguments.length; i++)
|
|
args.push(arguments[i]);
|
|
|
|
// Retrieve the root group from all data sources
|
|
angular.forEach(dataSources, function invokeAgainstDataSource(dataSource) {
|
|
|
|
// Add promise to list of pending requests
|
|
var deferredRequest = $q.defer();
|
|
requests.push(deferredRequest.promise);
|
|
|
|
// Retrieve root group from data source
|
|
fn.apply(this, [dataSource].concat(args))
|
|
|
|
// Store result on success
|
|
.then(function immediateRequestSucceeded(data) {
|
|
results[dataSource] = data;
|
|
deferredRequest.resolve();
|
|
},
|
|
|
|
// Fail on any errors (except "NOT FOUND")
|
|
function immediateRequestFailed(error) {
|
|
|
|
if (error.type === Error.Type.NOT_FOUND)
|
|
deferredRequest.resolve();
|
|
|
|
// Explicitly abort for all other errors
|
|
else
|
|
deferredRequest.reject(error);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
// Resolve if all requests succeed
|
|
$q.all(requests).then(function requestsSucceeded() {
|
|
deferred.resolve(results);
|
|
},
|
|
|
|
// Reject if at least one request fails
|
|
function requestFailed(response) {
|
|
deferred.reject(response);
|
|
});
|
|
|
|
return deferred.promise;
|
|
|
|
};
|
|
|
|
return service;
|
|
|
|
}]);
|