Skip to content

Commit

Permalink
Restore RPC tasks methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Parry committed Mar 24, 2017
1 parent ed1ecac commit f6b5370
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 2 deletions.
6 changes: 5 additions & 1 deletion api/rpc/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,16 @@ function schedulerServerFactory(
var grpc = require('grpc');
var schedulerProto = grpc.load(self.options.protoFile).scheduler;

var tasks = require('./tasks.js');
var workflowGraphs = require('./workflowGraphs.js');
var workflows = require('./workflows.js');
var workflowTasks = require('./workflowTasks.js');

self.gRPC = new grpc.Server();
self.gRPC.addProtoService(schedulerProto.Scheduler.service, {
getBootstrap: grpcWrapper(tasks.getBootstrap),
getTasksById: grpcWrapper(tasks.getTasksById),
postTaskById: grpcWrapper(tasks.postTaskById),
workflowsGetGraphs: grpcWrapper(workflowGraphs.workflowsGetGraphs),
workflowsGetGraphsByName: grpcWrapper(workflowGraphs.workflowsGetGraphsByName),
workflowsPutGraphs: grpcWrapper(workflowGraphs.workflowsPutGraphs),
Expand Down Expand Up @@ -88,7 +92,7 @@ function schedulerServerFactory(
})
.catch(function(err) {
callback(err);
});
})
};
}

Expand Down
44 changes: 44 additions & 0 deletions api/rpc/tasks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2016, EMC, Inc.

'use strict';

var injector = require('../../index.js').injector;
var tasksApiService = injector.get('Http.Services.Api.Tasks');
var _ = injector.get('_'); // jshint ignore:line
var Errors = injector.get('Errors');
var Promise = injector.get('Promise');

var getBootstrap = function(call) {
return Promise.try(function() {
var scope = call.request.scope;
var ipAddress = call.request.ipAddress;
var macAddress = call.request.macAddress;
return tasksApiService.getBootstrap(scope, ipAddress, macAddress);
});
};

var getTasksById = function(call) {
return Promise.try(function() {
return tasksApiService.getTasks(call.request.identifier)
})
.catch(function (err) {
if (err.name === 'NoActiveTaskError') {
return {};
}
// throw a NotFoundError
throw new Errors.NotFoundError('Not Found');
});
};

var postTaskById = function(call) {
return Promise.try(function() {
return tasksApiService.postTasksById(call.request.identifier,
JSON.parse(call.request.config));
});
};

module.exports = {
getBootstrap: getBootstrap,
getTasksById: getTasksById,
postTaskById: postTaskById
};
18 changes: 18 additions & 0 deletions scheduler.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ syntax = "proto3";
package scheduler;

service Scheduler {
rpc getBootstrap (getBootstrapRequest) returns (HttpReply) {}
rpc getTasksById (getTasksByIdRequest) returns (HttpReply) {}
rpc postTaskById (postTaskByIdRequest) returns (HttpReply) {}
rpc workflowsGetGraphs (workflowsGetGraphsRequest) returns (HttpReply) {}
rpc workflowsGetGraphsByName (workflowsGetGraphsByNameRequest) returns (HttpReply) {}
rpc workflowsPutGraphs (workflowsPutGraphsRequest) returns (HttpReply) {}
Expand All @@ -19,6 +22,21 @@ service Scheduler {

}

message getBootstrapRequest {
repeated string scope = 1;
string ipAddress = 2;
string macAddress = 3;
}

message getTasksByIdRequest {
string identifier = 1;
}

message postTaskByIdRequest {
string identifier = 1;
string config = 2;
}

message workflowsGetGraphsRequest {
}

Expand Down
8 changes: 7 additions & 1 deletion spec/api/rpc/index-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ describe('TaskGraph.TaskScheduler.Server', function () {
'workflowsGetGraphs',
'workflowsGetGraphsByName',
'workflowsPutGraphs',
'workflowsDeleteGraphs',
'workflowsDeleteGraphs'
];
var tasksMethods = [
'getBootstrap',
'getTaskById',
'postTaskById'
];
var workflowsMethods = [
'workflowsGet',
Expand All @@ -53,6 +58,7 @@ describe('TaskGraph.TaskScheduler.Server', function () {
mockery = require('mockery');
mockery.registerMock('./workflowGraphs.js', _buildMock(workflowsGraphMethods));
mockery.registerMock('./workflowTasks.js', _buildMock(workflowsTasksMethods));
mockery.registerMock('./tasks.js', _buildMock(tasksMethods));
mockery.registerMock('./workflows.js', _buildMock(workflowsMethods));
mockery.registerMock('grpc', _buildMock(gprcMethods));
mockery.enable({ useCleanCache: true, warnOnUnregistered: false });
Expand Down
140 changes: 140 additions & 0 deletions spec/api/rpc/tasks-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// Copyright 2016, EMC, Inc.
/* jshint node:true */

'use strict';

describe('Taskgraph.Api.Tasks.Rpc', function () {
var mockery;
var tasksApi;

before('setup mockery', function () {
this.timeout(10000);

// setup injector with mock override injecatbles
var injectables = [
helper.di.simpleWrapper({
controller: function(opts, cb) {
if (typeof(opts) === 'function') {
cb = opts;
}
return cb;
}
}, 'Http.Services.Swagger'),
helper.di.simpleWrapper({
getBootstrap: sinon.stub(),
getTasks: sinon.stub(),
postTasksById: sinon.stub()
}, 'Http.Services.Api.Tasks')
];
helper.setupInjector(injectables);

// setup mockery such that index.injector is our test injector.
mockery = require('mockery');
mockery.registerMock('../../index.js', { injector: helper.injector });
mockery.enable();

// Now require file to test
tasksApi = require('../../../api/rpc/tasks');
});


after('disable mockery', function () {
mockery.deregisterMock('../../index.js');
mockery.disable();
});

describe('GET /tasks/:id', function () {
it("should get a task by id", function() {
var tasksApiService = helper.injector.get('Http.Services.Api.Tasks');
tasksApiService.getTasks.resolves('a task');
return tasksApi.getTasksById({ request: { identifier: '123' } })
.should.eventually.equal('a task');
});

it("should reject with not found if getTasks rejects", function() {
var tasksApiService = helper.injector.get('Http.Services.Api.Tasks');

tasksApiService.getTasks.rejects('Not Found');
return tasksApi.getTasksById({ request: { identifier: '123' } })
.should.be.rejectedWith('Not Found');
});

it("should reject with not found if req is invalid", function() {
var tasksApiService = helper.injector.get('Http.Services.Api.Tasks');
tasksApiService.getTasks.resolves();
return tasksApi.getTasksById(undefined)
.should.be.rejectedWith('Not Found');
});
});

describe("GET /tasks/bootstrap.js", function() {
it("should get bootstrap", function() {
var tasksApiService = helper.injector.get('Http.Services.Api.Tasks');
tasksApiService.getBootstrap.resolves('bootstrap');
return tasksApi.getBootstrap( { request: { scope: '' } }, { request: { ipAddress: '123' } },
{ request: { macAddress: '10.20.30' } } )
.should.eventually.equal('bootstrap');
});

it("should reject if getBootstrap rejects", function() {
var tasksApiService = helper.injector.get('Http.Services.Api.Tasks');
tasksApiService.getBootstrap.rejects('No Bootstrap');
return tasksApi.getBootstrap( { request: { scope: '' } }, { request: { ipAddress: '123' } },
{ request: { macAddress: '10.20.30' } } )
.should.be.rejectedWith('No Bootstrap');
});

it("should reject if req is invalid", function() {
var tasksApiService = helper.injector.get('Http.Services.Api.Tasks');
tasksApiService.getBootstrap.resolves();
return tasksApi.getBootstrap(undefined)
.should.be.rejectedWith(/undefined/);
});
});

// Since sinon.stub() has no returnsArg method, add a Promise wrapper.
// This will allow a stub to return a promise resolving to one of its call
// arguments.
function _stubPromiseWrapper(stub) {
return function() {
return Promise.resolve(stub.apply(sinon, arguments));
};
}

describe("POST /tasks/:id", function() {
beforeEach(function() {
var tasksApiService = helper.injector.get('Http.Services.Api.Tasks');
tasksApiService.postTasksById = sinon.stub();
});

it("should post a task", function() {
var tasksApiService = helper.injector.get('Http.Services.Api.Tasks');
tasksApiService.postTasksById = _stubPromiseWrapper(sinon.stub().returnsArg(1));
return tasksApi.postTaskById({ request: { identifier: '123' },
request: { config: '{ "foo": "bar" }' } })
.then(function(body) {
expect(body).to.deep.equal({ foo: 'bar' });
});
});


it("should reject if postTaskById rejects", function() {
var tasksApiService = helper.injector.get('Http.Services.Api.Tasks');
tasksApiService.postTasksById.rejects('post error');
return tasksApi.postTaskById({ request: { identifier: '123' },
request: { config: '{ "foo": "bar" }' } })
.should.be.rejectedWith('post error');

});


it("should reject if postTaskById rejects", function() {
var tasksApiService = helper.injector.get('Http.Services.Api.Tasks');
tasksApiService.postTasksById.resolves();
return tasksApi.postTaskById({ swagger: undefined,
body: { foo: 'bar' } })
.should.be.rejectedWith(/undefined/);

});
});
});

0 comments on commit f6b5370

Please sign in to comment.