Skip to content

Commit

Permalink
feature(admin): add route to get service configuration (#50)
Browse files Browse the repository at this point in the history
* feature(admin): add route to get service configuration

* feat(admin): add explicit error status on getting service configuration

* feat(admin): only add service id in response when getting all of services

* fix(admin): fix error message to get right service from request parameters

* feat(test): add cucumber test for /services/:service route

* feat(admin): update get service configuration according review

* fix(admin): function getServicesConfigurations do not need request parameters

* creation and use of serviceRequest, and form changes

---------

Co-authored-by: Loic <loic.grondin@ign.fr>
  • Loading branch information
benoitblanc and lgrd committed Mar 15, 2023
1 parent 2a07aec commit 0d36022
Show file tree
Hide file tree
Showing 11 changed files with 273 additions and 27 deletions.
1 change: 1 addition & 0 deletions documentation/test/integration/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ C'est l'approche bottom-up qui a été choisie pour ces tests. On va tester les
- serverManager (server, ExpressJS, log4js, fs, assert)
- healthRequest (request)
- healthResponse (response)
- serviceRequest (request)

- Deuxième niveau:
- routeRequest (request, point)
Expand Down
99 changes: 80 additions & 19 deletions src/js/administrator/administrator.js
Original file line number Diff line number Diff line change
Expand Up @@ -565,38 +565,99 @@ module.exports = class Administrator {
* @function
* @name getServicesConfigurations
* @description Récupération de la configuration des services
* @param {json} response - Reponse json contenant les configuration de services
* @return {object} responses - Json contenant les configuration de services gérés par l'administrateur
*
*/

getServicesConfigurations(parameters) {
getServicesConfigurations() {

LOGGER.info("getServicesConfigurations...");

let responses = new Array();

LOGGER.debug("Récupération des configurations de chaque service");

// Pour chaque service, on récupère la configuration depuis le fichier de configuration
for (let i = 0; i < this._configuration.administration.services.length; i++) {
for (let i = 0; i < this._configuration.administration.services.length; i++) {

const curServiceId = this._configuration.administration.services[i].id;
let curServiceAdminConf = this._configuration.administration.services[i];

LOGGER.debug("Lecture fichier de configuration du service : " + curServiceId);
try {
const curServiceConf = this._configuration.administration.services[i].configuration
const configurationLocation = path.resolve(path.dirname(this._configurationPath), curServiceConf);
let configuration = JSON.parse(fs.readFileSync(configurationLocation));

// Ajout de l'id
configuration.id = curServiceId

responses.push(configuration)

} catch (error) {
throw errorManager.createError("Can't read service configuration file : " + error)
}
}
LOGGER.debug("Récupération de la configuration du service : " + curServiceAdminConf.id);

let configuration = this.readServiceConfiguration(curServiceAdminConf);

// Ajout de l'id
configuration.id = curServiceAdminConf.id

responses.push(configuration);

}

LOGGER.debug(responses);

return responses;

}

/**
*
* @function
* @name getServiceConfiguration
* @description Récupération de la configuration d'un service
* @param {string} serviceId - Identifiant du service dont on veut la configuration
* @return {object} response - Contenu du service.json
*
*/

getServiceConfiguration(serviceId) {

LOGGER.info("getServiceConfiguration...");

// On récupère la configuration admin de ce service, s'il existe
const serviceAdminConf = this._configuration.administration.services.find(service => service.id == serviceId);

if (serviceAdminConf) {

LOGGER.debug("Le service " + serviceId + " a été trouvé");
LOGGER.debug(serviceAdminConf);
return this.readServiceConfiguration(serviceAdminConf);

} else {
throw errorManager.createError(`Can't find service ${serviceId}`, 404)
}

}

/**
*
* @function
* @name readServiceConfiguration
* @description Lecture de la configuration d'un service
* @param {object} serviceAdminConf - Configuration du service du point de vue de l'administrateur
* @return {json} configuration - Configuration du service
*
*/

readServiceConfiguration(serviceAdminConf) {

LOGGER.info(`readServiceConfiguration...`);

LOGGER.debug(`Lecture fichier de configuration du service : ${serviceAdminConf.id}`);

try {

const configurationLocation = path.resolve(path.dirname(this._configurationPath), serviceAdminConf.configuration);
LOGGER.debug("Location à lire : " + configurationLocation);

const configuration = JSON.parse(fs.readFileSync(configurationLocation));
LOGGER.debug(configuration);

return configuration;

} catch (error) {
throw errorManager.createError(`Can't read service configuration file : ${error}`, 500);
}

}

}
Expand Down
34 changes: 33 additions & 1 deletion src/js/apis/admin/1.0.0/controller/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const errorManager = require('../../../../utils/errorManager');
const log4js = require('log4js');
const HealthRequest = require('../../../../requests/healthRequest');
const ServiceRequest = require('../../../../requests/serviceRequest');

var LOGGER = log4js.getLogger("CONTROLLER");

Expand All @@ -13,7 +14,7 @@ module.exports = {
* @function
* @name checkHealthParameters
* @description Vérification des paramètres d'une requête sur /health
* @param {object} parameters - ensemble des paramètres de la requête
* @param {object} parameters - ensemble des paramètres de la requête ExpressJS
* @return {object} HealthRequest - Instance de la classe HealthRequest
*
*/
Expand Down Expand Up @@ -78,6 +79,37 @@ module.exports = {

return userResponse;

},

/**
*
* @function
* @name checkServiceParameters
* @description Vérification des paramètres d'une requête sur /services/{service}
* @param {object} parameters - ensemble des paramètres de la requête ExpressJS
* @return {ServiceRequest} request - Instance de la classe ServiceRequest
*
*/

checkServiceParameters: function(parameters) {

LOGGER.debug("checkServiceParameters()");

// Service
if (!parameters.service) {
throw errorManager.createError(" Parameter 'service' is invalid: there is no value", 400);
}

if (parameters.service === "") {
throw errorManager.createError(" Parameter 'service' is invalid: value should not be empty", 400);
}

// TODO : vérifier ici que le service exite (appel à une fonction de la classe administrator)

const request = new ServiceRequest(parameters.service);

return request;

}

}
39 changes: 35 additions & 4 deletions src/js/apis/admin/1.0.0/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ router.route("/health")
// Vérification des paramètres de la requête
const healthRequest = controller.checkHealthParameters(parameters);
LOGGER.debug(healthRequest);
// Envoie au service et récupération de l'objet réponse
// Envoie à l'administrateur et récupération de l'objet réponse
const healthResponse = await administrator.computeHealthRequest(healthRequest);
LOGGER.debug(healthResponse);
// Formattage de la réponse
Expand Down Expand Up @@ -80,15 +80,46 @@ router.route("/services")
// On récupère l'instance d'Administrator pour répondre aux requêtes
let administrator = req.app.get("administrator");

try {

const servicesResponse = administrator.getServicesConfigurations()
res.set('content-type', 'application/json');
res.status(200).json(servicesResponse);

} catch (error) {
return next(error);
}

});

// Services/{service}
// Récupérer les informations d'un service
router.route("/services/:service")

.get(async function(req, res, next) {

LOGGER.debug("requete GET sur /admin/1.0.0/services/:service?");
LOGGER.debug(req.originalUrl);

// On récupère l'instance d'Administrator pour répondre aux requêtes
let administrator = req.app.get("administrator");

// on récupère l'ensemble des paramètres de la requête
let parameters = req.query;
const parameters = req.params;
LOGGER.debug(parameters);

try {

const servicesResponse = administrator.getServicesConfigurations(parameters)
// Vérification des paramètres de la requête
const serviceRequest = controller.checkServiceParameters(parameters);
LOGGER.debug(serviceRequest);

// Envoie à l'administrateur et récupération de l'objet réponse
const serviceResponse = administrator.getServiceConfiguration(serviceRequest.service);

// Formattage de la réponse
res.set('content-type', 'application/json');
res.status(200).json(servicesResponse);
res.status(200).json(serviceResponse);

} catch (error) {
return next(error);
Expand Down
56 changes: 56 additions & 0 deletions src/js/requests/serviceRequest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use strict';

const Request = require('./request');

/**
*
* @class
* @name serviceRequest
* @description Classe modélisant une requête sur un service géré par l'administrateur.
*
*/

module.exports = class serviceRequest extends Request {

/**
*
* @function
* @name constructor
* @description Constructeur de la classe serviceRequest
* @param {string} serviceId - Id du service interrogé
*
*/

constructor(serviceId) {

super("service", "serviceRequest");

// Id du service d'après l'administrateur
this._service = serviceId;

}

/**
*
* @function
* @name get service
* @description Récupérer le caractère verbeux de la requête
*
*/
get service() {
return this._service;
}

/**
*
* @function
* @name set service
* @description Attribuer le caractère verbeux de la requête.
* @param {string} id - Id du service
*
*/
set service(id) {
this._service = id;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"1.0.0": {
"health": "/admin/1.0.0/health",
"version": "/admin/1.0.0/version",
"services": "/admin/1.0.0/services"
"services": "/admin/1.0.0/services",
"services/<service>": "/admin/1.0.0/services/<service>"
}
}
},
Expand Down
19 changes: 19 additions & 0 deletions test/functional/request/cucumber/features/req-admin-1.0.0.feature
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,22 @@ Feature: Road2 with data
When I send the request
Then the server should send a response with status 404
And the response should contain "Not found"

Scenario: [admin/1.0.0] Configuration du service "main"
Given an "GET" request on operation "services/<service>" in api "admin" "1.0.0"
And with path parameters:
| key | value |
| service | main |
When I send the request
Then the server should send a response with status 200
And the response should have an header "content-type" with value "application/json"
And the response should contain "application"

Scenario: [admin/1.0.0] Configuration d'un service inexistant ne marche pas
Given an "GET" request on operation "services/<service>" in api "admin" "1.0.0"
And with path parameters:
| key | value |
| service | other |
When I send the request
Then the server should send a response with status 404
And the response should contain "Can't find service"
4 changes: 4 additions & 0 deletions test/functional/request/cucumber/features/support/steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ Given('with query parameters:', function (table) {
this.setQueryParameters(table.hashes());
});

Given('with path parameters:', function (table) {
this.setPathParameters(table.hashes());
});

Given('with table parameters for {string}:', function (key, table) {
this.setTableParameters(key, table.hashes());
});
Expand Down
10 changes: 10 additions & 0 deletions test/functional/request/cucumber/features/support/world.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,16 @@ class road2World {

}

setPathParameters(parametersToAdd) {

for(let i = 0; i < parametersToAdd.length; i++) {
if (this._path.includes(`<${parametersToAdd[i].key}>`)) {
this._path = this._path.replace(`<${parametersToAdd[i].key}>`, parametersToAdd[i].value)
}
}

}

setTableParameters(key, valuesToAdd) {

let arrayParameters = new Array();
Expand Down
31 changes: 31 additions & 0 deletions test/integration/mocha/requests/integrationServiceRequest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const assert = require('assert');
const ServiceRequest = require('../../../../src/js/requests/serviceRequest');
const logManager = require('../logManager');

describe('Test de la classe ServiceRequest', function() {

before(function() {
// runs before all tests in this block
logManager.manageLogs();
});

let request = new ServiceRequest("test");

describe('Test du constructeur et des getters/setters', function() {

it('Get type', function() {
assert.equal(request.type, "serviceRequest");
});

it('Get service', function() {
assert.equal(request.service, "test");
});

it('Set service', function() {
request.service = "main";
assert.equal(request.service, "main");
});

});

});
Loading

0 comments on commit 0d36022

Please sign in to comment.