Browse Source

Update hapi to 20.1.0 (#6355)

- plugin registration code and handlers were refactored to support hapi 20.1.0.
- vision package was upgraded to be compatible with hapi 20.1.0
- mongoose code was updated in order to remove deprecated methods and
  features.
  (useNewUrlParser, useUnifiedTopology, updateOne instead of update)
- mongoose implementation of /queries was not reading all queries from the
  database, causing tests to fail.
Gerik Bonaert 4 years ago
parent
commit
7be3d36e26

+ 2 - 2
frameworks/JavaScript/hapi/README.md

@@ -12,8 +12,8 @@ This is the Hapi portion of a [benchmarking test suite](../) comparing a variety
 
 
 ## Infrastructure Software Versions
 ## Infrastructure Software Versions
 The tests were run with:
 The tests were run with:
-* [Node.js v7.5.0](http://nodejs.org/)
-* [Hapi 16.1.0](http://hapijs.com/)
+* [Node.js v14.15.1](http://nodejs.org/)
+* [Hapi 20.1.0](http://hapijs.com/)
 
 
 ## Resources
 ## Resources
 * http://nodejs.org/api/cluster.html
 * http://nodejs.org/api/cluster.html

+ 45 - 41
frameworks/JavaScript/hapi/create-server.js

@@ -3,54 +3,58 @@
  * working implementation for the benchmark suite.
  * working implementation for the benchmark suite.
  */
  */
 
 
-const Hapi = require('hapi');
-const Vision = require('vision');
+const Hapi = require('@hapi/hapi');
+const Vision = require('@hapi/vision');
 
 
 const options = {
 const options = {
-  connections: {
-    compression: false
-  }
+  port: process.env.PORT || 8080, 
+  host: '0.0.0.0',
+  compression: false
 };
 };
 
 
-const server = new Hapi.Server(options);
+const server = new Hapi.server(options);
 
 
-server.connection({port: process.env.PORT || 8080, host: '0.0.0.0'});
-server.register(Vision, (err) => {
-    if (err) {
-        throw err;
-    }
-
-    server.views({
-        engines: { html: require('handlebars') },
-        path: __dirname + '/views/'
-    });
-});
-
-const Handler = require(`./handlers/${process.env.NODE_HANDLER}`);
-
-// Makes routing simpler as tfb routes are all GET's
-// We also don't use the nifty route features that Hapi has
-// to offer such as attaching a validator
-const Route = (path, handler) =>
-  server.route({ method: 'GET', path, handler });
+const provision = async () => {
 
 
-const JsonSerialization = (req, reply) =>
-  reply({ message: 'Hello, World!' }).header('Server', 'hapi');
-
-const Plaintext = (req, reply) =>
-  reply('Hello, World!')
-    .header('Server', 'hapi')
-    .header('Content-Type', 'text/plain');
+  await server.register({
+    plugin: Vision,
+    options: {
+      engines: { html: require('handlebars') },
+      path: __dirname + '/views/'
+    }
+  })
+  
+  const Handler = require(`./handlers/${process.env.NODE_HANDLER}`);
+
+  // Makes routing simpler as tfb routes are all GET's
+  // We also don't use the nifty route features that Hapi has
+  // to offer such as attaching a validator
+  const Route = (path, handler) =>
+    server.route({ method: 'GET', path, handler });
+  
+  const JsonSerialization = (request, h) =>
+    h.response({ message: 'Hello, World!' }).header('Server', 'hapi');
+  
+  const Plaintext = (request, h) =>
+    h.response('Hello, World!')
+      .header('Server', 'hapi')
+      .header('Content-Type', 'text/plain');
+  
+  
+  Route('/json', JsonSerialization);
+  Route('/plaintext', Plaintext);
+  
+  Route('/db', Handler.SingleQuery);
+  Route('/queries', Handler.MultipleQueries);
+  Route('/fortunes', Handler.Fortunes);
+  Route('/updates', Handler.Updates);
+
+  await server.start();
 
 
+  console.log('Hapi worker started and listening on ' + server.info.uri + " "
+    + new Date().toISOString(" "));
+}
 
 
-Route('/json', JsonSerialization);
-Route('/plaintext', Plaintext);
+provision()
 
 
-Route('/db', Handler.SingleQuery);
-Route('/queries', Handler.MultipleQueries);
-Route('/fortunes', Handler.Fortunes);
-Route('/updates', Handler.Updates);
 
 
-server.start((err) =>
-  console.log('Hapi worker started and listening on ' + server.info.uri + " "
-    + new Date().toISOString(" ")));

+ 22 - 18
frameworks/JavaScript/hapi/handlers/mongoose.js

@@ -1,9 +1,9 @@
 // Connects to MongoDB using the mongoose driver
 // Connects to MongoDB using the mongoose driver
 // Handles related routes
 // Handles related routes
 
 
-const h = require('../helper');
+const helper = require('../helper');
 const Mongoose = require('mongoose');
 const Mongoose = require('mongoose');
-Mongoose.connect('mongodb://tfb-database/hello_world');
+Mongoose.connect('mongodb://tfb-database/hello_world', { useNewUrlParser: true, useUnifiedTopology: true });
 
 
 const WorldSchema = new Mongoose.Schema({
 const WorldSchema = new Mongoose.Schema({
   id: Number,
   id: Number,
@@ -22,52 +22,56 @@ const FortuneSchema = new Mongoose.Schema({
 const Worlds = Mongoose.model('world', WorldSchema);
 const Worlds = Mongoose.model('world', WorldSchema);
 const Fortunes = Mongoose.model('fortune', FortuneSchema);
 const Fortunes = Mongoose.model('fortune', FortuneSchema);
 
 
-const randomWorld = async () =>
-  await Worlds.findOne({ id: h.randomTfbNumber() });
+const randomWorld = () => Worlds.findOne({ id: helper.randomTfbNumber() });
 
 
 const updateWorld = async (world) =>
 const updateWorld = async (world) =>
-  await Worlds.update(
+  await Worlds.updateOne(
     { id: world.randomNumber },
     { id: world.randomNumber },
     { randomNumber: world.randomNumber }
     { randomNumber: world.randomNumber }
   );
   );
 
 
 module.exports = {
 module.exports = {
 
 
-  SingleQuery: async (req, reply) => {
-    reply(await randomWorld()).header('Server', 'hapi');
+  SingleQuery: async (request, h) => {
+    return h.response(await randomWorld()).header('Server', 'hapi');
   },
   },
 
 
-  MultipleQueries: async (req, reply) => {
-    const queries = h.getQueries(req);
-    const results = h.fillArray(await randomWorld(), queries);
+  MultipleQueries: async (request, h) => {
+    const queries = helper.getQueries(request);
+    const results = [];
+
+    for (let i = 0; i < queries; i++) {
+      results.push(await randomWorld());
+    }
+
 
 
-    reply(results).header('Server', 'hapi');
+    return h.response(results).header('Server', 'hapi');
   },
   },
 
 
-  Fortunes: async (req, reply) => {
+  Fortunes: async (request, h) => {
     const fortunes = await Fortunes.find();
     const fortunes = await Fortunes.find();
-    fortunes.push(h.additionalFortune());
+    fortunes.push(helper.additionalFortune());
     fortunes.sort((a, b) => a.message.localeCompare(b.message));
     fortunes.sort((a, b) => a.message.localeCompare(b.message));
 
 
-    reply.view('fortunes', {
+    return h.view('fortunes', {
       fortunes: fortunes
       fortunes: fortunes
     })
     })
       .header('Content-Type', 'text/html')
       .header('Content-Type', 'text/html')
       .header('Server', 'hapi');
       .header('Server', 'hapi');
   },
   },
 
 
-  Updates: async (req, reply) => {
-    const queries = h.getQueries(req);
+  Updates: async (request, h) => {
+    const queries = helper.getQueries(request);
     const results = [];
     const results = [];
 
 
     for (let i = 0; i < queries; i++) {
     for (let i = 0; i < queries; i++) {
       const world = await randomWorld();
       const world = await randomWorld();
-      world.randomNumber = h.randomTfbNumber();
+      world.randomNumber = helper.randomTfbNumber();
       await updateWorld(world);
       await updateWorld(world);
       results.push(world);
       results.push(world);
     }
     }
 
 
-    reply(results)
+    return h.response(results)
       .header('Content-Type', 'application/json')
       .header('Content-Type', 'application/json')
       .header('Server', 'hapi');
       .header('Server', 'hapi');
   }
   }

+ 23 - 18
frameworks/JavaScript/hapi/handlers/sequelize-postgres.js

@@ -1,7 +1,7 @@
 // Connects to Postgres using the sequelize driver
 // Connects to Postgres using the sequelize driver
 // Handles related routes
 // Handles related routes
 
 
-const h = require('../helper');
+const helper = require('../helper');
 
 
 const Sequelize = require('sequelize');
 const Sequelize = require('sequelize');
 const sequelize = new Sequelize('hello_world', 'benchmarkdbuser', 'benchmarkdbpass', {
 const sequelize = new Sequelize('hello_world', 'benchmarkdbuser', 'benchmarkdbpass', {
@@ -32,53 +32,58 @@ const Fortunes = sequelize.define('fortune', {
     freezeTableName: true
     freezeTableName: true
   });
   });
 
 
-const randomWorld = async () =>
-  await Worlds.findOne({ where: { id: h.randomTfbNumber() } });
+const randomWorld = () => Worlds.findOne({ where: { id: helper.randomTfbNumber() } });
 
 
 module.exports = {
 module.exports = {
 
 
-  SingleQuery: (req, reply) => {
-    reply(randomWorld())
+  SingleQuery: async (request, h) => {
+    return h.response(await randomWorld())
       .header('Content-Type', 'application/json')
       .header('Content-Type', 'application/json')
       .header('Server', 'hapi');
       .header('Server', 'hapi');
   },
   },
 
 
-  MultipleQueries: async (req, reply) => {
-    const queries = h.getQueries(req);
+  MultipleQueries: async (request, h) => {
+    const queries = helper.getQueries(request);
     const results = [];
     const results = [];
 
 
     for (let i = 0; i < queries; i++) {
     for (let i = 0; i < queries; i++) {
       results.push(await randomWorld());
       results.push(await randomWorld());
     }
     }
 
 
-    reply(results)
+    return h.response(results)
       .header('Content-Type', 'application/json')
       .header('Content-Type', 'application/json')
       .header('Server', 'hapi');
       .header('Server', 'hapi');
   },
   },
 
 
-  Fortunes: (req, reply) => {
-    Fortunes.findAll().then((fortunes) => {
-      fortunes.push(h.additionalFortune());
+  Fortunes: async (request, h) => {
+    try {
+      const fortunes = await Fortunes.findAll()
+      fortunes.push(helper.additionalFortune());
       fortunes.sort((a, b) => a.message.localeCompare(b.message));
       fortunes.sort((a, b) => a.message.localeCompare(b.message));
 
 
-      reply.view('fortunes', { fortunes })
+      return h.view('fortunes', { fortunes })
         .header('Content-Type', 'text/html')
         .header('Content-Type', 'text/html')
         .header('Server', 'hapi');
         .header('Server', 'hapi');
-    }).catch((err) => process.exit(1));
+    } catch (err) {
+      process.exit(1)
+    }
   },
   },
 
 
-  Updates: async (req, reply) => {
-    const queries = h.getQueries(req);
+  Updates: async (request, h) => {
+    const queries = helper.getQueries(request);
     const results = [];
     const results = [];
 
 
     for (let i = 0; i < queries; i++) {
     for (let i = 0; i < queries; i++) {
       const world = await randomWorld();
       const world = await randomWorld();
-      await world.set('randomnumber', h.randomTfbNumber());
-      await world.save();
+      world.randomnumber = helper.randomTfbNumber();
+      await Worlds.update(
+        { randomnumber: world.randomnumber },
+        { where: { id: world.id } }
+      );
       results.push(world);
       results.push(world);
     }
     }
 
 
-    reply(results)
+    return h.response(results)
       .header('Content-Type', 'application/json')
       .header('Content-Type', 'application/json')
       .header('Server', 'hapi');
       .header('Server', 'hapi');
   }
   }

+ 19 - 17
frameworks/JavaScript/hapi/handlers/sequelize.js

@@ -1,7 +1,7 @@
 // Connects to MySQL using the sequelize driver
 // Connects to MySQL using the sequelize driver
 // Handles related routes
 // Handles related routes
 
 
-const h = require('../helper');
+const helper = require('../helper');
 
 
 const Sequelize = require('sequelize');
 const Sequelize = require('sequelize');
 const sequelize = new Sequelize('hello_world', 'benchmarkdbuser', 'benchmarkdbpass', {
 const sequelize = new Sequelize('hello_world', 'benchmarkdbuser', 'benchmarkdbpass', {
@@ -32,48 +32,50 @@ const Fortunes = sequelize.define('Fortune', {
     freezeTableName: true
     freezeTableName: true
   });
   });
 
 
-const randomWorld = async () =>
-  await Worlds.findOne({ where: { id: h.randomTfbNumber() } });
+const randomWorld = () => Worlds.findOne({ where: { id: helper.randomTfbNumber() } });
 
 
 module.exports = {
 module.exports = {
 
 
-  SingleQuery: (req, reply) => {
-    reply(randomWorld())
+  SingleQuery: async (request, h) => {
+    return h.response(await randomWorld())
       .header('Content-Type', 'application/json')
       .header('Content-Type', 'application/json')
       .header('Server', 'hapi');
       .header('Server', 'hapi');
   },
   },
 
 
-  MultipleQueries: async (req, reply) => {
-    const queries = h.getQueries(req);
+  MultipleQueries: async (request, h) => {
+    const queries = helper.getQueries(request);
     const results = [];
     const results = [];
 
 
     for (let i = 0; i < queries; i++) {
     for (let i = 0; i < queries; i++) {
       results.push(await randomWorld());
       results.push(await randomWorld());
     }
     }
 
 
-    reply(results)
+    return h.response(results)
       .header('Content-Type', 'application/json')
       .header('Content-Type', 'application/json')
       .header('Server', 'hapi');
       .header('Server', 'hapi');
   },
   },
 
 
-  Fortunes: (req, reply) => {
-    Fortunes.findAll().then((fortunes) => {
-      fortunes.push(h.additionalFortune());
+  Fortunes: async (request, h) => {
+    try {
+      const fortunes = await Fortunes.findAll()
+      fortunes.push(helper.additionalFortune());
       fortunes.sort((a, b) => a.message.localeCompare(b.message));
       fortunes.sort((a, b) => a.message.localeCompare(b.message));
 
 
-      reply.view('fortunes', { fortunes })
+      return h.view('fortunes', { fortunes })
         .header('Content-Type', 'text/html')
         .header('Content-Type', 'text/html')
         .header('Server', 'hapi');
         .header('Server', 'hapi');
-    }).catch((err) => process.exit(1));
+    } catch (err) {
+      process.exit(1)
+    }
   },
   },
 
 
-  Updates: async (req, reply) => {
-    const queries = h.getQueries(req);
+  Updates: async (request, h) => {
+    const queries = helper.getQueries(request);
     const results = [];
     const results = [];
 
 
     for (let i = 0; i < queries; i++) {
     for (let i = 0; i < queries; i++) {
       const world = await randomWorld();
       const world = await randomWorld();
-      world.randomNumber = h.randomTfbNumber();
+      world.randomNumber = helper.randomTfbNumber();
       await Worlds.update(
       await Worlds.update(
         { randomNumber: world.randomNumber },
         { randomNumber: world.randomNumber },
         { where: { id: world.id } }
         { where: { id: world.id } }
@@ -81,7 +83,7 @@ module.exports = {
       results.push(world);
       results.push(world);
     }
     }
 
 
-    reply(results)
+    return h.response(results)
       .header('Content-Type', 'application/json')
       .header('Content-Type', 'application/json')
       .header('Server', 'hapi');
       .header('Server', 'hapi');
   }
   }

+ 0 - 9
frameworks/JavaScript/hapi/helper.js

@@ -1,15 +1,6 @@
 module.exports = {
 module.exports = {
   randomTfbNumber: () => Math.floor(Math.random() * 10000) + 1,
   randomTfbNumber: () => Math.floor(Math.random() * 10000) + 1,
 
 
-  fillArray: (value, len) => {
-    const filled = [];
-
-    for (let i = 0; i < len; i++) {
-      filled.push(value);
-    }
-    return filled;
-  },
-
   getQueries: (req) => {
   getQueries: (req) => {
     let queries = ~~(req.query.queries) || 1;
     let queries = ~~(req.query.queries) || 1;
     queries = Math.min(Math.max(queries, 1), 500);
     queries = Math.min(Math.max(queries, 1), 500);

+ 3 - 3
frameworks/JavaScript/hapi/package.json

@@ -3,12 +3,12 @@
   "version": "0.0.1",
   "version": "0.0.1",
   "private": true,
   "private": true,
   "dependencies": {
   "dependencies": {
+    "@hapi/hapi": "20.1.0",
+    "@hapi/vision": "6.0.1",
     "async": "2.1.5",
     "async": "2.1.5",
     "bluebird": "3.4.7",
     "bluebird": "3.4.7",
     "handlebars": "4.3.0",
     "handlebars": "4.3.0",
-    "hapi": "16.1.1",
-    "vision": "4.1.0",
-    "mongoose": "5.7.5",
+    "mongoose": "5.11.15",
     "mysql": "2.16.0",
     "mysql": "2.16.0",
     "mysql2": "1.6.5",
     "mysql2": "1.6.5",
     "pg": "8.5.1",
     "pg": "8.5.1",