jhipster / generator-jhipster-nodejs

A NodeJS blueprint that creates the backend using NestJS
https://www.npmjs.com/package/generator-jhipster-nodejs
Apache License 2.0
258 stars 79 forks source link

Node JS microservice is not registered properly in Jhipster Registry #103

Closed ajoysinhactc closed 4 years ago

ajoysinhactc commented 4 years ago

Describe the bug NodeJS microservices is not registered properly in Jhipster Registry

To Reproduce

Screenshot attached

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior

usermicroservice:<> should bedisplayed

Screenshots

image

ghost commented 4 years ago

Hi @ajoysinhactc , thanks for your feedback! The feature that you want, maybe is not implemented yet. But, we can do it in the next release. Could you please add your yo-rc.json to get more information? Thanks

ajoysinhactc commented 4 years ago

yo-rc.json addaed as requested

{
  "generator-jhipster": {
    "databaseType": "sql",
    "devDatabaseType": "mysql",
    "enableHibernateCache": true,
    "enableSwaggerCodegen": false,
    "enableTranslation": false,
    "jhiPrefix": "jhi",
    "languages": ["en"],
    "messageBroker": false,
    "nativeLanguage": "en",
    "packageName": "com.app.services.user",
    "packageFolder": "com/app/services/user",
    "prodDatabaseType": "mysql",
    "searchEngine": false,
    "serviceDiscoveryType": "eureka",
    "skipClient": true,
    "testFrameworks": [],
    "websocket": false,
    "baseName": "usermicroservice",
    "applicationType": "microservice",
    "serverPort": "8181",
    "authenticationType": "jwt",
    "skipUserManagement": true,
    "jhipsterVersion": "6.6.0",
    "buildTool": "maven",
    "clientPackageManager": "npm",
    "cacheProvider": "hazelcast",
    "creationTimestamp": 1579672609443,
    "entitySuffix": "",
    "dtoSuffix": "DTO",
    "otherModules": [
      {
        "name": "generator-jhipster-nodejs",
        "version": "1.0.0-beta.2"
      }
    ],
    "blueprints": [
      {
        "name": "generator-jhipster-nodejs",
        "version": "1.0.0-beta.2"
      }
    ]
  },
  "entities": ["Manager", "Customer", "UserPassword", "CustomerProfile"],
  "generator-jhipster-nodejs": {
    "jhipsterVersion": "6.6.0",
    "applicationType": "microservice",
    "baseName": "usermicroservice",
    "packageName": "com.jhipster.node",
    "packageFolder": "com/jhipster/node",
    "serverPort": "8181",
    "authenticationType": "jwt",
    "cacheProvider": "no",
    "enableHibernateCache": false,
    "websocket": false,
    "databaseType": "sql",
    "devDatabaseType": "sqlite",
    "prodDatabaseType": "mysql",
    "searchEngine": false,
    "messageBroker": false,
    "serviceDiscoveryType": false,
    "buildTool": "maven",
    "enableSwaggerCodegen": false,
    "jwtSecretKey": "YTg5YzM2ZTMyM2U2NDdjYzY3MmQzNmI1ZTA0NjE5ZjMzN2QzZDU0NDBiMTU1ZmM4NWUwZjU0ODQ2Y2VjYTkwNzYyNjhkNWJmMDQ2YjMyNjUxOTQzNDFmMGFjNDExMzI5MThlZGIwZWE1N2E4YTM2YzFjNjIwMDBlNDZmODYxOWQ=",
    "enableTranslation": true,
    "embeddableLaunchScript": false
  }
}
ghost commented 4 years ago

Thanks. Please attention that you are using an old version of the nodejs blueprint (1.0.0-beta.2).

jlopezjuy commented 4 years ago

@amanganiello90 Hi, my name is Juan, im from Jujuy Argentina, I have a question with nhipster microservices, when i create a microservice this create user and roles, it's ok? on jhipster microservice this entities don't created. Could you help me? In mi case, i have two microservices and one gateway, i have loged in ok on gateway, but when im trying to get info from other microservice passing jwt token, i have this error message "user does not exist"

ghost commented 4 years ago

Hi @jlopezjuy, thanks for the interest! Yes, there are roles and users created according this seed file as jhipster standard, executed in the microservice startup. However this issue is not the topic of your question. Please add on gitter or open another issue. Thanks.

jlopezjuy commented 4 years ago

I have the same error like Ajoy

{
  "generator-jhipster": {
    "jhipsterVersion": "6.8.0",
    "applicationType": "gateway",
    "baseName": "gateway",
    "packageName": "com.jhipster.node",
    "packageFolder": "com/jhipster/node",
    "serverPort": "8080",
    "authenticationType": "jwt",
    "cacheProvider": "no",
    "enableHibernateCache": false,
    "websocket": false,
    "databaseType": "sql",
    "devDatabaseType": "sqlite",
    "prodDatabaseType": "mysql",
    "searchEngine": false,
    "messageBroker": false,
    "serviceDiscoveryType": false,
    "buildTool": "maven",
    "enableSwaggerCodegen": false,
    "embeddableLaunchScript": false,
    "useSass": true,
    "clientPackageManager": "npm",
    "clientFramework": "angularX",
    "clientTheme": "none",
    "clientThemeVariant": "",
    "creationTimestamp": 1599004988219,
    "testFrameworks": [],
    "jhiPrefix": "jhi",
    "entitySuffix": "",
    "dtoSuffix": "DTO",
    "otherModules": [
      {
        "name": "generator-jhipster-nodejs",
        "version": "1.1.0"
      }
    ],
    "enableTranslation": false,
    "blueprints": [
      {
        "name": "generator-jhipster-nodejs",
        "version": "1.1.0"
      }
    ],
    "promptValues": {
      "microservicePath": "/home/jlopezjuy/Proyectos/Bintelligence/TestMicros/documentos"
    }
  }
}
App | Instance ID | Status
-- | -- | --
DOCUMENTOS | documentos:undefined | UP
GATEWAY | gateway:undefined | UP

2020-09-16 23:09:46.387 DEBUG 31587 --- [ry-scheduling-1] i.g.j.r.service.ZuulUpdaterService       : Enter: updateZuulRoutes() with argument[s] = []
2020-09-16 23:09:46.387 DEBUG 31587 --- [ry-scheduling-1] i.g.j.r.service.ZuulUpdaterService       : Checking instance gateway:undefined - null 
2020-09-16 23:09:46.388 DEBUG 31587 --- [ry-scheduling-1] i.g.j.r.service.ZuulUpdaterService       : Instance 'gateway:undefined' already registered
2020-09-16 23:09:46.388 ERROR 31587 --- [ry-scheduling-1] i.g.j.r.service.ZuulUpdaterService       : Exception in updateZuulRoutes() with cause = 'NULL' and exception = 'null'

java.lang.NullPointerException: null
    at io.github.jhipster.registry.service.ZuulUpdaterService.updateZuulRoutes(ZuulUpdaterService.java:66)
    at io.github.jhipster.registry.service.ZuulUpdaterService$$FastClassBySpringCGLIB$$534967d0.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
ghost commented 4 years ago

i solved this NullPointerException problem by adding "homePageUrl" in instance object in my case :

       instance: {
            hostName: ip.address(),
            instanceId: `${appName}:${serviceID}`,
            vipAddress: `${appName}`,
            app: `${appName.toUpperCase()}`,
            ipAddr: ip.address(),
            status: `UP`,
            port: {
                $: port,
                "@enabled": true
            },
            homePageUrl: `http://${ip.address()}:${port}/`,
            dataCenterInfo: {
                "@class": `com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo`,
                name: `MyOwn`
            }
        } 
ghost commented 4 years ago

@OmidPoorali Thanks for the suggestion! I have reported your fix on the https://github.com/jhipster/generator-jhipster-nodejs/tree/feature/issue-103

Could you test it with a generation? Thanks

jlopezjuy commented 4 years ago

Hi in my case i add status: 'UP',

instance: {
        app: config.get('eureka.instance.appname').toUpperCase(),
        instanceId: config.get('eureka.instance.instanceId'),
        hostName: config.get('ipAddress') || 'localhost',
        ipAddr: config.get('ipAddress') || '127.0.0.1',
        status: 'UP',
        port: {
          $: port,
          '@enabled': 'true'
        },
        vipAddress: config.get('eureka.instance.appname'),
        statusPageUrl: `http://${config.get('ipAddress')}:${port}/`,
        dataCenterInfo: {
          '@class': 'com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo',
          name: 'MyOwn'
        }
      },
ghost commented 4 years ago

@jlopezjuy yes, maybe status up is already the default (if not defined). But homePageUrl could be mandatory

jlopezjuy commented 4 years ago
Here my main.ts
require('dotenv').config({ path: '.env' });
import { NestFactory } from '@nestjs/core';
import cloudConfigClient from 'cloud-config-client';
import { AppModule } from './app.module';
import { setupSwagger } from './swagger';
import { config } from './config';
import { Logger, ValidationPipe, BadRequestException } from '@nestjs/common';
import * as express from 'express';
import * as path from 'path';
import * as fs from 'fs';
const logger: Logger = new Logger('Main');
const port = process.env.NODE_SERVER_PORT || config.get('server.port');
const useJHipsterRegistry = config.get('eureka.client.enabled');

async function bootstrap(): Promise<void> {
  loadCloudConfig();
  registerAsEurekaService();

  const appOptions = { cors: true };
  const app = await NestFactory.create(AppModule, appOptions);
  app.useGlobalPipes(
    new ValidationPipe({
      exceptionFactory: (): BadRequestException => new BadRequestException('Validation error')
    })
  );

  const staticClientPath = path.join(__dirname, '../dist/classes/static');
  if (fs.existsSync(staticClientPath)) {
    app.use(express.static(staticClientPath));
    logger.log(`Serving static client resources on ${staticClientPath}`);
  } else {
    logger.log(`No client it has been found`);
  }

  setupSwagger(app);

  await app.listen(port);
  logger.log(`Application listening on port ${port}`);
}

async function loadCloudConfig(): Promise<void> {
  if (useJHipsterRegistry) {
    const endpoint = config.get('cloud.config.uri') || 'http://admin:admin@localhost:8761/config';
    logger.log(`Loading cloud config from ${endpoint}`);

    const cloudConfig = await cloudConfigClient.load({
      context: process.env,
      endpoint,
      name: config.get('cloud.config.name'),
      profiles: config.get('cloud.config.profile') || ['prod'],
      auth: {
        user: 'admin',
        pass: 'admin'
      }
    });
    config.addAll(cloudConfig.properties);
  }
}

function registerAsEurekaService(): void {
  if (useJHipsterRegistry) {
    logger.log(`Registering with eureka ${config.get('cloud.config.uri')}`);
    const Eureka = require('eureka-js-client').Eureka;
    const eurekaUrl = require('url').parse(config.get('cloud.config.uri'));
    const client = new Eureka({
      instance: {
        app: config.get('eureka.instance.appname').toUpperCase(),
        instanceId: config.get('eureka.instance.instanceId'),
        hostName: config.get('ipAddress') || 'localhost',
        ipAddr: config.get('ipAddress') || '127.0.0.1',
        status: 'UP',
        port: {
          $: port,
          '@enabled': 'true'
        },
        vipAddress: config.get('eureka.instance.appname'),
        statusPageUrl: `http://${config.get('ipAddress')}:${port}/`,
        homePageUrl: `http://${config.get('ipAddress')}:${port}/`,
        dataCenterInfo: {
          '@class': 'com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo',
          name: 'MyOwn'
        }
      },
      eureka: {
        // eureka server host / port
        host: eurekaUrl.hostname || '127.0.0.1',
        port: eurekaUrl.port || 8761,
        servicePath: '/eureka/apps'
      },
      requestMiddleware: (requestOpts, done): any => {
        requestOpts.auth = {
          user: 'admin',
          password: 'admin'
        };
        done(requestOpts);
      }
    });
    client.logger.level('debug');
    client.start(error => logger.log(error || 'Eureka registration complete'));
  }
}

bootstrap();
ghost commented 4 years ago

@jlopezjuy could you try a new generation using the branch https://github.com/jhipster/generator-jhipster-nodejs/tree/feature/issue-103? Please check if it works. Thanks

jlopezjuy commented 4 years ago

ok, I'll chek. off-topic question, did you use this configuration? "client.getInstancesByAppId" to communicate directly every micro service?

ghost commented 4 years ago

ok, I'll chek. off-topic question, did you use this configuration? "client.getInstancesByAppId" to communicate directly every micro service?

I don't know if it is used because the eureka feature is been done by a contributor that tested it. I haven't experience on that usage. So every contribution to improve that is welcome 💯 .

jlopezjuy commented 4 years ago

ok, did you have npm command to install feature 103?

ghost commented 4 years ago

ok, did you have npm command to install feature 103?

Follow the steps to install locally the generator from the repository: https://github.com/jhipster/generator-jhipster-nodejs#-steps-to-develop-a-generator-feature-and-test-it

jlopezjuy commented 4 years ago

great, tnks

jlopezjuy commented 4 years ago

i have this error: @amanganiello90

 ✘ jlopezjuy@juan-Rog  /media/jlopezjuy/Datos/proyectos/jhipsterNodejs/test-generation  nhipster
INFO! Using JHipster version installed locally in current project's node_modules
INFO! No custom sharedOptions found within blueprint: generator-jhipster-nodejs at /home/jlopezjuy/.nvm/versions/node/v12.18.2/lib/node_modules/generator-jhipster-nodejs
INFO! No custom commands found within blueprint: generator-jhipster-nodejs at /home/jlopezjuy/.nvm/versions/node/v12.18.2/lib/node_modules/generator-jhipster-nodejs
INFO! Error parsing options for generator jhipster-nodejs:app, unknown option will lead to error at jhipster 7
INFO! Error parsing options for generator jhipster-nodejs:entity, unknown option will lead to error at jhipster 7
INFO! Error parsing options for generator jhipster-nodejs:languages, unknown option will lead to error at jhipster 7
INFO! Error parsing options for generator jhipster-nodejs:spring-service, unknown option will lead to error at jhipster 7
INFO! Error parsing options for generator jhipster-nodejs:spring-controller, unknown option will lead to error at jhipster 7
INFO! Executing jhipster:app
     info Using blueprint generator-jhipster-nodejs for app subgenerator
WARNING! Deprecated: JHipster seems to be invoked using Yeoman command. Please use the JHipster CLI. Run jhipster <command> instead of yo jhipster:<command>

 ███╗   ██╗ ██╗   ██╗ ████████╗ ███████╗   ██████╗ ████████╗ ████████╗ ███████╗
 ████╗  ██║ ██║   ██║ ╚══██╔══╝ ██╔═══██╗ ██╔════╝ ╚══██╔══╝ ██╔═════╝ ██╔═══██╗
 ██╔██╗ ██║ ████████║    ██║    ███████╔╝ ╚█████╗     ██║    ██████╗   ███████╔╝
 ██║╚██╗██║ ██╔═══██║    ██║    ██╔════╝   ╚═══██╗    ██║    ██╔═══╝   ██╔══██║
 ██║ ╚████║ ██║   ██║ ████████╗ ██║       ██████╔╝    ██║    ████████╗ ██║  ╚██╗
 ╚═╝  ╚═══╝ ╚═╝   ╚═╝ ╚═══════╝ ╚═╝       ╚═════╝     ╚═╝    ╚═══════╝ ╚═╝   ╚═╝

                            https://www.jhipster.tech

Welcome to NHipster (Jhipster NodeJS Official Blueprint) v1.2.0
This blueprint generates your backend in NodeJS with NestJS framework
 _______________________________________________________________________________________________________________

  For any questions or improvements refer to the stream lead at https://github.com/amanganiello90
  If you find NHipster useful, support and star the project at https://github.com/jhipster/generator-jhipster-nodejs
 _______________________________________________________________________________________________________________

 This NodeJS blueprint use these following configurations:

 1. NestJS Framework with swagger doc

 2. JWT or OAuth2 Passport security authentication

 3. TypeORM usage with SQLite development database and versioning/migration

 4. Initial load data seed with users (using auth roles) integrated with the angular/react client

 5. Eureka JS client registry

WARNING! Could not retrieve version of JHipster declared by blueprint 'generator-jhipster-nodejs'
 ______________________________________________________________________________

  JHipster update available: 6.10.3 (current: 6.8.0)

  Run npm install -g generator-jhipster to update.

 ______________________________________________________________________________

? Which *type* of application would you like to create? Microservice application
? What is the base name of your application? testms
events.js:292
      throw er; // Unhandled 'error' event
      ^

TypeError: Cannot read property 'call' of undefined
    at JHipsterAppGenerator.setupSharedOptions (/media/jlopezjuy/Datos/proyectos/jhipsterNodejs/generator-jhipster/generators/generator-base.js:2122:33)
    at JHipsterAppGenerator.setupServerOptions (/media/jlopezjuy/Datos/proyectos/jhipsterNodejs/generator-jhipster/generators/generator-base.js:2151:14)
    at new module.exports (/media/jlopezjuy/Datos/proyectos/jhipsterNodejs/generator-jhipster-nodejs/generators/server/index.js:21:19)
    at Environment.instantiate (/media/jlopezjuy/Datos/proyectos/jhipsterNodejs/generator-jhipster/node_modules/yeoman-environment/lib/environment.js:673:23)
    at instantiate (/media/jlopezjuy/Datos/proyectos/jhipsterNodejs/generator-jhipster-nodejs/node_modules/yeoman-generator/lib/index.js:811:23)
    at module.exports.composeWith (/media/jlopezjuy/Datos/proyectos/jhipsterNodejs/generator-jhipster-nodejs/node_modules/yeoman-generator/lib/index.js:840:33)
    at module.exports.composeServer (/media/jlopezjuy/Datos/proyectos/jhipsterNodejs/generator-jhipster-nodejs/generators/app/index.js:124:22)
    at Object.<anonymous> (/media/jlopezjuy/Datos/proyectos/jhipsterNodejs/generator-jhipster-nodejs/node_modules/yeoman-generator/lib/index.js:647:25)
    at /media/jlopezjuy/Datos/proyectos/jhipsterNodejs/generator-jhipster-nodejs/node_modules/run-async/index.js:49:25
    at new Promise (<anonymous>)
Emitted 'error' event on  instance at:
    at Immediate.<anonymous> (/media/jlopezjuy/Datos/proyectos/jhipsterNodejs/generator-jhipster-nodejs/node_modules/yeoman-generator/lib/index.js:668:20)
    at processImmediate (internal/timers.js:456:21)
    at process.topLevelDomainCallback (domain.js:137:15)
ghost commented 4 years ago

Hi @jlopezjuy , try to perform the following under generator-jhipster repository:

git checkout v6.8.0

jlopezjuy commented 4 years ago

Here's the new main.ts using feature 103: @amanganiello90

require('dotenv').config({ path: '.env' });
import { NestFactory } from '@nestjs/core';
import cloudConfigClient from 'cloud-config-client';
import { AppModule } from './app.module';
import { setupSwagger } from './swagger';
import { config } from './config';
import { Logger, ValidationPipe, BadRequestException } from '@nestjs/common';
import * as express from 'express';
import * as path from 'path';
import * as fs from 'fs';
const logger: Logger = new Logger('Main');
const port = process.env.NODE_SERVER_PORT || config.get('server.port');
const useJHipsterRegistry = config.get('eureka.client.enabled');

async function bootstrap(): Promise<void> {
  loadCloudConfig();
  registerAsEurekaService();

  const appOptions = { cors: true };
  const app = await NestFactory.create(AppModule, appOptions);
  app.useGlobalPipes(
    new ValidationPipe({
      exceptionFactory: (): BadRequestException => new BadRequestException('Validation error')
    })
  );

  const staticClientPath = path.join(__dirname, '../dist/classes/static');
  if (fs.existsSync(staticClientPath)) {
    app.use(express.static(staticClientPath));
    logger.log(`Serving static client resources on ${staticClientPath}`);
  } else {
    logger.log(`No client it has been found`);
  }

  setupSwagger(app);

  await app.listen(port);
  logger.log(`Application listening on port ${port}`);
}

async function loadCloudConfig(): Promise<void> {
  if (useJHipsterRegistry) {
    const endpoint = config.get('cloud.config.uri') || 'http://admin:admin@localhost:8761/config';
    logger.log(`Loading cloud config from ${endpoint}`);

    const cloudConfig = await cloudConfigClient.load({
      context: process.env,
      endpoint,
      name: config.get('cloud.config.name'),
      profiles: config.get('cloud.config.profile') || ['prod']
      // auth: {
      //   user: config.get('jhipster.registry.username') || 'admin',
      //   pass: config.get('jhipster.registry.password') || 'admin'
      // }
    });
    config.addAll(cloudConfig.properties);
  }
}

function registerAsEurekaService(): void {
  if (useJHipsterRegistry) {
    logger.log(`Registering with eureka ${config.get('cloud.config.uri')}`);
    const Eureka = require('eureka-js-client').Eureka;
    const eurekaUrl = require('url').parse(config.get('cloud.config.uri'));
    const client = new Eureka({
      instance: {
        app: config.get('eureka.instance.appname'),
        instanceId: config.get('eureka.instance.instanceId'),
        hostName: config.get('ipAddress') || 'localhost',
        ipAddr: config.get('ipAddress') || '127.0.0.1',
        port: {
          $: port,
          '@enabled': 'true'
        },
        vipAddress: config.get('ipAddress') || 'localhost',
        statusPageUrl: `http://${config.get('ipAddress')}:${port}/`,
        dataCenterInfo: {
          '@class': 'com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo',
          name: 'MyOwn'
        }
      },
      eureka: {
        // eureka server host / port
        host: eurekaUrl.hostname || '127.0.0.1',
        port: eurekaUrl.port || 8761,
        servicePath: '/eureka/apps'
      },
      requestMiddleware: (requestOpts, done): any => {
        requestOpts.auth = {
          user: config.get('jhipster.registry.username') || 'admin',
          password: config.get('jhipster.registry.password') || 'admin'
        };
        done(requestOpts);
      }
    });
    client.logger.level('debug');
    client.start(error => logger.log(error || 'Eureka registration complete'));
  }
}

bootstrap();
ghost commented 4 years ago

Thanks @jlopezjuy, but it works as your expectation?

jlopezjuy commented 4 years ago

yes

ghost commented 4 years ago

@jlopezjuy thanks a lot! If you want to contribute or give any suggestions you are welcome! 💯