Skip to content

Commit

Permalink
Merge pull request #172 from forio/dms3-version
Browse files Browse the repository at this point in the history
Dms3 version
  • Loading branch information
mmrj authored Sep 20, 2016
2 parents 8cc4e9e + af63366 commit ae3555b
Show file tree
Hide file tree
Showing 12 changed files with 225 additions and 83 deletions.
2 changes: 1 addition & 1 deletion documentation/index.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Although in most cases you'll work with the managers directly, the services are
* [Variables Service](./generated/variables-api-service/)
* [World Adapter](./generated/world-api-adapter/)
* [Data Service](./generated/data-api-service/)
* [Other Adapters](./other-adapters/) are used less frequently, and include [Asset Adapter](./generated/asset-api-adapter/), [State Adapter](./generated/state-api-adapter/), [User Adapter](./generated/user-api-adapter/), and [Member Adapter](./generated/member-api-adapter/).
* [Other Adapters](./other-adapters/) are used less frequently, and include [Asset Adapter](./generated/asset-api-adapter/), [State Adapter](./generated/state-api-adapter/), [User Adapter](./generated/user-api-adapter/), [Member Adapter](./generated/member-api-adapter/), and [Introspection Service](./generated/introspection-api-service/).



Expand Down
3 changes: 2 additions & 1 deletion documentation/other-adapters/index.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ The other, less commonly used adapters include:
* [Asset Adapter](../generated/asset-api-adapter/)
* [State Adapter](../generated/state-api-adapter/)
* [User Adapter](../generated/user-api-adapter/)
* [Member Adapter](../generated/member-api-adapter/)
* [Member Adapter](../generated/member-api-adapter/)
* [Introspection Service](../generated/introspection-api-service/)
3 changes: 3 additions & 0 deletions grunt/markdox.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ module.exports = function (grunt) {
}, {
src: 'src/service/channel-service.js',
dest: 'documentation/generated/channel-service/index.html.md'
}, {
src: 'src/service/introspection-api-service.js',
dest: 'documentation/generated/introspection-api-service/index.html.md'
}, {
src: 'src/service/state-api-adapter.js',
dest: 'documentation/generated/state-api-adapter/index.html.md'
Expand Down
2 changes: 1 addition & 1 deletion grunt/mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = function (grunt) {
reporter: 'Min',
options: {
coverage: {
coverageFile: 'coverage/coverage.json'
jsonReport: 'coverage'
}
}
},
Expand Down
1 change: 1 addition & 0 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ F.service.User = require('./service/user-api-adapter');
F.service.Member = require('./service/member-api-adapter');
F.service.Asset = require('./service/asset-api-adapter');
F.service.Group = require('./service/group-api-service');
F.service.Introspect = require('./service/introspection-api-service');

F.store.Cookie = require('./store/cookie-store');
F.factory.Store = require('./store/store-factory');
Expand Down
28 changes: 10 additions & 18 deletions src/service/admin-file-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,29 +128,21 @@ module.exports = function (config) {
* Creates a file in the given file path.
* @param {String} `filePath` Path to the file
* @param {String} `contents` Contents to write to file
* @param {Boolean} `replaceExisting` Replace file if it already exists; defaults to false
* @param {Object} `options` (Optional) Overrides for configuration options
*/
create: function (filePath, contents, options) {
create: function (filePath, contents, replaceExisting, options) {
var httpOptions = uploadFileOptions(filePath, contents, options);

return http.post(httpOptions.data, httpOptions);
},

/**
* Uploads a file to the given path. It will try to create the file and if there's a conflict error (409) it will try to replace the file instead.
* @param {String} `filePath` Path to the file
* @param {String} `contents` Contents to write to file
* @param {Object} `options` (Optional) Overrides for configuration options
*/
upload: function (filePath, contents, options) {
var self = this;

return this.create(filePath, contents, options)
.then(null, function (xhr) {
var prom = http.post(httpOptions.data, httpOptions);
var me = this;
if (replaceExisting === true) {
prom = prom.then(null, function (xhr) {
if (xhr.status === 409) {
return self.replace(filePath, contents, options);
return me.replace(filePath, contents, options);
}
});
}
return prom;
},

/**
Expand All @@ -169,7 +161,7 @@ module.exports = function (config) {
/**
* Renames the file.
* @param {String} filePath Path to the file
* @param {Stirng} newName New name of file
* @param {String} newName New name of file
* @param {Object} options (Optional) Overrides for configuration options
*/
rename: function (filePath, newName, options) {
Expand Down
108 changes: 77 additions & 31 deletions src/service/introspection-api-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,48 @@
*
* The Introspection API Service allows you to view a list of the variables and operations in a model. Used in conjunction with the [Run API Service](../run-api-service/).
*
* var rm = new F.manager.RunManager({
* run: {
* var intro = new F.service.Introspect({
* account: 'acme-simulations',
* project: 'supply-chain-game',
* model: 'supply-chain-model.py'
* }
* });
* rm.getRun()
* .then(function() {
* var intro = rm.run.introspection();
* project: 'supply-chain-game'
* });
* intro.byModel('supply-chain.py').then(function(data){ ... });
* intro.byRunID('2b4d8f71-5c34-435a-8c16-9de674ab72e6').then(function(data){ ... });
*
*/

'use strict';

var ConfigService = require('./configuration-service');
var TransportFactory = require('../transport/http-transport-factory');
var SessionManager = require('../store/session-manager');

var apiEndpoint = 'model/introspect';

module.exports = function (config) {
var defaults = {
server: {
versionPath: 'v3/'
}
/**
* For projects that require authentication, pass in the user access token (defaults to empty string). If the user is already logged in to Epicenter, the user access token is already set in a cookie and automatically loaded from there. (See [more background on access tokens](../../../project_access/)).
* @see [Authentication API Service](../auth-api-service/) for getting tokens.
* @type {String}
*/
token: undefined,

/**
* The account id. In the Epicenter UI, this is the **Team ID** (for team projects) or **User ID** (for personal projects). Defaults to empty string. If left undefined, taken from the URL.
* @type {String}
*/
account: undefined,

/**
* The project id. Defaults to empty string. If left undefined, taken from the URL.
* @type {String}
*/
project: undefined,

};
var serviceOptions = $.extend({}, defaults, config);

var sessionManager = new SessionManager();
var serviceOptions = sessionManager.getMergedOptions(defaults, config);

var urlConfig = new ConfigService(serviceOptions).get('server');
if (serviceOptions.account) {
Expand All @@ -39,43 +55,73 @@ module.exports = function (config) {
urlConfig.projectPath = serviceOptions.project;
}

urlConfig.filter = ';';

var httpOptions = {
url: urlConfig.getAPIPath('model') + 'publish'
};
var transportOptions = $.extend(true, {}, serviceOptions.transport, {
url: urlConfig.getAPIPath(apiEndpoint)
});
if (serviceOptions.token) {
httpOptions.headers = {
transportOptions.headers = {
'Authorization': 'Bearer ' + serviceOptions.token
};
}
var http = new TransportFactory(httpOptions);
var http = new TransportFactory(transportOptions);

var publicAPI = {
/**
* Get the available functions and variables.
* Get the available variables and operations for a given model file.
*
* Note: This does not work for any model which requires additional parameters, such as `files`.
*
* **Example**
*
* intro.byModel('abc.vmf')
* .then(function(data) {
* // data contains an object with available functions (used with operations API) and available variables (used with variables API)
* console.log(data.functions);
* console.log(data.variables);
* });
*
* **Parameters**
* @param {String} `modelFile` Name of the model file to introspect.
* @param {Object} `options` (Optional) Overrides for configuration options.
*/
byModel: function (modelFile, options) {
var opts = $.extend(true, {}, serviceOptions, options);
if (!opts.account || !opts.project) {
throw new Error('Account and project are required when using introspect#byModel');
}
if (!modelFile) {
throw new Error('modelFile is required when using introspect#byModel');
}
var url = { url: urlConfig.getAPIPath(apiEndpoint) + [opts.account, opts.project, modelFile].join('/') };
var httpOptions = $.extend(true, {}, serviceOptions, options, url);
return http.get('', httpOptions);
},

/**
* Get the available variables and operations for a given model file.
*
* Note: This does not work for any model which requires additional parameters such as `files`.
*
* **Example**
*
* intro.get()
* intro.byRunID('2b4d8f71-5c34-435a-8c16-9de674ab72e6')
* .then(function(data) {
* // data contains an object with available functions (used with operations API) and available variables (used with variables API)
* console.log(data.functions);
* console.log(data.variables);
* });
*
* **Parameters**
* @param {String} `runId` (Optional) Overrides the run id used when the service was created
* @param {String} `runID` Id of the run to introspect.
* @param {Object} `options` (Optional) Overrides for configuration options.
*/
get: function (runId, options) {
var httpOptions = $.extend(true, {}, serviceOptions, options);
var params = {
runId: runId || httpOptions.filter,
commandWrapper: { command: { introspect: {} } },
reanimate: false
};
return http.post(params, httpOptions);
byRunID: function (runID, options) {
if (!runID) {
throw new Error('runID is required when using introspect#byModel');
}
var url = { url: urlConfig.getAPIPath(apiEndpoint) + runID };
var httpOptions = $.extend(true, {}, serviceOptions, options, url);
return http.get('', httpOptions);
}
};
$.extend(this, publicAPI);
Expand Down
35 changes: 30 additions & 5 deletions src/service/run-api-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ module.exports = function (config) {
var oldSuccess = createOptions.success;
createOptions.success = function (response) {
serviceOptions.filter = response.id; //all future chained calls to operate on this id
serviceOptions.id = response.id;
return oldSuccess.apply(this, arguments);
};

Expand Down Expand Up @@ -472,6 +473,35 @@ module.exports = function (config) {
});

return $d.promise();
},

/**
* Shortcut to using the [Introspection API Service](../introspection-api-service/). Allows you to view a list of the variables and operations in a model.
*
* **Example**
*
* rs.introspect({ runID: 'cbf85437-b539-4977-a1fc-23515cf071bb' }).then(function (data) {
* console.log(data.functions);
* console.log(data.variables);
* });
*
* **Parameters**
* @param {Object} `options` Options can either be of the form `{ runID: <runid> }` or `{ model: <modelFileName> }`.
* @param {Object} `introspectionConfig` (Optional) Service options for Introspection Service
*/
introspect: function (options, introspectionConfig) {
var introspection = new IntrospectionService($.extend(true, {}, serviceOptions, introspectionConfig));
if (options) {
if (options.runID) {
return introspection.byRunID(options.runID);
} else if (options.model) {
return introspection.byModel(options.model);
}
} else if (serviceOptions.id) {
return introspection.byRunID(serviceOptions.id);
} else {
throw new Error('Please specify either the model or runid to introspect');
}
}
};

Expand All @@ -495,11 +525,6 @@ module.exports = function (config) {
runService: this
}));
return vs;
},

introspection: function (config) {
var introspection = new IntrospectionService($.extend(true, {}, serviceOptions, config));
return introspection;
}
};

Expand Down
1 change: 1 addition & 0 deletions tests/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
<script src="spec/test-member-api-service.js"></script>
<script src="spec/test-asset-api-adapter.js"></script>
<script src="spec/test-state-api-adapter.js"></script>
<script src="spec/test-introspection-api-service.js"></script>
<script src="spec/test-cookie-store.js"></script>
<script src="spec/test-admin-file-service.js"></script>
<script src="spec/test-group-api-service.js"></script>
Expand Down
29 changes: 3 additions & 26 deletions tests/spec/test-admin-file-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,25 +122,16 @@
var content = '<html></html>';
var fs = new FileService({ account: account, project: projectUpload, folderType: 'static' });
fs.create('test.html', content);
server.requests.should.have.lengthOf(2);

var req = server.requests.pop();
req.requestBody.should.include(content);
req.requestBody.should.include('test.html');
});
});
describe('#upload', function () {
it('Should do a POST only', function () {
var fs = new FileService({ account: account, project: projectUpload, folderType: 'static' });
fs.upload('new.html', '<html></html>');

var req = server.requests.pop();
req.method.toUpperCase().should.equal('POST');
});

it('Should do a POST and PUT after it fails', function (done) {
it('should overwrite if file is present and `replaceExisting` is set', function (done) {
server.requests = [];
var fs = new FileService({ account: account, project: projectUpload, folderType: 'static' });
fs.upload('existing.html', '<html></html>').then(function () {
fs.create('existing.html', '<html></html>', true).then(function () {
server.requests.should.have.lengthOf(2);
var req = server.requests.pop();
req.method.toUpperCase().should.equal('PUT');
Expand All @@ -151,20 +142,6 @@
done(new Error('Should not fail'));
});
});

it('Should only do a POST', function (done) {
server.requests = [];
var fs = new FileService({ account: account, project: projectUpload, folderType: 'static' });

fs.upload('new.html', '<html></html>').then(function () {
server.requests.should.have.lengthOf(1);
var req = server.requests.pop();
req.method.toUpperCase().should.equal('POST');
done();
}, function () {
done(new Error('Should not fail'));
});
});
});
describe('#remove', function () {
it('Should do a DELETE', function () {
Expand Down
Loading

0 comments on commit ae3555b

Please sign in to comment.