diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index 019fca48..761af686 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -1,2 +1,3 @@ - Add: check response obj before use it handling http commands - Upgrade NodeJS version from 8.16.1 to 10.17.0 in Dockerfile due to Node 8 End-of-Life +- Add: /api-docs endpoint providing swagger-based documentation of the HTTP southbound interface \ No newline at end of file diff --git a/docs/usermanual.md b/docs/usermanual.md index a1771a8f..f30a16c3 100644 --- a/docs/usermanual.md +++ b/docs/usermanual.md @@ -193,17 +193,18 @@ Some additional remarks regarding polling commands: MQTT is a machine-to-machine (M2M)/IoT connectivity protocol, focused on a lightweight interaction between peers. MQTT is based on publish-subscribe mechanisms over a hierarchical set of topics defined by the user. -This section specifies the topics and messages allowed when using MQTT as the transport protocol for Ultralight 2.0. All -the topics subscribed by the agent (to send measures, to configuration command retrieval or to get result -of a command) are prefixed with the agent procotol: +This section specifies the topics and messages allowed when using MQTT as the transport protocol for Ultralight 2.0. All +the topics subscribed by the agent (to send measures, to configuration command retrieval or to get result of a command) +are prefixed with the agent procotol: ```text /ul// ``` + where `` is the API Key assigned to the service and `` is the ID of the device. -All topis published by the agent (to send a comamnd or to send configuration information) to a device are not prefixed -by the protocol, in this case '/ul', just include apikey and deviceid (e.g: `/FF957A98/MydeviceId/cmd` and +All topics published by the agent (to send a comamnd or to send configuration information) to a device are not prefixed +by the protocol, in this case `/ul`, just include apikey and deviceid (e.g: `/FF957A98/MydeviceId/cmd` and `/FF957A98/MyDeviceId/configuration/values` ). This transport protocol binding is still under development. @@ -544,3 +545,15 @@ To ensure consistent Markdown formatting run the following: # Use git-bash on Windows npm run prettier:text ``` + +### Swagger + +In order to run Swagger, you need to execute the IoT Agent (as explained [here](installationguide.md#usage) and then you +can access to: + +``` +:7896/api-docs +``` + +The swagger documentation provided at /api-docs covers the HTTP southbound interface of the agent. The northbound HTTP +interface is not covered. diff --git a/lib/bindings/HTTPBindings.js b/lib/bindings/HTTPBindings.js index 89bf31b7..5309ce26 100644 --- a/lib/bindings/HTTPBindings.js +++ b/lib/bindings/HTTPBindings.js @@ -42,7 +42,10 @@ var http = require('http'), context = { op: 'IOTAUL.HTTP.Binding' }, - transport = 'HTTP'; + swaggerUi = require('swagger-ui-express'), + swaggerJSDoc = require('swagger-jsdoc'), + transport = 'HTTP', + packageJSON = require('../../package.json'); function handleError(error, req, res, next) { var code = 500; @@ -406,11 +409,75 @@ function start(callback) { router: express.Router() }; + var options = { + swaggerDefinition: { + info: { + title: 'IoT Agent UL2 - HTTP', // Title (required) + version: packageJSON.version, // Version (required) + description: + 'This documentation explains the POST and GET requests to the route ' + + config.getConfig().iota.defaultResource // Description (not required) + } + }, + apis: ['./lib/bindings/*'] // Path to the API docs + }; + var swaggerSpec = swaggerJSDoc(options); + + httpBindingServer.app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec)); + config.getLogger().info(context, 'HTTP Binding listening on port [%s]', config.getConfig().http.port); httpBindingServer.app.set('port', config.getConfig().http.port); httpBindingServer.app.set('host', config.getConfig().http.host || '0.0.0.0'); + /** + * @swagger + * + * /iot/d: + * get: + * tags: + * - "iot/d" + * summary: "Report new measures" + * description: "A device can report new measures to the + * IoT Platform using an HTTP GET request to the /iot/d path" + * consumes: + * - "application/json" + * produces: + * - "application/json" + * parameters: + * - in: "query" + * name: "i" + * description: "Device ID" + * type: string + * required: true + * - in: "query" + * name: "k" + * description: "API Key for the service the device is registered on" + * type: string + * required: true + * - in: "query" + * name: "d" + * description: "Ultralight 2.0 payload. + * Payloads for GET requests should not contain multiple measure groups" + * type: string + * required: true + * - in: "query" + * name: "t" + * description: "Timestamp of the measure" + * type: timestamp + * required: false + * responses: + * 200: + * description: "The new measure has been registered " + * 404: + * description: 'No device was found with "device_name"' + * DEVICE_GROUP_NOT_FOUND: + * description: "Could not find device group" + * PARSE_ERROR: + * description: 'There was a syntax error in the Ultralight request: + * Unknown error parsing Ultralight 2.0: "syntax_error"' + */ + httpBindingServer.router.get( config.getConfig().iota.defaultResource || constants.HTTP_MEASURE_PATH, checkMandatoryParams(true), @@ -420,6 +487,52 @@ function start(callback) { returnCommands ); + /** + * @swagger + * + * /iot/d: + * post: + * tags: + * - "iot/d" + * summary: "Registrer a new measure" + * description: "This request add a new measure to the datebase." + * operationId: "addDevices" + * consumes: + * - text/plain + * parameters: + * - in: query + * name: "i" + * description: "Device ID" + * type: string + * required: true + * - in: query + * name: "k" + * description: "API key. Service identification." + * type: string + * required: true + * - in: query + * name: "t" + * description: "Date and time of register" + * type: timestamp + * required: false + * - in: body + * name: "Sensors" + * description: 'Sensors Measurements. + * The different sensor values ​​are sent in IoT Agent format. For example: "c|1"' + * type: string + * required: true + * responses: + * 200: + * description: "Report new measures to the IoT Platform" + * 404: + * description: 'DEVICE_NOT_FOUND - No device was found with "device_name"' + * DEVICE_GROUP_NOT_FOUND: + * description: "Could not find device group" + * PARSE_ERROR: + * description: 'There was a syntax error in the + * Ultralight request: Unknown error parsing Ultralight 2.0: "syntax_error"' + */ + httpBindingServer.router.post( config.getConfig().iota.defaultResource || constants.HTTP_MEASURE_PATH, addDefaultHeader, diff --git a/package.json b/package.json index 8a1b52ab..df6def1c 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,8 @@ "textlint-rule-terminology": "~1.1.30", "textlint-rule-write-good": "~1.6.2", "should": "13.2.3", + "swagger-jsdoc": "~3.4.0", + "swagger-ui-express": "~4.1.2", "timekeeper": "2.1.2", "watch": "~1.0.2" },