aboutsummaryrefslogtreecommitdiffstats
path: root/lib/inventory.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/inventory.js')
-rw-r--r--lib/inventory.js213
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);
+ }
+ });
+ }