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

JHipster Registry doesn't recognize microservices or gateway #265

Open
keyz231 opened this issue Feb 22, 2022 · 6 comments
Open

JHipster Registry doesn't recognize microservices or gateway #265

keyz231 opened this issue Feb 22, 2022 · 6 comments
Labels
good first issue Good for newcomers more information is needed More information are required to understand issue

Comments

@keyz231
Copy link

keyz231 commented Feb 22, 2022

I have installed a microservice using the guide:

npm install -g generator-jhipster-nodejs

and my microservice works ( for example I've tried to go to localhost:8081/api/users)

I have downloaded the jhipster-registry from github and start with mvwn

Now my registry recognize only 👍
image

But nothing about the microservice.

About microservice:

.yo-rc.json

  "generator-jhipster": {
    "blueprints": [
      {
        "name": "generator-jhipster-nodejs",
        "version": "2.0.0"
      }
    ],
    "otherModules": [
      {
        "name": "generator-jhipster-nodejs",
        "version": "2.0.0"
      }
    ],
    "applicationType": "microservice",
    "baseName": "microservice",
    "jhipsterVersion": "7.0.1",
    "skipClient": true,
    "skipUserManagement": true,
    "skipServer": false,
    "skipCheckLengthOfIdentifier": false,
    "skipFakeData": false,
    "jhiPrefix": "jhi",
    "entitySuffix": "",
    "dtoSuffix": "DTO",
    "testFrameworks": [],
    "pages": [],
    "creationTimestamp": 1645529869157,
    "serverPort": "8081",
    "packageName": "com.jhipster.node",
    "databaseType": "sql",
    "devDatabaseType": "sqlite",
    "prodDatabaseType": "oracle",
    "authenticationType": "jwt",
    "enableTranslation": false,
    "nativeLanguage": "it",
    "packageFolder": "com/jhipster/node",
    "jwtSecretKey": "Yjg1ZGExYWU2YjhiNjZhNDUwMTc5ZDUzNzhlMGFkOGY1MWUwODdmYWY0OWQ1NTVhZTc3N2U4NTU5N2M4MDg5Njg1YmY4NDQzMjc1NjIxYzg3ZDc3MDllMDdiZGFmNDE4ODBkYTVlMWIxZWFhYjdkNjBkYjNmOTc4NTczYzEyNWE=",
    "serviceDiscoveryType": false,
    "websocket": false,
    "searchEngine": false,
    "messageBroker": false,
    "cacheProvider": "ehcache",
    "buildTool": "maven",
    "enableHibernateCache": true,
    "reactive": false,
    "languages": ["en", "fr"]
  }
}

server/src/client/config/application.yml

# ===================================================================
# Configuration.
#
# This configuration will be overridden by the BACKEND_ENV you use,
# for example application-dev.yml if you use the "dev" profile.
#
# More information on profiles: https://www.jhipster.tech/profiles/
# More information on configuration properties: https://www.jhipster.tech/common-application-properties/
# ===================================================================

# ===================================================================
# Standard app properties.
# ===================================================================

eureka:
  client:
    enabled: false
    healthcheck:
      enabled: true
    fetch-registry: true
    register-with-eureka: true
    instance-info-replication-interval-seconds: 10
    registry-fetch-interval-seconds: 10
  instance:
    appname: microservice
    instanceId: microservice:${random.value}
    lease-renewal-interval-in-seconds: 5
    lease-expiration-duration-in-seconds: 10
    status-page-url-path: ${management.endpoints.web.base-path}/info
    health-check-url-path: ${management.endpoints.web.base-path}/health
    metadata-map:
      zone: primary # This is needed for the load balancer
      version: #project.version#
      git-version: ${git.commit.id.describe:}
      git-commit: ${git.commit.id.abbrev:}
      git-branch: ${git.branch:}

# ===================================================================
# JHipster specific properties
#
# Full reference is available at: https://www.jhipster.tech/common-application-properties/
# ===================================================================

jhipster:
  clientApp:
    name: 'microservice'
  registry:
    password: admin
  security:
    authentication:
      jwt:
        # This token must be encoded using Base64 and be at least 256 bits long (you can type `openssl rand -base64 64` on your command line to generate a 512 bits one)
        base64-secret: NDhjNjk1NTM3NWRlNjc1NDMwZjllNWFiMmVlYjQ4NzViYzY4MmY5ZWY2MzZhMzNiMTYxYmNlYjJkMWYwNDk0NDBlNDYwZThjMmFmNzAyNTQyOWYxMDhkM2QxYTQ3ZDFjM2I5YWU4YWVjOGRhNDc3MWE5OTExMzUyMjI3MDlmZWM=
        # Token is valid 24 hours
        token-validity-in-seconds: 86400
        token-validity-in-seconds-for-remember-me: 2592000
  mail:
    from: microservice@localhost
  swagger:
    default-include-pattern: /api/.*
    title: microservice API
    description: microservice API documentation
    version: 0.0.1
    terms-of-service-url:
    contact-name:
    contact-url:
    contact-email:
    license:
    license-url:
    path: /api/v2/api-docs

cloud:
  config:
    uri: http://admin:${jhipster.registry.password}@localhost:8761/config
    # name of the config server's property source (file.yml) that we want to use
    name: microservice
    profile: prod # profile(s) of the property source
    label: master # toggle to switch to a different version of the configuration as stored in git
    # it can be set to any label, branch or commit of the configuration source Git repository
# ===================================================================
# Application specific properties
# Add your own application properties here, see the ApplicationProperties class
# to have type-safe configuration, like in the JHipsterProperties above
#
# More documentation is available at:
# https://www.jhipster.tech/common-application-properties/
# ===================================================================

# application:

server/src/client/config/application-dev.yml

eureka:
  instance:
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://admin:${jhipster.registry.password}@localhost:8761/eureka/

server:
  port: 8081

  mail:
    host: localhost
    port: 25
    username:
    password:


jhipster:
  registry:
      password: admin
  mail: # specific JHipster mail property, for standard properties see MailProperties
    from: microservice@localhost
    base-url: http://127.0.0.1:8082

I have also tried with a gateway, but the result is the same. How can I set my microservice to the registry? Thank you

@ghost
Copy link

ghost commented Feb 23, 2022

Hi @keyz231,
thanks for the issue. Could you add your .yo-rc.json file? Thanks

@ghost ghost added good first issue Good for newcomers more information is needed More information are required to understand issue labels Feb 23, 2022
@keyz231
Copy link
Author

keyz231 commented Feb 23, 2022

Thank you for answer, I have insert .yo-rc.json at the beginning, do you refer to it ?

@ghost
Copy link

ghost commented Feb 26, 2022

Hi @keyz231, view the issue #103 .
Thanks for the issue.

@keyz231
Copy link
Author

keyz231 commented Feb 28, 2022

Thank you for your answer, So I can't use registry with microservices?
Anyway before opening the post I had given a good read to all the questions, but the difference with the one suggested by you is that my microservice can't even register (as if it wasn't even activated)

@ghost
Copy link

ghost commented Feb 28, 2022

The feature has been implemented. See the last linked issue in the comments.
For example:#103 (comment)

@Yomesh1995
Copy link

Yomesh1995 commented Aug 6, 2022

@amanganiello90 As you said this feature has been implemented, but still microservices or gateway metadata info & git commit info are not visible like jhipster-registry or any other jhipster(JAVA) microservice.
Screenshot from 2022-08-06 23-49-13

Mircoservice status
Screenshot from 2022-08-06 23-50-35

.yo-rc.json

{
  "generator-jhipster": {
    "blueprints": [
      {
        "name": "generator-jhipster-nodejs",
        "version": "2.0.0"
      }
    ],
    "otherModules": [
      {
        "name": "generator-jhipster-nodejs",
        "version": "2.0.0"
      }
    ],
    "applicationType": "microservice",
    "baseName": "result",
    "jhipsterVersion": "7.0.1",
    "skipClient": true,
    "skipUserManagement": true,
    "skipServer": false,
    "skipCheckLengthOfIdentifier": false,
    "skipFakeData": true,
    "jhiPrefix": "jhi",
    "entitySuffix": "",
    "dtoSuffix": "DTO",
    "testFrameworks": [],
    "pages": [],
    "creationTimestamp": 1659788990090,
    "serverPort": "8082",
    "packageName": "com.jhipster.node",
    "databaseType": "sql",
    "devDatabaseType": "sqlite",
    "prodDatabaseType": "mysql",
    "authenticationType": "jwt",
    "enableTranslation": true,
    "nativeLanguage": "en",
    "packageFolder": "com/jhipster/node",
    "jwtSecretKey": "ZjRlMDI3OWNhYWE4MjRkYWZlODc2YTg4NTJiMGVjOGM2OTdkOTI3YWNmMDA2ODVmMGMxNzc3OTExNzA1YmY1N2Y4ZjFkZTE3MGI3OWZiNjg0OTE3Mjk0ZjQ4YjZhODYzZTU5YWNjMmQyNjNkNWQ3MDBlMTJiN2QwNmRiNTE3NjM=",
    "serviceDiscoveryType": true,
    "websocket": false,
    "searchEngine": false,
    "messageBroker": false,
    "cacheProvider": "ehcache",
    "buildTool": "maven",
    "enableHibernateCache": true,
    "reactive": false,
    "languages": ["en", "fr"],
    "clientFramework": "angularX",
    "clientPackageManager": "npm",
    "clientTheme": "none",
    "clientThemeVariant": "",
    "withAdminUi": true,
    "entities": []
  }
}

application.yml

eureka:
  client:
    enabled: true
    healthcheck:
      enabled: true
    fetch-registry: true
    register-with-eureka: true
    instance-info-replication-interval-seconds: 10
    registry-fetch-interval-seconds: 10
  instance:
    appname: result
    instanceId: result:${random.value}
    lease-renewal-interval-in-seconds: 5
    lease-expiration-duration-in-seconds: 10
    status-page-url-path: ${management.endpoints.web.base-path}/info
    health-check-url-path: ${management.endpoints.web.base-path}/health
    metadata-map:
      zone: primary # This is needed for the load balancer
      version: #project.version#
      git-version: ${git.commit.id.describe:}
      git-commit: ${git.commit.id.abbrev:}
      git-branch: ${git.branch:}

jhipster:
  clientApp:
    name: 'result'
  registry:
    password: admin
  security:
    authentication:
      jwt:
        # This token must be encoded using Base64 and be at least 256 bits long (you can type `openssl rand -base64 64` on your command line to generate a 512 bits one)
        base64-secret: NDhjNjk1NTM3NWRlNjc1NDMwZjllNWFiMmVlYjQ4NzViYzY4MmY5ZWY2MzZhMzNiMTYxYmNlYjJkMWYwNDk0NDBlNDYwZThjMmFmNzAyNTQyOWYxMDhkM2QxYTQ3ZDFjM2I5YWU4YWVjOGRhNDc3MWE5OTExMzUyMjI3MDlmZWM=
        # Token is valid 24 hours
        token-validity-in-seconds: 86400
        token-validity-in-seconds-for-remember-me: 2592000
  mail:
    from: result@localhost
  swagger:
    default-include-pattern: /api/.*
    title: result API
    description: result API documentation
    version: 0.0.1
    terms-of-service-url:
    contact-name:
    contact-url:
    contact-email:
    license:
    license-url:
    path: /api/v2/api-docs

cloud:
  config:
    uri: http://admin:${jhipster.registry.password}@localhost:8761/config
    # name of the config server's property source (file.yml) that we want to use
    name: result
    profile: prod # profile(s) of the property source
    label: master # toggle to switch to a different version of the configuration as stored in git

config.ts

import yaml from 'js-yaml';
import * as fs from 'fs';
import * as path from 'path';
import { Logger } from '@nestjs/common';

const logger = new Logger('Config');

export class Config {
    debugLogging = 'debug';
    'server.port' = '8082';
    'jhipster.clientApp.name' = 'result';
    'jhipster.registry.password' = 'admin';
    'jhipster.security.authentication.jwt.base64-secret' = '';
    'jhipster.security.authentication.jwt.token-validity-in-seconds' = 86400;
    'jhipster.security.authentication.jwt.token-validity-in-seconds-for-remember-me' = 2592000;
    'jhipster.security.authentication.jwt.hash-salt-or-rounds' = 10;
    'jhipster.mail.base-url' = 'http://127.0.0.1:${server.port}';
    'jhipster.mail.from' = 'result@localhost';
    'jhipster.swagger.default-include-pattern' = '/api/.*';
    'jhipster.swagger.title' = 'result API';
    'jhipster.swagger.description' = 'result API documentation';
    'jhipster.swagger.version' = '0.0.1';
    'jhipster.swagger.path' = '/api/v2/api-docs';
    'eureka.client.enabled' = true;
    'eureka.client.healthcheck.enabled' = true;
    'eureka.client.fetch-registry' = true;
    'eureka.client.register-with-eureka' = true;
    'eureka.client.instance-info-replication-interval-seconds' = 10;
    'eureka.client.registry-fetch-interval-seconds' = 10;
    'eureka.instance.appname' = 'result';
    'eureka.instance.instanceId' = 'result:${random.value}';
    'eureka.instance.lease-renewal-interval-in-seconds' = 5;
    'eureka.instance.lease-expiration-duration-in-seconds' = 10;
    'eureka.instance.status-page-url-path' = '${management.endpoints.web.base-path}/info';
    'eureka.instance.health-check-url-path' = '${management.endpoints.web.base-path}/health';
    'eureka.instance.metadata-map.zone' = 'primary';
    // 'eureka.instance.metadata-map.profile' = '${profiles.active}';
    'eureka.instance.metadata-map.git-version' = '${git.commit.id.describe:}';
    'eureka.instance.metadata-map.git-commit' = '${git.commit.id.abbrev:}';
    'eureka.instance.metadata-map.git-branch' = '${git.branch:}';
    'eureka.instance.prefer-ip-address' = true;
    'eureka.client.service-url.defaultZone' = 'http://admin:${jhipster.registry.password}@localhost:8761/eureka/';
    'cloud.config.uri' = 'http://admin:${jhipster.registry.password}@localhost:8761/config';
    'cloud.config.name' = 'result';
    'cloud.config.profile' = 'prod';
    'cloud.config.label' = 'master';

    constructor(properties) {
        this.addAll(properties);
    }

    public get(key: string): any {
        return this[key];
    }

    public addAll(properties): any {
        properties = objectToArray(properties);
        for (const property in properties) {
            if (properties.hasOwnProperty(property)) {
                this[property] = properties[property];
            }
        }
        this.postProcess();
    }

    public postProcess(): any {
        const variables = { ...this, ...process.env };
        for (const property in this) {
            if (this.hasOwnProperty(property)) {
                const value = this[property];
                const processedValue = this.processTemplate(value, variables);
                this[property] = processedValue;
            }
        }
    }

    private processTemplate(template, variables): any {
        // console.log(template);
        if (typeof template === 'string') {
            return template.replace(
                new RegExp('\\${[^{]+}', 'g'),
                name => variables[name.substring(2, name.length - 1)],
            );
        }
        return template;
    }
}

const yamlConfigPath = path.join(__dirname, 'config', 'application.yml');
const envYamlConfigPath = path.join(__dirname, 'config', `application-${process.env.BACKEND_ENV}.yml`);

const yamlConfig = yaml.load(fs.readFileSync(yamlConfigPath, 'utf8'));
logger.log(`Actual process.env.BACKEND_ENV value: ${process.env.BACKEND_ENV}`);
logger.log('Standard allowed values are: dev, test or prod');
logger.log(
    'if you run with a non standard BACKEND_ENV value, remember to add your application-{process.env.BACKEND_ENV}.yml file',
);
if (!fs.existsSync(envYamlConfigPath)) {
    logger.error(
        'An application-{process.env.BACKEND_ENV}.yml file with your process.env.BACKEND_ENV value does not exist under config folder!',
    );
}
const envYamlConfig = yaml.load(fs.readFileSync(envYamlConfigPath, 'utf8'));

const config = new Config({ ...objectToArray(yamlConfig), ...objectToArray(envYamlConfig), ipAddress: ipAddress() });

export { config };

function objectToArray(source, currentKey?, target?): any {
    target = target || {};
    for (const property in source) {
        if (source.hasOwnProperty(property)) {
            const newKey = currentKey ? currentKey + '.' + property : property;
            const newVal = source[property];

            if (typeof newVal === 'object') {
                objectToArray(newVal, newKey, target);
            } else {
                target[newKey] = newVal;
            }
        }
    }
    return target;
}

function ipAddress(): any {
    const interfaces = require('os').networkInterfaces();
    for (const dev in interfaces) {
        if (interfaces.hasOwnProperty(dev)) {
            const iface = interfaces[dev];
            for (const alias of iface) {
                if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
                    return alias.address;
                }
            }
        }
    }

    return null;
}

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';
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'),
        }),
    );

    logger.log('The client is not been generated');
    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',
                status: 'UP',
                port: {
                    $: port,
                    '@enabled': 'true',
                },
                vipAddress: config.get('ipAddress') || 'localhost',
                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: 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();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers more information is needed More information are required to understand issue
Projects
None yet
Development

No branches or pull requests

2 participants