diff options
Diffstat (limited to 'lib/inventory.js')
-rw-r--r-- | lib/inventory.js | 213 |
1 files changed, 166 insertions, 47 deletions
diff --git a/lib/inventory.js b/lib/inventory.js index 5124a98..fbf83df 100644 --- a/lib/inventory.js +++ b/lib/inventory.js @@ -19,6 +19,7 @@ See the License for the specific language governing permissions and limitations "use strict"; const req = require('./promise_request'); + const createError = require('./dispatcher-error').createDispatcherError; const INV_SERV_TYPES = '/dcae-service-types'; const INV_SERVICES = '/dcae-services'; @@ -34,12 +35,20 @@ See the License for the specific language governing permissions and limitations return []; } else { - var newErr = new Error("Error response " + err.status + " from DCAE inventory: " + err.body); - newErr.status = 502; - newErr.code = 502; + var newErr; + var message; + if (err.status) { + /* Got a response from inventory indicating an error */ + message = "Error response " + err.status + " from DCAE inventory: " + err.body; + newErr = createError(message, 502, "api", 501, "dcae-inventory"); + } + else { + /* Problem connecting to inventory */ + message = "Error communicating with inventory: " + err.message; + newErr = createError(message, 504, "system", 201, "dcae-inventory"); + } throw newErr; - } - + } }; /* @@ -48,30 +57,45 @@ See the License for the specific language governing permissions and limitations * objects, each object having: - type: the service type name associated * with the blueprint template - template: the blueprint template */ - const findTemplates = function(targetType, location, serviceId) { + const findTemplates = function(targetType, location, serviceId, asdcServiceId, asdcResourceId) { /* Set up query string based on available parameters */ - var qs = {vnfType: targetType, serviceLocation: location }; + var qs = {serviceLocation: location, onlyActive: true, onlyLatest: true}; + if (serviceId) { qs.serviceId = serviceId; } + + if (asdcResourceId) { + qs.asdcResourceId = asdcResourceId; + } + + if (asdcServiceId){ + qs.asdcServiceId = asdcServiceId; + } + + /* We'll set vnfType in the query except when both asdcServiceId and asdcResourceId are populated */ + if (!(asdcResourceId && asdcServiceId)) { + qs.vnfType = targetType; + } + /* Make the request to inventory */ const reqOptions = { - method : "GET", - uri : config.inventory.url + INV_SERV_TYPES, - qs: qs - }; - return req.doRequest(reqOptions) - .then(function(result) { - let templates = []; - let content = JSON.parse(result.body); - if (content.items) { - /* Pick out the fields we want */ - templates = content.items.map(function(i) {return {type: i.typeName, template: i.blueprintTemplate};}); - } - return templates; - }) - .catch (invError); + method : "GET", + uri : config.inventory.url + INV_SERV_TYPES, + qs: qs + }; + return req.doRequest(reqOptions) + .then(function(result) { + var templates = []; + var content = JSON.parse(result.body); + if (content.items) { + /* Pick out the fields we want */ + templates = content.items.map(function(i) {return {type: i.typeId, template: i.blueprintTemplate};}); + } + return templates; + }) + .catch (invError); }; /* @@ -88,8 +112,8 @@ See the License for the specific language governing permissions and limitations }; return req.doRequest(reqOptions) .then(function(result) { - let services = []; - let content = JSON.parse(result.body); + var services = []; + var content = JSON.parse(result.body); if(content.items) { /* Pick out the fields we want */ services = content.items.map(function(i) { return {type: i.typeLink.title, deploymentId: i.deploymentRef};}); @@ -113,8 +137,8 @@ See the License for the specific language governing permissions and limitations }; return req.doRequest(reqOptions) .then(function(result) { - let shareables = {}; - let content = JSON.parse(result.body); + var shareables = {}; + var content = JSON.parse(result.body); if (content.items) { content.items.forEach(function(s) { s.components.filter(function(c) {return c.shareable === 1;}) @@ -130,25 +154,42 @@ See the License for the specific language governing permissions and limitations /* - * Middleware-style function to check inventory. For 'deploy' operations, - * finds blueprint templates and shareable components Attaches list of - * templates to req.dcae_templates, object with shareable components to - * req.dcae_shareables. For 'undeploy' operations, finds deployed services. - * Attaches list of deployed services to req.dcae_services. - */ + * Middleware-style function to check inventory. + * + * For 'deploy' operations: + * - finds blueprint templates and shareable components + * - attaches list of templates to req.dcae_templates + * - attaches object with shareable components to req.dcae_shareables + * + * For 'undeploy' operations: + * - finds deployed services + * - attaches list of deployed services to req.dcae_services + */ exports.checkInventory = function(req, res, next) { - if (req.body.dcae_service_action.toLowerCase() === 'deploy'){ - findTemplates(req.body.dcae_target_type, req.body.dcae_service_location, req.body.dcae_service_type) + if (req.body.dcae_service_action.toLowerCase() === 'deploy') { + findTemplates( + req.body.dcae_target_type, + req.body.dcae_service_location, + req.body.dcae_service_type, + req.body['dcae_service-instance_persona-model-id'], + req.body['dcae_generic-vnf_persona-model-id'] + ) .then(function (templates) { if (templates.length > 0) { req.dcae_templates = templates; return templates; } else { - var paramList = [req.body.dcae_target_type, req.body.dcae_service_location, req.body.dcae_service_type ? req.body.dcae_service_type : "unspecified"].join('/'); - let err = new Error(paramList + ' has no associated DCAE service types'); - err.status = 400; - next(err); + var paramList = [ + req.body.dcae_target_type, + req.body.dcae_service_location, + req.body.dcae_service_type || "unspecified", + req.body['dcae_service-instance_persona-model-id'] || "unspecified", + req.body['dcae_generic-vnf_persona-model-id'] || "unspecified" + ].join('/'); + var err0 = new Error(paramList + ' has no associated DCAE service types'); + err0.status = 400; + next(err0); } }) .then(function(result) { @@ -170,9 +211,9 @@ See the License for the specific language governing permissions and limitations next(); } else { - let err = new Error('"' + req.body.dcae_target_name + '" has no deployed DCAE services'); - err.status = 400; - next(err); + var err1 = new Error('"' + req.body.dcae_target_name + '" has no deployed DCAE services'); + err1.status = 400; + next(err1); } }) .catch(function(err) { @@ -180,9 +221,9 @@ See the License for the specific language governing permissions and limitations }); } else { - let err = new Error ('"' + req.body.dcae_service_action + '" is not a valid service action. Valid actions: "deploy", "undeploy"'); - err.status = 400; - next(err); + var err2 = new Error ('"' + req.body.dcae_service_action + '" is not a valid service action. Valid actions: "deploy", "undeploy"'); + err2.status = 400; + next(err2); } }; @@ -192,12 +233,12 @@ See the License for the specific language governing permissions and limitations exports.addService = function(deploymentId, serviceType, vnfId, vnfType, vnfLocation, outputs) { /* Create the service description */ - let serviceDescription = + var serviceDescription = { - "typeName" : serviceType, "vnfId" : vnfId, "vnfType" : vnfType, "vnfLocation" : vnfLocation, + "typeId" : serviceType, "deploymentRef" : deploymentId }; @@ -226,4 +267,82 @@ See the License for the specific language governing permissions and limitations exports.deleteService = function(serviceId) { return req.doRequest({method: "DELETE", uri: config.inventory.url + INV_SERVICES + "/" + serviceId}); }; -
\ No newline at end of file + + /* + * Find running/deploying instances of services (with a given type name, if specified) + */ + + exports.getServicesByType = function(query) { + var options = { + method: 'GET', + uri: config.inventory.url + INV_SERVICES, + qs: query || {} + }; + + return req.doRequest(options) + .then (function (result) { + var services = []; + var content = JSON.parse(result.body); + if(content.items) { + /* Pick out the fields we want */ + services = content.items.map(function(i) { return { deploymentId: i.deploymentRef, serviceTypeId: i.typeId};}); + } + return services; + }) + .catch(invError); + }; + + /* + * Find a blueprint given the service type ID -- return blueprint and type ID + */ + exports.getBlueprintByType = function(serviceTypeId) { + return req.doRequest({ + method: "GET", + uri: config.inventory.url + INV_SERV_TYPES + '/' + serviceTypeId + }) + .then (function(result) { + var blueprintInfo = {}; + var content = JSON.parse(result.body); + blueprintInfo.blueprint = content.blueprintTemplate; + blueprintInfo.typeId = content.typeId; + + return blueprintInfo; + }) + .catch(invError); + }; + + /* + * Verify that the specified deployment ID does not already have + * an entry in inventory. This is needed to enforce the rule that + * creating a second instance of a deployment under the + * same ID as an existing deployment is not permitted. + * The function checks for a service in inventory using the + * deployment ID as service name. If it doesn't exist, the function + * resolves its promise. If it *does* exist, then it throws an error. + */ + exports.verifyUniqueDeploymentId = function(deploymentId) { + + return req.doRequest({ + method: "GET", + uri: config.inventory.url + INV_SERVICES + "/" + deploymentId + }) + + /* Successful lookup -- the deployment exists, so throw an error */ + .then(function(res) { + throw createError("Deployment " + deploymentId + " already exists", 409, "api", 501); + }, + + /* Error from the lookup -- either deployment ID doesn't exist or some other problem */ + function (err) { + + /* Inventory returns a 404 if it does not find the deployment ID */ + if (err.status && err.status === 404) { + return true; + } + + /* Some other error -- it really is an error and we can't continue */ + else { + return invError(err); + } + }); + } |