Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A problem with custom routes #37

Open
killmenot opened this issue Oct 5, 2018 · 0 comments
Open

A problem with custom routes #37

killmenot opened this issue Oct 5, 2018 · 0 comments

Comments

@killmenot
Copy link

killmenot commented Oct 5, 2018

Motivation

I'd like to add a simple module that provided with healthcheck functionality (actually, it's part of integration testing for ripple qewd microservices).

The module should look very simple:
qewd.js

'use strict';

const qewd = require('qewd').master;
const path = require('path');

const config = {
  managementPassword: 'keepThisSecret!',
  serverName: 'My QEWD Server',
  port: 8080,
  database: {
    type: 'redis'
  }
};
const routes = [
  {
    path: '/',
    module: path.join(__dirname, 'healthcheck')
  }
];

qewd.start(config, routes);

healthcheck.js

function healthcheck(args, finished) {
  finished({
    ok: true,
    timestamp: Date.now()
  });
}

module.exports = {
  restModule: true,

  init: function (application) {
    const routes = [
      {
        url: '/healthcheck',
        method: 'GET',
        handler: healthcheck
      }
    ];

    router.initialise(routes, module.exports);
    router.setErrorResponse(404, 'Not Found');

    this.setCustomErrorResponse.call(this, {
      application: application,
      errorType: 'noTypeHandler',
      text: 'Resource Not Found',
      statusCode: '404'
    });
  }
};

Problem

It returns 404

Investigation

I started to look deeper at the problem to see why such a simple case doesn't work. After research master-express, qewd-router and qx.router logic I found the following:
routes.path is used as first parameter to pass in express middleware app.use the following way

app.use(routes.path, beforeRouter, qx.router(options), afterRouter)

That means routes.path should be / to work correctly (see example with 2 routers on root path). However, this leads to another problem. GET /healthcheck returns {"error":"Missing authorization header"}

Looking at express params I found the following:

{
  "type": "ewd-qoper8-express",
  "path": "/healthcheck",
  "method": "GET",
  "headers": {
    "host": "127.0.0.1:8085",
    "connection": "keep-alive",
    "cache-control": "max-age=0",
    "upgrade-insecure-requests": "1",
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
    "dnt": "1",
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
    "accept-encoding": "gzip, deflate, br",
    "accept-language": "en-US,en;q=0.9,ru;q=0.8,de;q=0.7",
    "cookie": "io=gT4u07XmDNfb7crjAAAF"
  },
  "params": {
    "type": "healthcheck"
  },
  "query": {},
  "body": {},
  "ip": "::ffff:172.17.0.1",
  "ips": []
}

And again there are 2 problems here now

  1. module map looks like {"":"/opt/qewd/healthcheck"} that it's bad
  2. application prop is missed for messageObj and corresponding app handler logic is not called

Solution

  1. Update qewd master module map initialization to use application parameter when path is /
  2. I found that application and expressType parameters are not passed to router here. If we update corresponding master-express and master-koa logic, this problem will be gone.

Now messageObj looks correctly

  1. module map is initialized correctly -> moduleMap":{"healthcheck":"/opt/qewd/healthcheck"}
  2. messageObj looks correctly to be loaded by restModules
{
  "type": "ewd-qoper8-express",
  "path": "/healthcheck",
  "method": "GET",
  "headers": {
    "host": "127.0.0.1:8085",
    "connection": "keep-alive",
    "cache-control": "max-age=0",
    "upgrade-insecure-requests": "1",
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
    "dnt": "1",
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
    "accept-encoding": "gzip, deflate, br",
    "accept-language": "en-US,en;q=0.9,ru;q=0.8,de;q=0.7",
    "cookie": "io=gT4u07XmDNfb7crjAAAF"
  },
  "params": {
    "type": "healthcheck"
  },
  "query": {},
  "body": {},
  "ip": "::ffff:172.17.0.1",
  "ips": [],
  "application": "healthcheck",
  "expressType": "healthcheck"
}

However, the module could not be loaded due to the problem with processing name for handler in qewd-router. This should be patched also. If it be patched for this particular case, all will work. The final healthcheck module code is the following: https://gist.github.com/killmenot/44f03452b04066f97baa28ad91f6e279

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant