From 88d1e076083a7e26bd161025901c2d0becfd6764 Mon Sep 17 00:00:00 2001 From: Pierre Besson Date: Fri, 26 Jan 2018 17:53:18 +0100 Subject: [PATCH 01/19] remove the ProfileInfoResource --- generators/server/files.js | 91 ++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 13 deletions(-) diff --git a/generators/server/files.js b/generators/server/files.js index 9094e8a01b69..6cd41b5d8f17 100644 --- a/generators/server/files.js +++ b/generators/server/files.js @@ -590,13 +590,16 @@ const serverFiles = { { file: 'package/client/TokenRelayRequestInterceptor.java', renameTo: generator => `${generator.javaDir}client/TokenRelayRequestInterceptor.java` } ] }, - { - condition: generator => !(generator.applicationType !== 'microservice' && !(generator.applicationType === 'gateway' && (generator.authenticationType === 'uaa' || generator.authenticationType === 'oauth2'))) - && (generator.authenticationType === 'oauth2' && generator.applicationType === 'gateway'), - path: SERVER_MAIN_SRC_DIR, - templates: [ - { file: 'package/config/OAuth2SsoConfiguration.java', renameTo: generator => `${generator.javaDir}config/OAuth2SsoConfiguration.java` } - ] + + writeServerJavaWebFiles() { + this.template(`${SERVER_MAIN_SRC_DIR}package/web/rest/vm/package-info.java.ejs`, `${javaDir}web/rest/vm/package-info.java`); + this.template(`${SERVER_MAIN_SRC_DIR}package/web/rest/vm/LoggerVM.java.ejs`, `${javaDir}web/rest/vm/LoggerVM.java`); + + this.template(`${SERVER_MAIN_SRC_DIR}package/web/rest/util/HeaderUtil.java.ejs`, `${javaDir}web/rest/util/HeaderUtil.java`); + this.template(`${SERVER_MAIN_SRC_DIR}package/web/rest/util/PaginationUtil.java.ejs`, `${javaDir}web/rest/util/PaginationUtil.java`); + this.template(`${SERVER_MAIN_SRC_DIR}package/web/rest/package-info.java.ejs`, `${javaDir}web/rest/package-info.java`); + + this.template(`${SERVER_MAIN_SRC_DIR}package/web/rest/LogsResource.java.ejs`, `${javaDir}web/rest/LogsResource.java`); }, { condition: generator => !(generator.applicationType !== 'microservice' && !(generator.applicationType === 'gateway' && (generator.authenticationType === 'uaa' || generator.authenticationType === 'oauth2'))) @@ -645,12 +648,74 @@ const serverFiles = { { file: 'package/config/WebConfigurer.java', renameTo: generator => `${generator.javaDir}config/WebConfigurer.java` } ] }, - { - condition: generator => ['ehcache', 'hazelcast', 'infinispan'].includes(generator.cacheProvider) || generator.applicationType === 'gateway', - path: SERVER_MAIN_SRC_DIR, - templates: [ - { file: 'package/config/CacheConfiguration.java', renameTo: generator => `${generator.javaDir}config/CacheConfiguration.java` } - ] + + writeServerTestFwFiles() { + // Create Test Java files + const testDir = this.testDir; + + mkdirp(testDir); + + if (this.databaseType === 'cassandra') { + this.template(`${SERVER_TEST_SRC_DIR}package/CassandraKeyspaceUnitTest.java.ejs`, `${testDir}CassandraKeyspaceUnitTest.java`); + this.template(`${SERVER_TEST_SRC_DIR}package/AbstractCassandraTest.java.ejs`, `${testDir}AbstractCassandraTest.java`); + this.template(`${SERVER_TEST_SRC_DIR}package/config/CassandraTestConfiguration.java.ejs`, `${testDir}config/CassandraTestConfiguration.java`); + this.template(`${SERVER_TEST_RES_DIR}cassandra-random-port.yml.ejs`, `${SERVER_TEST_RES_DIR}cassandra-random-port.yml`); + } + + if (this.databaseType === 'couchbase') { + this.template(`${SERVER_TEST_SRC_DIR}package/config/DatabaseTestConfiguration.java.ejs`, `${testDir}config/DatabaseTestConfiguration.java`); + } + + this.template(`${SERVER_TEST_SRC_DIR}package/config/WebConfigurerTest.java.ejs`, `${testDir}config/WebConfigurerTest.java`); + this.template(`${SERVER_TEST_SRC_DIR}package/config/WebConfigurerTestController.java.ejs`, `${testDir}config/WebConfigurerTestController.java`); + this.template(`${SERVER_TEST_SRC_DIR}package/web/rest/TestUtil.java.ejs`, `${testDir}web/rest/TestUtil.java`); + this.template(`${SERVER_TEST_SRC_DIR}package/web/rest/LogsResourceIntTest.java.ejs`, `${testDir}web/rest/LogsResourceIntTest.java`); + this.template(`${SERVER_TEST_SRC_DIR}package/web/rest/errors/ExceptionTranslatorIntTest.java.ejs`, `${testDir}web/rest/errors/ExceptionTranslatorIntTest.java`); + this.template(`${SERVER_TEST_SRC_DIR}package/web/rest/errors/ExceptionTranslatorTestController.java.ejs`, `${testDir}web/rest/errors/ExceptionTranslatorTestController.java`); + this.template(`${SERVER_TEST_SRC_DIR}package/web/rest/util/PaginationUtilUnitTest.java.ejs`, `${testDir}web/rest/util/PaginationUtilUnitTest.java`); + + this.template(`${SERVER_TEST_RES_DIR}config/application.yml.ejs`, `${SERVER_TEST_RES_DIR}config/application.yml`); + this.template(`${SERVER_TEST_RES_DIR}logback.xml.ejs`, `${SERVER_TEST_RES_DIR}logback.xml`); + + // Create Gateway tests files + if (this.applicationType === 'gateway') { + this.template(`${SERVER_TEST_SRC_DIR}package/gateway/responserewriting/SwaggerBasePathRewritingFilterTest.java.ejs`, `${testDir}gateway/responserewriting/SwaggerBasePathRewritingFilterTest.java`); + } + if (this.serviceDiscoveryType) { + this.template(`${SERVER_TEST_RES_DIR}config/bootstrap.yml.ejs`, `${SERVER_TEST_RES_DIR}config/bootstrap.yml`); + } + + if (this.authenticationType === 'uaa') { + this.template(`${SERVER_TEST_SRC_DIR}package/security/OAuth2TokenMockUtil.java.ejs`, `${testDir}security/OAuth2TokenMockUtil.java`); + this.template(`${SERVER_TEST_SRC_DIR}package/config/SecurityBeanOverrideConfiguration.java.ejs`, `${testDir}config/SecurityBeanOverrideConfiguration.java`); + if (this.applicationType === 'gateway') { + this.template(`${SERVER_TEST_SRC_DIR}package/security/oauth2/OAuth2CookieHelperTest.java.ejs`, `${testDir}security/oauth2/OAuth2CookieHelperTest.java`); + this.template(`${SERVER_TEST_SRC_DIR}package/security/oauth2/OAuth2AuthenticationServiceTest.java.ejs`, `${testDir}security/oauth2/OAuth2AuthenticationServiceTest.java`); + this.template(`${SERVER_TEST_SRC_DIR}package/security/oauth2/CookieTokenExtractorTest.java.ejs`, `${testDir}security/oauth2/CookieTokenExtractorTest.java`); + this.template(`${SERVER_TEST_SRC_DIR}package/security/oauth2/CookieCollectionTest.java.ejs`, `${testDir}security/oauth2/CookieCollectionTest.java`); + } + } + + // Create Gatling test files + if (this.gatlingTests) { + this.copy(`${TEST_DIR}gatling/conf/gatling.conf.ejs`, `${TEST_DIR}gatling/conf/gatling.conf`); + this.copy(`${TEST_DIR}gatling/conf/logback.xml.ejs`, `${TEST_DIR}gatling/conf/logback.xml`); + mkdirp(`${TEST_DIR}gatling/user-files/data`); + mkdirp(`${TEST_DIR}gatling/user-files/bodies`); + mkdirp(`${TEST_DIR}gatling/user-files/simulations`); + } + + // Create Cucumber test files + if (this.cucumberTests) { + this.template(`${SERVER_TEST_SRC_DIR}package/cucumber/CucumberTest.java.ejs`, `${testDir}cucumber/CucumberTest.java`); + this.template(`${SERVER_TEST_SRC_DIR}package/cucumber/stepdefs/StepDefs.java.ejs`, `${testDir}cucumber/stepdefs/StepDefs.java`); + this.copy(`${TEST_DIR}features/gitkeep`, `${TEST_DIR}features/.gitkeep`); + } + + // Create auth config test files + if (this.applicationType === 'monolith' && this.authenticationType !== 'oauth2') { + this.template(`${SERVER_TEST_SRC_DIR}package/security/DomainUserDetailsServiceIntTest.java.ejs`, `${testDir}security/DomainUserDetailsServiceIntTest.java`); + } }, { condition: generator => generator.cacheProvider === 'infinispan', From 08ee2f5e4bb4e5e67d6b4e2fab54762bc661ab3f Mon Sep 17 00:00:00 2001 From: Pierre Besson Date: Fri, 26 Jan 2018 17:55:01 +0100 Subject: [PATCH 02/19] authorize everyone to access the /management/info endpoint --- .../config/MicroserviceSecurityConfiguration.java.ejs | 5 +++-- .../main/java/package/config/SecurityConfiguration.java.ejs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/generators/server/templates/src/main/java/package/config/MicroserviceSecurityConfiguration.java.ejs b/generators/server/templates/src/main/java/package/config/MicroserviceSecurityConfiguration.java.ejs index e60544b080dc..0d02a19e8111 100644 --- a/generators/server/templates/src/main/java/package/config/MicroserviceSecurityConfiguration.java.ejs +++ b/generators/server/templates/src/main/java/package/config/MicroserviceSecurityConfiguration.java.ejs @@ -80,6 +80,7 @@ public class MicroserviceSecurityConfiguration extends WebSecurityConfigurerAdap .authorizeRequests() .antMatchers("/api/**").authenticated() .antMatchers("/management/health").permitAll() + .antMatchers("/management/info").permitAll() .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/swagger-resources/configuration/ui").permitAll() .and() @@ -153,9 +154,9 @@ public class MicroserviceSecurityConfiguration extends ResourceServerConfigurerA .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() - .antMatchers("/api/profile-info").permitAll() .antMatchers("/api/**").authenticated() .antMatchers("/management/health").permitAll() + .antMatchers("/management/info").permitAll() .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/swagger-resources/configuration/ui").permitAll(); } @@ -269,9 +270,9 @@ public class MicroserviceSecurityConfiguration extends ResourceServerConfigurerA .and() .requestMatcher(authorizationHeaderRequestMatcher()) .authorizeRequests() - .antMatchers("/api/profile-info").permitAll() .antMatchers("/api/**").authenticated() .antMatchers("/management/health").permitAll() + .antMatchers("/management/info").permitAll() .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN); } } diff --git a/generators/server/templates/src/main/java/package/config/SecurityConfiguration.java.ejs b/generators/server/templates/src/main/java/package/config/SecurityConfiguration.java.ejs index 61a09a28b83a..baab4af7986c 100644 --- a/generators/server/templates/src/main/java/package/config/SecurityConfiguration.java.ejs +++ b/generators/server/templates/src/main/java/package/config/SecurityConfiguration.java.ejs @@ -236,11 +236,11 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { .antMatchers("/api/account/reset-password/init").permitAll() .antMatchers("/api/account/reset-password/finish").permitAll() <%_ } _%> - .antMatchers("/api/profile-info").permitAll() .antMatchers("/api/**").authenticated()<% if (websocket === 'spring-websocket') { %> .antMatchers("/websocket/tracker").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/websocket/**").permitAll()<% } %> .antMatchers("/management/health").permitAll() + .antMatchers("/management/info").permitAll() .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/v2/api-docs/**").permitAll() .antMatchers("/swagger-resources/configuration/ui").permitAll() From eac267dafd4cf40802f1b4fbe0e3430e6e2e4a40 Mon Sep 17 00:00:00 2001 From: Pierre Besson Date: Fri, 26 Jan 2018 18:01:36 +0100 Subject: [PATCH 03/19] migrate ribbon system from /api/profile-info to /management/info --- .../src/main/resources/config/application.yml.ejs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/generators/server/templates/src/main/resources/config/application.yml.ejs b/generators/server/templates/src/main/resources/config/application.yml.ejs index eb495bc3e583..1fc1453afef6 100644 --- a/generators/server/templates/src/main/resources/config/application.yml.ejs +++ b/generators/server/templates/src/main/resources/config/application.yml.ejs @@ -53,6 +53,9 @@ eureka: zone: primary # This is needed for the load balancer profile: ${spring.profiles.active} version: ${info.project.version} + git-version: ${git.commit.id.describe:} + git-commit: ${git.commit.id.abbrev:} + git-branch: ${git.branch:} ribbon: eureka: enabled: true @@ -211,9 +214,10 @@ server: cookie: http-only: true +# Properties to be exposed on the /info management endpoint info: - project: - version: #project.version# + # Comma separated list of profiles that will trigger the ribbon to show + display-ribbon-on-profiles: "dev" # =================================================================== # JHipster specific properties @@ -251,8 +255,6 @@ jhipster: contact-email: license: license-url: - ribbon: - display-on-active-profiles: dev # =================================================================== # Application specific properties From bd871149f54c5ff6c8e36404bca91c202639e99d Mon Sep 17 00:00:00 2001 From: Pierre Besson Date: Fri, 26 Jan 2018 18:02:17 +0100 Subject: [PATCH 04/19] make angular client use take ribbon and profile data from the info endpoint --- .../layouts/profiles/profile.service.ts.ejs | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs index a18076f5e075..4aca529ce115 100644 --- a/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs +++ b/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs @@ -25,21 +25,29 @@ import { ProfileInfo } from './profile-info.model'; @Injectable() export class ProfileService { - private profileInfoUrl = SERVER_API_URL + 'api/profile-info'; + private infoUrl = SERVER_API_URL + 'management/info'; private profileInfo: Promise; constructor(private http: HttpClient) { } getProfileInfo(): Promise { if (!this.profileInfo) { - this.profileInfo = this.http.get(this.profileInfoUrl, { observe: 'response' }) + this.profileInfo = this.http.get(this.infoUrl, { observe: 'response' }) .map((res: HttpResponse) => { const data = res.body; const pi = new ProfileInfo(); - pi.activeProfiles = data.activeProfiles; - pi.ribbonEnv = data.ribbonEnv; - pi.inProduction = data.activeProfiles.includes('prod') ; - pi.swaggerEnabled = data.activeProfiles.includes('swagger'); + pi.activeProfiles = data['active-profiles']; + const displayRibbonOnProfiles = data['display-ribbon-on-profiles'].split(','); + + const ribbonProfiles = displayRibbonOnProfiles.filter(function(profile) { + return pi.activeProfiles.includes(profile); + }); + + if (ribbonProfiles.length !== 0) { + pi.ribbonEnv = ribbonProfiles[0]; + } + pi.inProduction = pi.activeProfiles.includes('prod'); + pi.swaggerEnabled = pi.activeProfiles.includes('swagger'); return pi; }).toPromise(); } From 6e2ae4688b6db4a6cd5910c1f38451f5a679c3c9 Mon Sep 17 00:00:00 2001 From: Pierre Besson Date: Fri, 26 Jan 2018 18:17:02 +0100 Subject: [PATCH 05/19] upgrade gradle git-commit-plugin to 1.4.20 to support the gitVersion property for gradle as well --- .../server/templates/gradle/profile_prod.gradle.ejs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/generators/server/templates/gradle/profile_prod.gradle.ejs b/generators/server/templates/gradle/profile_prod.gradle.ejs index 99ea209ef342..1da0947fc44a 100644 --- a/generators/server/templates/gradle/profile_prod.gradle.ejs +++ b/generators/server/templates/gradle/profile_prod.gradle.ejs @@ -73,14 +73,8 @@ processResources { <%_ } _%> } -generateGitProperties { - onlyIf { - !source.isEmpty() - } -} - gitProperties { - keys = ['git.branch', 'git.commit.id.abbrev'] + keys = ['git.branch', 'git.commit.id.abbrev', 'git.commit.id.describe'] } <%_ if (!skipClient) { _%> From 8f2382f97261fd2fcf5a5c8134593df72a7581df Mon Sep 17 00:00:00 2001 From: Pierre Besson Date: Mon, 29 Jan 2018 11:48:17 +0100 Subject: [PATCH 06/19] use camel case properties rather than kebab case in /info json --- .../main/webapp/app/layouts/profiles/profile.service.ts.ejs | 4 ++-- .../templates/src/main/resources/config/application.yml.ejs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs index 4aca529ce115..4195214634d7 100644 --- a/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs +++ b/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs @@ -36,8 +36,8 @@ export class ProfileService { .map((res: HttpResponse) => { const data = res.body; const pi = new ProfileInfo(); - pi.activeProfiles = data['active-profiles']; - const displayRibbonOnProfiles = data['display-ribbon-on-profiles'].split(','); + pi.activeProfiles = data['activeProfiles']; + const displayRibbonOnProfiles = data['displayRibbonOnProfiles'].split(','); const ribbonProfiles = displayRibbonOnProfiles.filter(function(profile) { return pi.activeProfiles.includes(profile); diff --git a/generators/server/templates/src/main/resources/config/application.yml.ejs b/generators/server/templates/src/main/resources/config/application.yml.ejs index 1fc1453afef6..9191008595d4 100644 --- a/generators/server/templates/src/main/resources/config/application.yml.ejs +++ b/generators/server/templates/src/main/resources/config/application.yml.ejs @@ -217,7 +217,7 @@ server: # Properties to be exposed on the /info management endpoint info: # Comma separated list of profiles that will trigger the ribbon to show - display-ribbon-on-profiles: "dev" + displayRibbonOnProfiles: "dev" # =================================================================== # JHipster specific properties From 8b69b276a22fa16e6b65606c66cfa6b395103b93 Mon Sep 17 00:00:00 2001 From: Pierre Besson Date: Mon, 29 Jan 2018 14:11:33 +0100 Subject: [PATCH 07/19] use lambda for filter method --- .../main/webapp/app/layouts/profiles/profile.service.ts.ejs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs index 4195214634d7..4ee557cb60a3 100644 --- a/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs +++ b/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs @@ -38,11 +38,7 @@ export class ProfileService { const pi = new ProfileInfo(); pi.activeProfiles = data['activeProfiles']; const displayRibbonOnProfiles = data['displayRibbonOnProfiles'].split(','); - - const ribbonProfiles = displayRibbonOnProfiles.filter(function(profile) { - return pi.activeProfiles.includes(profile); - }); - + const ribbonProfiles = displayRibbonOnProfiles.filter((profile) => pi.activeProfiles.includes(profile)); if (ribbonProfiles.length !== 0) { pi.ribbonEnv = ribbonProfiles[0]; } From 7e9eb1857fad012a2a7c5b97cd6a2f0cc9f0a1fd Mon Sep 17 00:00:00 2001 From: Pierre Besson Date: Wed, 7 Feb 2018 11:48:18 +0100 Subject: [PATCH 08/19] go back to kebab case for display-ribbon-on-profiles property --- .../src/main/webapp/app/layouts/profiles/profile.service.ts.ejs | 2 +- .../templates/src/main/resources/config/application.yml.ejs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs index 4ee557cb60a3..ac2e49d6ddf3 100644 --- a/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs +++ b/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs @@ -37,7 +37,7 @@ export class ProfileService { const data = res.body; const pi = new ProfileInfo(); pi.activeProfiles = data['activeProfiles']; - const displayRibbonOnProfiles = data['displayRibbonOnProfiles'].split(','); + const displayRibbonOnProfiles = data['display-ribbon-on-profiles'].split(','); const ribbonProfiles = displayRibbonOnProfiles.filter((profile) => pi.activeProfiles.includes(profile)); if (ribbonProfiles.length !== 0) { pi.ribbonEnv = ribbonProfiles[0]; diff --git a/generators/server/templates/src/main/resources/config/application.yml.ejs b/generators/server/templates/src/main/resources/config/application.yml.ejs index 9191008595d4..1fc1453afef6 100644 --- a/generators/server/templates/src/main/resources/config/application.yml.ejs +++ b/generators/server/templates/src/main/resources/config/application.yml.ejs @@ -217,7 +217,7 @@ server: # Properties to be exposed on the /info management endpoint info: # Comma separated list of profiles that will trigger the ribbon to show - displayRibbonOnProfiles: "dev" + display-ribbon-on-profiles: "dev" # =================================================================== # JHipster specific properties From 7b40c7eb91c242033f01e03aa08697db5e129a67 Mon Sep 17 00:00:00 2001 From: "pbesson@ippon.fr" Date: Sun, 11 Mar 2018 19:43:52 +0100 Subject: [PATCH 09/19] add semicolon to support cases when build properties are not set by the build tool --- .../src/main/java/package/config/LoggingConfiguration.java.ejs | 2 +- .../templates/src/main/resources/config/application.yml.ejs | 2 +- .../templates/src/main/resources/config/bootstrap.yml.ejs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/generators/server/templates/src/main/java/package/config/LoggingConfiguration.java.ejs b/generators/server/templates/src/main/java/package/config/LoggingConfiguration.java.ejs index 532624ca579f..a56dbb10275b 100644 --- a/generators/server/templates/src/main/java/package/config/LoggingConfiguration.java.ejs +++ b/generators/server/templates/src/main/java/package/config/LoggingConfiguration.java.ejs @@ -82,7 +82,7 @@ public class LoggingConfiguration { private final JHipsterProperties jHipsterProperties; public LoggingConfiguration(@Value("${spring.application.name}") String appName, @Value("${server.port}") String serverPort, - <% if (serviceDiscoveryType === "consul") { %> ConsulRegistration consulRegistration,<% } %><% if (serviceDiscoveryType && (applicationType === 'microservice' || applicationType === 'gateway' || applicationType === 'uaa')) { %> @Value("${info.project.version}") String version,<% } %> JHipsterProperties jHipsterProperties) { + <% if (serviceDiscoveryType === "consul") { %> ConsulRegistration consulRegistration,<% } %><% if (serviceDiscoveryType && (applicationType === 'microservice' || applicationType === 'gateway' || applicationType === 'uaa')) { %> @Value("${info.project.version:}") String version,<% } %> JHipsterProperties jHipsterProperties) { this.appName = appName; this.serverPort = serverPort; <%_ if (serviceDiscoveryType === 'consul') { _%> diff --git a/generators/server/templates/src/main/resources/config/application.yml.ejs b/generators/server/templates/src/main/resources/config/application.yml.ejs index 1fc1453afef6..e6334045e0a3 100644 --- a/generators/server/templates/src/main/resources/config/application.yml.ejs +++ b/generators/server/templates/src/main/resources/config/application.yml.ejs @@ -52,7 +52,7 @@ eureka: metadata-map: zone: primary # This is needed for the load balancer profile: ${spring.profiles.active} - version: ${info.project.version} + version: ${info.project.version:} git-version: ${git.commit.id.describe:} git-commit: ${git.commit.id.abbrev:} git-branch: ${git.branch:} diff --git a/generators/server/templates/src/main/resources/config/bootstrap.yml.ejs b/generators/server/templates/src/main/resources/config/bootstrap.yml.ejs index ec2c5b5b09c0..4ecbb31090a6 100644 --- a/generators/server/templates/src/main/resources/config/bootstrap.yml.ejs +++ b/generators/server/templates/src/main/resources/config/bootstrap.yml.ejs @@ -43,7 +43,7 @@ spring: format: yaml profile-separator: "-" discovery: - tags: profile=${spring.profiles.active}, version=${info.project.version} + tags: profile=${spring.profiles.active}, version=${info.project.version:} host: localhost port: 8500 <%_ } _%> From 8fe90a9821be80653badcc9150ce23dc264f5253 Mon Sep 17 00:00:00 2001 From: Pierre Besson Date: Tue, 10 Apr 2018 13:50:49 +0200 Subject: [PATCH 10/19] add nullcheck for pi.activeProfile in angular profile service --- .../layouts/profiles/profile.service.ts.ejs | 12 +-- generators/server/files.js | 83 ------------------- 2 files changed, 7 insertions(+), 88 deletions(-) diff --git a/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs index ac2e49d6ddf3..fc0d335c2e76 100644 --- a/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs +++ b/generators/client/templates/angular/src/main/webapp/app/layouts/profiles/profile.service.ts.ejs @@ -38,12 +38,14 @@ export class ProfileService { const pi = new ProfileInfo(); pi.activeProfiles = data['activeProfiles']; const displayRibbonOnProfiles = data['display-ribbon-on-profiles'].split(','); - const ribbonProfiles = displayRibbonOnProfiles.filter((profile) => pi.activeProfiles.includes(profile)); - if (ribbonProfiles.length !== 0) { - pi.ribbonEnv = ribbonProfiles[0]; + if (pi.activeProfiles) { + const ribbonProfiles = displayRibbonOnProfiles.filter((profile) => pi.activeProfiles.includes(profile)); + if (ribbonProfiles.length !== 0) { + pi.ribbonEnv = ribbonProfiles[0]; + } + pi.inProduction = pi.activeProfiles.includes('prod'); + pi.swaggerEnabled = pi.activeProfiles.includes('swagger'); } - pi.inProduction = pi.activeProfiles.includes('prod'); - pi.swaggerEnabled = pi.activeProfiles.includes('swagger'); return pi; }).toPromise(); } diff --git a/generators/server/files.js b/generators/server/files.js index 6cd41b5d8f17..47588d491f86 100644 --- a/generators/server/files.js +++ b/generators/server/files.js @@ -590,17 +590,6 @@ const serverFiles = { { file: 'package/client/TokenRelayRequestInterceptor.java', renameTo: generator => `${generator.javaDir}client/TokenRelayRequestInterceptor.java` } ] }, - - writeServerJavaWebFiles() { - this.template(`${SERVER_MAIN_SRC_DIR}package/web/rest/vm/package-info.java.ejs`, `${javaDir}web/rest/vm/package-info.java`); - this.template(`${SERVER_MAIN_SRC_DIR}package/web/rest/vm/LoggerVM.java.ejs`, `${javaDir}web/rest/vm/LoggerVM.java`); - - this.template(`${SERVER_MAIN_SRC_DIR}package/web/rest/util/HeaderUtil.java.ejs`, `${javaDir}web/rest/util/HeaderUtil.java`); - this.template(`${SERVER_MAIN_SRC_DIR}package/web/rest/util/PaginationUtil.java.ejs`, `${javaDir}web/rest/util/PaginationUtil.java`); - this.template(`${SERVER_MAIN_SRC_DIR}package/web/rest/package-info.java.ejs`, `${javaDir}web/rest/package-info.java`); - - this.template(`${SERVER_MAIN_SRC_DIR}package/web/rest/LogsResource.java.ejs`, `${javaDir}web/rest/LogsResource.java`); - }, { condition: generator => !(generator.applicationType !== 'microservice' && !(generator.applicationType === 'gateway' && (generator.authenticationType === 'uaa' || generator.authenticationType === 'oauth2'))) && (generator.applicationType === 'microservice'), @@ -648,75 +637,6 @@ const serverFiles = { { file: 'package/config/WebConfigurer.java', renameTo: generator => `${generator.javaDir}config/WebConfigurer.java` } ] }, - - writeServerTestFwFiles() { - // Create Test Java files - const testDir = this.testDir; - - mkdirp(testDir); - - if (this.databaseType === 'cassandra') { - this.template(`${SERVER_TEST_SRC_DIR}package/CassandraKeyspaceUnitTest.java.ejs`, `${testDir}CassandraKeyspaceUnitTest.java`); - this.template(`${SERVER_TEST_SRC_DIR}package/AbstractCassandraTest.java.ejs`, `${testDir}AbstractCassandraTest.java`); - this.template(`${SERVER_TEST_SRC_DIR}package/config/CassandraTestConfiguration.java.ejs`, `${testDir}config/CassandraTestConfiguration.java`); - this.template(`${SERVER_TEST_RES_DIR}cassandra-random-port.yml.ejs`, `${SERVER_TEST_RES_DIR}cassandra-random-port.yml`); - } - - if (this.databaseType === 'couchbase') { - this.template(`${SERVER_TEST_SRC_DIR}package/config/DatabaseTestConfiguration.java.ejs`, `${testDir}config/DatabaseTestConfiguration.java`); - } - - this.template(`${SERVER_TEST_SRC_DIR}package/config/WebConfigurerTest.java.ejs`, `${testDir}config/WebConfigurerTest.java`); - this.template(`${SERVER_TEST_SRC_DIR}package/config/WebConfigurerTestController.java.ejs`, `${testDir}config/WebConfigurerTestController.java`); - this.template(`${SERVER_TEST_SRC_DIR}package/web/rest/TestUtil.java.ejs`, `${testDir}web/rest/TestUtil.java`); - this.template(`${SERVER_TEST_SRC_DIR}package/web/rest/LogsResourceIntTest.java.ejs`, `${testDir}web/rest/LogsResourceIntTest.java`); - this.template(`${SERVER_TEST_SRC_DIR}package/web/rest/errors/ExceptionTranslatorIntTest.java.ejs`, `${testDir}web/rest/errors/ExceptionTranslatorIntTest.java`); - this.template(`${SERVER_TEST_SRC_DIR}package/web/rest/errors/ExceptionTranslatorTestController.java.ejs`, `${testDir}web/rest/errors/ExceptionTranslatorTestController.java`); - this.template(`${SERVER_TEST_SRC_DIR}package/web/rest/util/PaginationUtilUnitTest.java.ejs`, `${testDir}web/rest/util/PaginationUtilUnitTest.java`); - - this.template(`${SERVER_TEST_RES_DIR}config/application.yml.ejs`, `${SERVER_TEST_RES_DIR}config/application.yml`); - this.template(`${SERVER_TEST_RES_DIR}logback.xml.ejs`, `${SERVER_TEST_RES_DIR}logback.xml`); - - // Create Gateway tests files - if (this.applicationType === 'gateway') { - this.template(`${SERVER_TEST_SRC_DIR}package/gateway/responserewriting/SwaggerBasePathRewritingFilterTest.java.ejs`, `${testDir}gateway/responserewriting/SwaggerBasePathRewritingFilterTest.java`); - } - if (this.serviceDiscoveryType) { - this.template(`${SERVER_TEST_RES_DIR}config/bootstrap.yml.ejs`, `${SERVER_TEST_RES_DIR}config/bootstrap.yml`); - } - - if (this.authenticationType === 'uaa') { - this.template(`${SERVER_TEST_SRC_DIR}package/security/OAuth2TokenMockUtil.java.ejs`, `${testDir}security/OAuth2TokenMockUtil.java`); - this.template(`${SERVER_TEST_SRC_DIR}package/config/SecurityBeanOverrideConfiguration.java.ejs`, `${testDir}config/SecurityBeanOverrideConfiguration.java`); - if (this.applicationType === 'gateway') { - this.template(`${SERVER_TEST_SRC_DIR}package/security/oauth2/OAuth2CookieHelperTest.java.ejs`, `${testDir}security/oauth2/OAuth2CookieHelperTest.java`); - this.template(`${SERVER_TEST_SRC_DIR}package/security/oauth2/OAuth2AuthenticationServiceTest.java.ejs`, `${testDir}security/oauth2/OAuth2AuthenticationServiceTest.java`); - this.template(`${SERVER_TEST_SRC_DIR}package/security/oauth2/CookieTokenExtractorTest.java.ejs`, `${testDir}security/oauth2/CookieTokenExtractorTest.java`); - this.template(`${SERVER_TEST_SRC_DIR}package/security/oauth2/CookieCollectionTest.java.ejs`, `${testDir}security/oauth2/CookieCollectionTest.java`); - } - } - - // Create Gatling test files - if (this.gatlingTests) { - this.copy(`${TEST_DIR}gatling/conf/gatling.conf.ejs`, `${TEST_DIR}gatling/conf/gatling.conf`); - this.copy(`${TEST_DIR}gatling/conf/logback.xml.ejs`, `${TEST_DIR}gatling/conf/logback.xml`); - mkdirp(`${TEST_DIR}gatling/user-files/data`); - mkdirp(`${TEST_DIR}gatling/user-files/bodies`); - mkdirp(`${TEST_DIR}gatling/user-files/simulations`); - } - - // Create Cucumber test files - if (this.cucumberTests) { - this.template(`${SERVER_TEST_SRC_DIR}package/cucumber/CucumberTest.java.ejs`, `${testDir}cucumber/CucumberTest.java`); - this.template(`${SERVER_TEST_SRC_DIR}package/cucumber/stepdefs/StepDefs.java.ejs`, `${testDir}cucumber/stepdefs/StepDefs.java`); - this.copy(`${TEST_DIR}features/gitkeep`, `${TEST_DIR}features/.gitkeep`); - } - - // Create auth config test files - if (this.applicationType === 'monolith' && this.authenticationType !== 'oauth2') { - this.template(`${SERVER_TEST_SRC_DIR}package/security/DomainUserDetailsServiceIntTest.java.ejs`, `${testDir}security/DomainUserDetailsServiceIntTest.java`); - } - }, { condition: generator => generator.cacheProvider === 'infinispan', path: SERVER_MAIN_SRC_DIR, @@ -860,8 +780,6 @@ const serverFiles = { { file: 'package/web/rest/package-info.java', renameTo: generator => `${generator.javaDir}web/rest/package-info.java` }, { file: 'package/web/rest/LogsResource.java', renameTo: generator => `${generator.javaDir}web/rest/LogsResource.java` }, - { file: 'package/web/rest/ProfileInfoResource.java', renameTo: generator => `${generator.javaDir}web/rest/ProfileInfoResource.java` }, - ] }, @@ -910,7 +828,6 @@ const serverFiles = { { file: 'package/config/WebConfigurerTestController.java', renameTo: generator => `${generator.testDir}config/WebConfigurerTestController.java` }, { file: 'package/web/rest/TestUtil.java', renameTo: generator => `${generator.testDir}web/rest/TestUtil.java` }, { file: 'package/web/rest/LogsResourceIntTest.java', renameTo: generator => `${generator.testDir}web/rest/LogsResourceIntTest.java` }, - { file: 'package/web/rest/ProfileInfoResourceIntTest.java', renameTo: generator => `${generator.testDir}web/rest/ProfileInfoResourceIntTest.java` }, { file: 'package/web/rest/errors/ExceptionTranslatorIntTest.java', renameTo: generator => `${generator.testDir}web/rest/errors/ExceptionTranslatorIntTest.java` }, { file: 'package/web/rest/errors/ExceptionTranslatorTestController.java', renameTo: generator => `${generator.testDir}web/rest/errors/ExceptionTranslatorTestController.java` }, { file: 'package/web/rest/util/PaginationUtilUnitTest.java', renameTo: generator => `${generator.testDir}web/rest/util/PaginationUtilUnitTest.java` }, From 8528052d786e12644b6e88be979a5511ccb3ce27 Mon Sep 17 00:00:00 2001 From: Srinivasa Vasu Date: Mon, 16 Apr 2018 07:18:02 +0530 Subject: [PATCH 11/19] fix for issue#7345 --- generators/kubernetes/files.js | 8 ++-- generators/kubernetes/index.js | 11 ++++- .../templates/README-KUBERNETES.md.ejs | 10 ++-- generators/kubernetes/templates/_apply.sh | 2 + .../kubernetes/templates/deployment.yml.ejs | 4 +- .../{db => messagebroker}/kafka.yml.ejs | 20 ++++---- generators/openshift/files.js | 8 ++-- generators/openshift/index.js | 48 +++++++++++++++---- generators/openshift/templates/apply.sh.ejs | 24 +++++----- .../openshift/templates/deployment.yml.ejs | 4 +- .../{db => messagebroker}/kafka.yml.ejs | 12 ++--- test/kubernetes.spec.js | 2 +- 12 files changed, 99 insertions(+), 54 deletions(-) rename generators/kubernetes/templates/{db => messagebroker}/kafka.yml.ejs (74%) rename generators/openshift/templates/{db => messagebroker}/kafka.yml.ejs (93%) diff --git a/generators/kubernetes/files.js b/generators/kubernetes/files.js index 9ac4b8aa9995..3cd0f1df8e21 100644 --- a/generators/kubernetes/files.js +++ b/generators/kubernetes/files.js @@ -35,9 +35,6 @@ function writeFiles() { if (this.app.searchEngine === 'elasticsearch') { this.template('db/elasticsearch.yml.ejs', `${this.directoryPath}/k8s/${appName}/${appName}-elasticsearch.yml`); } - if (this.app.messageBroker === 'kafka') { - this.template('db/kafka.yml.ejs', `${this.directoryPath}/k8s/${appName}/${appName}-kafka.yml`); - } if ((this.app.applicationType === 'gateway' || this.app.applicationType === 'monolith') && this.kubernetesServiceType === 'Ingress') { this.template('ingress.yml.ejs', `${this.directoryPath}/k8s/${appName}/${appName}-ingress.yml`); } @@ -57,6 +54,11 @@ function writeFiles() { } }, + writeMessagingBroker() { + if (!this.useKafka) return; + this.template('messagebroker/kafka.yml.ejs', `${this.directoryPath}/k8s/messagebroker/kafka.yml`); + }, + writeJhipsterConsole() { if (this.monitoring === 'elk') { this.template('console/jhipster-elasticsearch.yml.ejs', `${this.directoryPath}/k8s/console/jhipster-elasticsearch.yml`); diff --git a/generators/kubernetes/index.js b/generators/kubernetes/index.js index 38e18635e8d3..5b7c4e55e010 100644 --- a/generators/kubernetes/index.js +++ b/generators/kubernetes/index.js @@ -75,6 +75,7 @@ module.exports = class extends BaseGenerator { this.monitoring = this.config.get('monitoring'); this.kubernetesServiceType = this.config.get('kubernetesServiceType'); this.ingressDomain = this.config.get('ingressDomain'); + this.useKafka = false; this.DOCKER_JHIPSTER_REGISTRY = constants.DOCKER_JHIPSTER_REGISTRY; this.DOCKER_JHIPSTER_ELASTICSEARCH = constants.DOCKER_JHIPSTER_ELASTICSEARCH; @@ -157,9 +158,12 @@ module.exports = class extends BaseGenerator { configureImageNames: docker.configureImageNames, setAppsFolderPaths: docker.setAppsFolderPaths, - setDistributedDBReplicaCount() { + setPostPromptProp() { this.appConfigs.forEach((element) => { element.clusteredDb ? element.dbPeerCount = 3 : element.dbPeerCount = 1; + if (element.messageBroker === 'kafka') { + this.useKafka = true; + } }); }, @@ -207,6 +211,9 @@ module.exports = class extends BaseGenerator { if (this.kubernetesNamespace !== 'default') { this.log(` ${chalk.cyan(`kubectl apply -f ${this.directoryPath}k8s/namespace.yml`)}`); } + if (this.useKafka === true) { + this.log(` ${chalk.cyan(`kubectl apply -f ${this.directoryPath}k8s/messagebroker`)}`); + } if (this.monitoring === 'elk') { this.log(` ${chalk.cyan(`kubectl apply -f ${this.directoryPath}k8s/console`)}`); } @@ -215,7 +222,7 @@ module.exports = class extends BaseGenerator { } for (let i = 0, regIndex = 0; i < this.appsFolders.length; i++) { this.log(` ${chalk.cyan(`kubectl apply -f ${this.directoryPath}k8s/${this.appConfigs[i].baseName.toLowerCase()}`)}`); - if (regIndex++ === 0 && this.appConfigs[i].serviceDiscoveryType !== false) { + if (this.appConfigs[i].serviceDiscoveryType !== false && regIndex++ === 0) { this.log(` ${chalk.cyan(`kubectl apply -f ${this.directoryPath}k8s/registry`)}`); } } diff --git a/generators/kubernetes/templates/README-KUBERNETES.md.ejs b/generators/kubernetes/templates/README-KUBERNETES.md.ejs index 645146bf1877..17ed3eee5435 100644 --- a/generators/kubernetes/templates/README-KUBERNETES.md.ejs +++ b/generators/kubernetes/templates/README-KUBERNETES.md.ejs @@ -22,6 +22,8 @@ You can deploy your apps by running: kubectl apply -f <%-directoryPath%>k8s/namespace.yml <%_ } _%> <%_ if (serviceDiscoveryType === 'eureka' || serviceDiscoveryType === 'consul') { _%> kubectl apply -f <%-directoryPath%>k8s/registry/ +<%_ } _%> <%_ if (useKafka === true) { _%> +kubectl apply -f <%-directoryPath%>k8s/messagebroker/ <%_ } _%> <%_ if (monitoring === 'elk') { _%> kubectl apply -f <%-directoryPath%>k8s/console/ <%_ } _%> <%_ if (monitoring === 'prometheus') { _%> @@ -55,7 +57,7 @@ $ kubectl get svc <%= appConfigs[i].baseName.toLowerCase() %><%= kubernetesNames ## Scaling your deployments -You can scale your apps using +You can scale your apps using ``` $ kubectl scale deployment --replicas <%= kubernetesNamespace === 'default' ? '' : ` -n ${kubernetesNamespace}` %> @@ -82,7 +84,7 @@ Your application logs can be found in JHipster console (powered by Kibana). You $ kubectl get svc jhipster-console<%= kubernetesNamespace === 'default' ? '' : ` -n ${kubernetesNamespace}` %> ``` -* If you have chosen *Ingress*, then you should be able to access Kibana using the given ingress domain. +* If you have chosen *Ingress*, then you should be able to access Kibana using the given ingress domain. * If you have chosen *NodePort*, then point your browser to an IP of any of your nodes and use the node port described in the output. * If you have chosen *LoadBalancer*, then use the IaaS provided LB IP <%_ } _%> @@ -90,7 +92,7 @@ $ kubectl get svc jhipster-console<%= kubernetesNamespace === 'default' ? '' : ` ### Prometheus metrics -Generator is also packaged with [Prometheus operator by CoreOS](https://github.com/coreos/prometheus-operator). +Generator is also packaged with [Prometheus operator by CoreOS](https://github.com/coreos/prometheus-operator). **hint**: use must build your apps with `prometheus` profile active! @@ -105,7 +107,7 @@ Also the visualisation can be explored in Grafana which is pre-configured with a $ kubectl get svc jhipster-grafana<%= kubernetesNamespace === 'default' ? '' : ` -n ${kubernetesNamespace}` %> ``` -* If you have chosen *Ingress*, then you should be able to access Grafana using the given ingress domain. +* If you have chosen *Ingress*, then you should be able to access Grafana using the given ingress domain. * If you have chosen *NodePort*, then point your browser to an IP of any of your nodes and use the node port described in the output. * If you have chosen *LoadBalancer*, then use the IaaS provided LB IP diff --git a/generators/kubernetes/templates/_apply.sh b/generators/kubernetes/templates/_apply.sh index 6dd18ab6e372..b8d3910d4813 100644 --- a/generators/kubernetes/templates/_apply.sh +++ b/generators/kubernetes/templates/_apply.sh @@ -23,6 +23,8 @@ kubectl apply -f <%-directoryPath%>k8s/namespace.yml <%_ } _%> <%_ if (serviceDiscoveryType === 'eureka' || serviceDiscoveryType === 'consul') { _%> kubectl apply -f <%-directoryPath%>k8s/registry/ +<%_ } _%> <%_ if (useKafka === true) { _%> +kubectl apply -f <%-directoryPath%>k8s/messagebroker/ <%_ } _%> <%_ if (monitoring === 'elk') { _%> kubectl apply -f <%-directoryPath%>k8s/console/ <%_ } _%> <%_ if (monitoring === 'prometheus') { _%> diff --git a/generators/kubernetes/templates/deployment.yml.ejs b/generators/kubernetes/templates/deployment.yml.ejs index a19c2ae31f1d..39bdb07540ce 100644 --- a/generators/kubernetes/templates/deployment.yml.ejs +++ b/generators/kubernetes/templates/deployment.yml.ejs @@ -113,9 +113,9 @@ spec: <%_ } _%> <%_ if (app.messageBroker === 'kafka') { _%> - name: SPRING_CLOUD_STREAM_KAFKA_BINDER_BROKERS - value: <%= app.baseName.toLowerCase() %>-kafka.<%= kubernetesNamespace %>.svc.cluster.local + value: jhipster-kafka.<%= kubernetesNamespace %>.svc.cluster.local - name: SPRING_CLOUD_STREAM_KAFKA_BINDER_ZK_NODES - value: <%= app.baseName.toLowerCase() %>-zookeeper.<%= kubernetesNamespace %>.svc.cluster.local + value: jhipster-zookeeper.<%= kubernetesNamespace %>.svc.cluster.local <%_ } _%> <%_ if (monitoring === 'elk') { _%> - name: JHIPSTER_METRICS_LOGS_ENABLED diff --git a/generators/kubernetes/templates/db/kafka.yml.ejs b/generators/kubernetes/templates/messagebroker/kafka.yml.ejs similarity index 74% rename from generators/kubernetes/templates/db/kafka.yml.ejs rename to generators/kubernetes/templates/messagebroker/kafka.yml.ejs index 2640bfc92735..4b8083f0c9d0 100644 --- a/generators/kubernetes/templates/db/kafka.yml.ejs +++ b/generators/kubernetes/templates/messagebroker/kafka.yml.ejs @@ -19,25 +19,25 @@ apiVersion: extensions/v1beta1 kind: Deployment metadata: - name: <%= app.baseName.toLowerCase() %>-kafka + name: jhipster-kafka namespace: <%= kubernetesNamespace %> spec: replicas: 1 template: metadata: labels: - app: <%= app.baseName.toLowerCase() %>-kafka + app: jhipster-kafka spec: containers: - name: kafka image: <%= DOCKER_KAFKA %> env: - name: KAFKA_ADVERTISED_HOST_NAME - value: <%= app.baseName.toLowerCase() %>-kafka.<%= kubernetesNamespace %>.svc.cluster.local + value: jhipster-kafka.<%= kubernetesNamespace %>.svc.cluster.local - name: KAFKA_ADVERTISED_PORT value: '9092' - name: KAFKA_ZOOKEEPER_CONNECT - value: <%= app.baseName.toLowerCase() %>-zookeeper.<%= kubernetesNamespace %>.svc.cluster.local:2181 + value: jhipster-zookeeper.<%= kubernetesNamespace %>.svc.cluster.local:2181 - name: KAFKA_CREATE_TOPICS value: 'topic-jhipster:1:1' ports: @@ -46,25 +46,25 @@ spec: apiVersion: v1 kind: Service metadata: - name: <%= app.baseName.toLowerCase() %>-kafka + name: jhipster-kafka namespace: <%= kubernetesNamespace %> spec: selector: - app: <%= app.baseName.toLowerCase() %>-kafka + app: jhipster-kafka ports: - port: 9092 --- apiVersion: extensions/v1beta1 kind: Deployment metadata: - name: <%= app.baseName.toLowerCase() %>-zookeeper + name: jhipster-zookeeper namespace: <%= kubernetesNamespace %> spec: replicas: 1 template: metadata: labels: - app: <%= app.baseName.toLowerCase() %>-zookeeper + app: jhipster-zookeeper spec: containers: - name: zookeeper @@ -75,10 +75,10 @@ spec: apiVersion: v1 kind: Service metadata: - name: <%= app.baseName.toLowerCase() %>-zookeeper + name: jhipster-zookeeper namespace: <%= kubernetesNamespace %> spec: selector: - app: <%= app.baseName.toLowerCase() %>-zookeeper + app: jhipster-zookeeper ports: - port: 2181 diff --git a/generators/openshift/files.js b/generators/openshift/files.js index f1dfce3d329b..91971ce87ef7 100644 --- a/generators/openshift/files.js +++ b/generators/openshift/files.js @@ -18,12 +18,14 @@ function writeFiles() { if (this.app.searchEngine === 'elasticsearch') { this.template('db/elasticsearch.yml.ejs', `${this.directoryPath}/ocp/${appName}/${appName}-elasticsearch.yml`); } - if (this.app.messageBroker === 'kafka') { - this.template('db/kafka.yml.ejs', `${this.directoryPath}/ocp/${appName}/${appName}-kafka.yml`); - } } }, + writeMessagingBroker() { + if (!this.useKafka) return; + this.template('messagebroker/kafka.yml.ejs', `${this.directoryPath}/ocp/messagebroker/kafka.yml`); + }, + writeRegistryFiles() { this.template('scc/scc-config.yml.ejs', `${this.directoryPath}/ocp/registry/scc-config.yml`); if (this.serviceDiscoveryType === 'eureka') { diff --git a/generators/openshift/index.js b/generators/openshift/index.js index 675dedcd7963..afead5a58249 100644 --- a/generators/openshift/index.js +++ b/generators/openshift/index.js @@ -76,6 +76,7 @@ module.exports = class extends BaseGenerator { this.openshiftNamespace = this.config.get('openshiftNamespace'); this.storageType = this.config.get('storageType'); this.registryReplicas = this.config.get('registryReplicas'); + this.useKafka = false; this.DOCKER_JHIPSTER_REGISTRY = constants.DOCKER_JHIPSTER_REGISTRY; this.DOCKER_TRAEFIK = constants.DOCKER_TRAEFIK; @@ -162,6 +163,16 @@ module.exports = class extends BaseGenerator { this.registryReplicas = 2; }, + setPostPromptProp() { + this.appConfigs.some((element) => { + if (element.messageBroker === 'kafka') { + this.useKafka = true; + return true; + } + return false; + }); + }, + saveConfig() { this.config.set('appsFolders', this.appsFolders); this.config.set('directoryPath', this.directoryPath); @@ -201,17 +212,36 @@ module.exports = class extends BaseGenerator { } this.log('\nYou can deploy all your apps by running: '); - this.log(` ${chalk.cyan(`${this.directoryPath}/ocp/ocp-apply.sh`)}`); - if (this.gatewayNb >= 1 || this.microserviceNb >= 1) { - this.log('OR'); - this.log(` ${chalk.cyan(`oc apply -f ${this.directoryPath}/ocp/registry`)}`); - if (this.monitoring === 'elk' || this.monitoring === 'prometheus') { - this.log(` ${chalk.cyan(`oc apply -f ${this.directoryPath}/ocp/monitoring`)}`); + this.log(` ${chalk.cyan(`${this.directoryPath}ocp/ocp-apply.sh`)}`); + this.log('OR'); + this.log(` ${chalk.cyan(`oc process -f ${this.directoryPath}ocp/registry/scc-config.yml | oc apply -f -`)}`); + if (this.monitoring === 'elk') { + this.log(` ${chalk.cyan(`oc process -f ${this.directoryPath}ocp/monitoring/jhipster-monitoring.yml | oc apply -f -`)}`); + } + if (this.monitoring === 'prometheus') { + this.log(` ${chalk.cyan(`oc process -f ${this.directoryPath}ocp/monitoring/jhipster-metrics.yml | oc apply -f -`)}`); + } + if (this.useKafka === true) { + this.log(` ${chalk.cyan(`oc process -f ${this.directoryPath}ocp/messagebroker/kafka.yml | oc apply -f -`)}`); + } + for (let i = 0, regIndex = 0; i < this.appsFolders.length; i++) { + const app = this.appConfigs[i]; + const appName = app.baseName.toLowerCase(); + if (app.searchEngine === 'elasticsearch') { + this.log(` ${chalk.cyan(`oc process -f ${this.directoryPath}ocp/${appName}/${appName}-elasticsearch.yml | oc apply -f -`)}`); } - for (let i = 0; i < this.appsFolders.length; i++) { - this.log(` ${chalk.cyan(`oc apply -f ${this.directoryPath}/ocp/${this.appConfigs[i].baseName}`)}`); + if (app.serviceDiscoveryType !== false && regIndex++ === 0) { + this.log(` ${chalk.cyan(`oc process -f ${this.directoryPath}ocp/registry/application-configmap.yml | oc apply -f -`)}`); + if (app.serviceDiscoveryType === 'eureka') { + this.log(` ${chalk.cyan(`oc process -f ${this.directoryPath}ocp/registry/jhipster-registry.yml | oc apply -f -`)}`); + } else { + this.log(` ${chalk.cyan(`oc process -f ${this.directoryPath}ocp/registry/consul.yml | oc apply -f -`)}`); + } + } + if (app.prodDatabaseType !== 'no') { + this.log(` ${chalk.cyan(`oc process -f ${this.directoryPath}ocp/${appName}/${appName}-${app.prodDatabaseType}.yml | oc apply -f -`)}`); } - this.log('and then install the apps from OpenShift console by choosing the template created in the namespace. '); + this.log(` ${chalk.cyan(`oc process -f ${this.directoryPath}ocp/${appName}/${appName}-deployment.yml | oc apply -f -`)}`); } if (this.gatewayNb + this.monolithicNb >= 1) { diff --git a/generators/openshift/templates/apply.sh.ejs b/generators/openshift/templates/apply.sh.ejs index 301507518c4a..2a447164ea42 100644 --- a/generators/openshift/templates/apply.sh.ejs +++ b/generators/openshift/templates/apply.sh.ejs @@ -20,26 +20,26 @@ # Use this script to run oc commands to create resources in the selected namespace. Files are ordered # in proper order. 'oc process' processes the template as resources which is again piped to # 'oc apply' to create those resources in OpenShift namespace -oc process -f <%-directoryPath%>/ocp/registry/scc-config.yml | oc apply -f - +oc process -f <%-directoryPath%>ocp/registry/scc-config.yml | oc apply -f - <%_ if (serviceDiscoveryType === 'eureka') { _%> -oc process -f <%-directoryPath%>/ocp/registry/application-configmap.yml | oc apply -f - -oc process -f <%-directoryPath%>/ocp/registry/jhipster-registry.yml | oc apply -f - +oc process -f <%-directoryPath%>ocp/registry/application-configmap.yml | oc apply -f - +oc process -f <%-directoryPath%>ocp/registry/jhipster-registry.yml | oc apply -f - <%_ } _%> <%_ if (serviceDiscoveryType === 'consul') { _%> -oc process -f <%-directoryPath%>/ocp/registry/application-configmap.yml | oc apply -f - -oc process -f <%-directoryPath%>/ocp/registry/consul.yml | oc apply -f - +oc process -f <%-directoryPath%>ocp/registry/application-configmap.yml | oc apply -f - +oc process -f <%-directoryPath%>ocp/registry/consul.yml | oc apply -f - +<%_ } _%> <%_ if (useKafka === true) { _%> +oc process -f <%-directoryPath%>ocp/messagebroker/kafka.yml | oc apply -f - <%_ } _%> <%_ if (monitoring === 'elk') { _%> -oc process -f <%-directoryPath%>/ocp/monitoring/jhipster-monitoring.yml | oc apply -f - +oc process -f <%-directoryPath%>ocp/monitoring/jhipster-monitoring.yml | oc apply -f - <%_ } _%> <%_ if (monitoring === 'prometheus') { _%> -oc process -f <%-directoryPath%>/ocp/monitoring/jhipster-metrics.yml | oc apply -f - +oc process -f <%-directoryPath%>ocp/monitoring/jhipster-metrics.yml | oc apply -f - <%_ } _%> <%_ for (var i = 0; i < appConfigs.length; i++) { const appName = appConfigs[i].baseName.toLowerCase(); app = appConfigs[i]; if (app.prodDatabaseType !== 'no') { _%> -oc process -f <%-directoryPath%>/ocp/<%- appName %>/<%- appName %>-<%- app.prodDatabaseType %>.yml | oc apply -f - +oc process -f <%-directoryPath%>ocp/<%- appName %>/<%- appName %>-<%- app.prodDatabaseType %>.yml | oc apply -f - <%_ } _%> <%_ if (app.searchEngine === 'elasticsearch') { _%> -oc process -f <%-directoryPath%>/ocp/<%- appName %>/<%- appName %>-elasticsearch.yml | oc apply -f - -<%_ } _%> <%_ if (app.messageBroker === 'kafka') { _%> -oc process -f <%-directoryPath%>/ocp/<%- appName %>/<%- appName %>-kafka.yml | oc apply -f - +oc process -f <%-directoryPath%>ocp/<%- appName %>/<%- appName %>-elasticsearch.yml | oc apply -f - <%_ } _%> -oc process -f <%-directoryPath%>/ocp/<%- appName %>/<%- appName %>-deployment.yml | oc apply -f - +oc process -f <%-directoryPath%>ocp/<%- appName %>/<%- appName %>-deployment.yml | oc apply -f - <%_ } _%> diff --git a/generators/openshift/templates/deployment.yml.ejs b/generators/openshift/templates/deployment.yml.ejs index f430b847220d..d9c849d00726 100644 --- a/generators/openshift/templates/deployment.yml.ejs +++ b/generators/openshift/templates/deployment.yml.ejs @@ -232,9 +232,9 @@ objects: <%_ } _%> <%_ if (app.messageBroker === 'kafka') { _%> - name: SPRING_CLOUD_STREAM_KAFKA_BINDER_BROKERS - value: ${APPLICATION_NAME}-kafka + value: jhipster-kafka - name: SPRING_CLOUD_STREAM_KAFKA_BINDER_ZK_NODES - value: ${APPLICATION_NAME}-zookeeper + value: jhipster-zookeeper <%_ } _%> <%_ if (monitoring === 'elk') { _%> - name: JHIPSTER_METRICS_LOGS_ENABLED diff --git a/generators/openshift/templates/db/kafka.yml.ejs b/generators/openshift/templates/messagebroker/kafka.yml.ejs similarity index 93% rename from generators/openshift/templates/db/kafka.yml.ejs rename to generators/openshift/templates/messagebroker/kafka.yml.ejs index b32030fc7fbf..10d2719ad44a 100644 --- a/generators/openshift/templates/db/kafka.yml.ejs +++ b/generators/openshift/templates/messagebroker/kafka.yml.ejs @@ -25,30 +25,30 @@ apiVersion: v1 kind: Template metadata: - name: <%= app.baseName.toLowerCase() %>-kafka-template + name: jhipster-kafka-template namespace: <%= openshiftNamespace %> annotations: description: This template defines objects that are required to spin up a kafka and zookeeper pod - tags: kafka, <%= app.baseName.toLowerCase() %>-kafka<% if (storageType === 'persistent') { %> ,persistent <% } %> <% if (storageType === 'ephemeral') { %> ,ephemeral <% } %> - openshift.io/display-name: <%= app.baseName.toLowerCase() %>-kafka-template + tags: kafka, jhipster-kafka<% if (storageType === 'persistent') { %> ,persistent <% } %> <% if (storageType === 'ephemeral') { %> ,ephemeral <% } %> + openshift.io/display-name: jhipster-kafka-template openshift.io/long-description: "This template provides objects that are required to spin up a kafka and zookeeper pod. <% if (storageType == 'persistent') { %>The database is stored on persistent storage, so any restart of the service will not cause any impact to the data. Please make sure you have provisioned PVs (Persistent Volumes) before using this template. <% } %><% if (storageType === 'ephemeral') { %>The database is not stored on persistent storage, so any restart of the service will result in all data being lost.<% } %>" openshift.io/provider-display-name: JHipster-OpenShift labels: - app: <%= app.baseName.toLowerCase() %>-kafka + app: jhipster-kafka createdBy: JHipster-Team parameters: - name: APPLICATION_NAME - value: <%= app.baseName.toLowerCase() %>-kafka + value: jhipster-kafka description: Name of the kafka application required: true displayName: Kafka Application Name - name: ZK_APPLICATION_NAME - value: <%= app.baseName.toLowerCase() %>-zookeeper + value: jhipster-zookeeper description: Name of the zookeeper application required: true displayName: Zookeeper Application Name diff --git a/test/kubernetes.spec.js b/test/kubernetes.spec.js index b57ee2ece67f..95e245da1368 100644 --- a/test/kubernetes.spec.js +++ b/test/kubernetes.spec.js @@ -68,7 +68,7 @@ const expectedFiles = { './k8s/samplekafka/samplekafka-deployment.yml', './k8s/samplekafka/samplekafka-mysql.yml', './k8s/samplekafka/samplekafka-service.yml', - './k8s/samplekafka/samplekafka-kafka.yml' + './k8s/messagebroker/kafka.yml' ], prometheusmonit: [ './k8s/monitoring/jhipster-prometheus-crd.yml', From 6c93c05f4ee4a731b2a66c74e5cfc3774e76503d Mon Sep 17 00:00:00 2001 From: Pascal Grimaud Date: Sun, 22 Apr 2018 16:52:06 +0200 Subject: [PATCH 12/19] Fix missing files --- generators/server/files.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/generators/server/files.js b/generators/server/files.js index 47588d491f86..f0d2bfb73558 100644 --- a/generators/server/files.js +++ b/generators/server/files.js @@ -590,6 +590,14 @@ const serverFiles = { { file: 'package/client/TokenRelayRequestInterceptor.java', renameTo: generator => `${generator.javaDir}client/TokenRelayRequestInterceptor.java` } ] }, + { + condition: generator => !(generator.applicationType !== 'microservice' && !(generator.applicationType === 'gateway' && (generator.authenticationType === 'uaa' || generator.authenticationType === 'oauth2'))) + && (generator.authenticationType === 'oauth2' && generator.applicationType === 'gateway'), + path: SERVER_MAIN_SRC_DIR, + templates: [ + { file: 'package/config/OAuth2SsoConfiguration.java', renameTo: generator => `${generator.javaDir}config/OAuth2SsoConfiguration.java` } + ] + }, { condition: generator => !(generator.applicationType !== 'microservice' && !(generator.applicationType === 'gateway' && (generator.authenticationType === 'uaa' || generator.authenticationType === 'oauth2'))) && (generator.applicationType === 'microservice'), @@ -637,6 +645,13 @@ const serverFiles = { { file: 'package/config/WebConfigurer.java', renameTo: generator => `${generator.javaDir}config/WebConfigurer.java` } ] }, + { + condition: generator => ['ehcache', 'hazelcast', 'infinispan'].includes(generator.cacheProvider) || generator.applicationType === 'gateway', + path: SERVER_MAIN_SRC_DIR, + templates: [ + { file: 'package/config/CacheConfiguration.java', renameTo: generator => `${generator.javaDir}config/CacheConfiguration.java` } + ] + }, { condition: generator => generator.cacheProvider === 'infinispan', path: SERVER_MAIN_SRC_DIR, From 0fa397738912197caa9c6cac83c142be7908e310 Mon Sep 17 00:00:00 2001 From: Pascal Grimaud Date: Sun, 22 Apr 2018 17:48:00 +0200 Subject: [PATCH 13/19] Fix Gradle build when there is no git --- generators/server/templates/gradle/profile_prod.gradle.ejs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/generators/server/templates/gradle/profile_prod.gradle.ejs b/generators/server/templates/gradle/profile_prod.gradle.ejs index 1da0947fc44a..35749fe53d1c 100644 --- a/generators/server/templates/gradle/profile_prod.gradle.ejs +++ b/generators/server/templates/gradle/profile_prod.gradle.ejs @@ -73,6 +73,12 @@ processResources { <%_ } _%> } +generateGitProperties { + onlyIf { + !source.isEmpty() + } +} + gitProperties { keys = ['git.branch', 'git.commit.id.abbrev', 'git.commit.id.describe'] } From 5b5d4ff8e1efbab389bf4741c157f6d75ad97c75 Mon Sep 17 00:00:00 2001 From: Alexandre GC Date: Tue, 24 Apr 2018 14:23:46 +0200 Subject: [PATCH 14/19] React: Fix header in prod profile (#7468) * fix reacter header in prod profile * add react profile handling * move a needle * remove unecessary prop * add and fix some react test * minor fix * minor fix * fix translation issue * fix a syntax error * improve translation tag regex * fix a possible name conflict * change profile reducer to applicationProfile I made this change to prevent name conflict with entities sicne profile appear to be pretty commmon. * add files that I forgot * refactor header to be a dumb component * add header test * minor change * remove unused import --- generators/client/files-react.js | 6 +- .../react/src/main/webapp/app/app.tsx.ejs | 18 +++- .../app/shared/layout/header/header.tsx.ejs | 54 ++++++++--- .../reducers/application-profile.ts.ejs | 51 ++++++++++ .../webapp/app/shared/reducers/index.ts.ejs | 2 + .../app/shared/layout/header.spec.tsx.ejs | 43 ++++++++- .../reducers/application-profile.spec.ts.ejs | 95 +++++++++++++++++++ .../templates/react/webpack/utils.js.ejs | 2 +- generators/generator-base.js | 2 +- 9 files changed, 246 insertions(+), 27 deletions(-) create mode 100644 generators/client/templates/react/src/main/webapp/app/shared/reducers/application-profile.ts.ejs create mode 100644 generators/client/templates/react/src/test/javascript/spec/app/shared/reducers/application-profile.spec.ts.ejs diff --git a/generators/client/files-react.js b/generators/client/files-react.js index 992d6064a640..821f3386e42f 100644 --- a/generators/client/files-react.js +++ b/generators/client/files-react.js @@ -207,7 +207,8 @@ const files = { templates: [ 'shared/reducers/index.ts', 'shared/reducers/action-type.util.ts', - 'shared/reducers/authentication.ts' + 'shared/reducers/authentication.ts', + 'shared/reducers/application-profile.ts' ] }, { @@ -357,10 +358,11 @@ const files = { 'spec/entry.ts', 'spec/app/utils.ts', 'spec/app/config/notification-middleware.spec.ts', - 'spec/app/shared/layout/header.spec.tsx', + 'spec/app/shared/reducers/application-profile.spec.ts', 'spec/app/shared/reducers/authentication.spec.ts', 'spec/app/shared/util/entity-utils.spec.ts', 'spec/app/shared/auth/private-route.spec.tsx', + 'spec/app/shared/layout/header.spec.tsx', 'spec/app/modules/account/register/register.spec.tsx', 'spec/app/modules/account/register/register.reducer.spec.ts', 'spec/app/modules/account/activate/activate.reducer.spec.ts', diff --git a/generators/client/templates/react/src/main/webapp/app/app.tsx.ejs b/generators/client/templates/react/src/main/webapp/app/app.tsx.ejs index 75c0e7a255ad..4b248c1c6bd9 100644 --- a/generators/client/templates/react/src/main/webapp/app/app.tsx.ejs +++ b/generators/client/templates/react/src/main/webapp/app/app.tsx.ejs @@ -25,6 +25,7 @@ import { HashRouter as Router } from 'react-router-dom'; import { ToastContainer, toast } from 'react-toastify'; import { getSession } from 'app/shared/reducers/authentication'; +import { getProfile } from 'app/shared/reducers/application-profile'; <%_ if (enableTranslation) { _%> import { setLocale } from 'app/shared/reducers/locale'; <%_ } _%> @@ -37,16 +38,21 @@ import AppRoutes from 'app/routes'; export interface IAppProps { isAuthenticated: boolean; isAdmin: boolean; + ribbonEnv: string; + isInProduction: boolean; + isSwaggerEnabled: boolean; <%_ if (enableTranslation) { _%> currentLocale: string; setLocale: Function; <%_ } _%> getSession: Function; + getProfile: Function; } export class App extends React.Component { componentDidMount() { this.props.getSession(); + this.props.getProfile(); } render() { @@ -62,6 +68,9 @@ export class App extends React.Component { currentLocale={this.props.currentLocale} onLocaleChange={this.props.setLocale} <%_ } _%> + ribbonEnv={this.props.ribbonEnv} + isInProduction={this.props.isInProduction} + isSwaggerEnabled={this.props.isSwaggerEnabled} />
@@ -75,14 +84,17 @@ export class App extends React.Component { } } -const mapStateToProps = ({ authentication<% if (enableTranslation) { %>, locale<% } %> }) => ({ +const mapStateToProps = ({ authentication, applicationProfile<% if (enableTranslation) { %>, locale<% } %> }) => ({ <%_ if (enableTranslation) { _%> currentLocale: locale.currentLocale, <%_ } _%> isAuthenticated: authentication.isAuthenticated, - isAdmin: hasAnyAuthority(authentication.account.authorities, [AUTHORITIES.ADMIN]) + isAdmin: hasAnyAuthority(authentication.account.authorities, [AUTHORITIES.ADMIN]), + ribbonEnv: applicationProfile.ribbonEnv, + isInProduction: applicationProfile.inProduction, + isSwaggerEnabled: applicationProfile.isSwaggerEnabled }); -const mapDispatchToProps = { <% if (enableTranslation) { %>setLocale, <% } %>getSession }; +const mapDispatchToProps = { <% if (enableTranslation) { %>setLocale, <% } %>getSession, getProfile }; export default connect(mapStateToProps, mapDispatchToProps)(App); diff --git a/generators/client/templates/react/src/main/webapp/app/shared/layout/header/header.tsx.ejs b/generators/client/templates/react/src/main/webapp/app/shared/layout/header/header.tsx.ejs index fca1a2633147..b9efd09abd2c 100644 --- a/generators/client/templates/react/src/main/webapp/app/shared/layout/header/header.tsx.ejs +++ b/generators/client/templates/react/src/main/webapp/app/shared/layout/header/header.tsx.ejs @@ -54,6 +54,9 @@ import appConfig from 'app/config/constants'; export interface IHeaderProps { isAuthenticated: boolean; isAdmin: boolean; + ribbonEnv: string; + isInProduction: boolean; + isSwaggerEnabled: boolean; <%_ if (enableTranslation) { _%> currentLocale: string; onLocaleChange: Function; @@ -72,7 +75,8 @@ const BrandIcon = props => ( />
); -export class Header extends React.Component { + +export default class Header extends React.Component { state: IHeaderState = { menuOpen: false }; @@ -89,13 +93,19 @@ export class Header extends React.Component { document.querySelector('html').setAttribute('dir', isRTL(event.target.value) ? 'rtl' : 'ltr'); <%_ } _%> } - <%_ } _%> - renderDevRibbon = () => ( - process.env.NODE_ENV === 'development' ? - : - null - ) + + renderDevRibbon = () => this.props.isInProduction === false ? ( + + ) : null; toggleMenu = () => { this.setState({ menuOpen: !this.state.menuOpen }); @@ -121,15 +131,27 @@ export class Header extends React.Component { Metrics, Health, Configuration, - <%_ if (databaseType !== 'cassandra') { _%> + <%_ if (databaseType !== 'cassandra') { _%> Audits, - <%_ } _%> - Logs, + <%_ } _%> /* jhipster-needle-add-element-to-admin-menu - JHipster will add entities to the admin menu here */ - API Docs<% if (devDatabaseType === 'h2Disk' || devDatabaseType === 'h2Memory') { %>, - Database - <%_ } _%> + Logs ]; + + const swaggerItem = ( + + API Docs + + ); + + <% if (devDatabaseType === 'h2Disk' || devDatabaseType === 'h2Memory') { %> + const databaseItem = [ + + Database + + ]; + <%_ } _%> + const accountMenuItems = []; if (isAuthenticated) { accountMenuItems.push( @@ -172,6 +194,10 @@ export class Header extends React.Component { {adminMenuItems} + {this.props.isSwaggerEnabled ? swaggerItem : null} + <% if (devDatabaseType === 'h2Disk' || devDatabaseType === 'h2Memory') { %> + {!this.props.isInProduction ? databaseItem : null} + <%_ } _%> ); @@ -225,5 +251,3 @@ export class Header extends React.Component { ); } } - -export default Header; diff --git a/generators/client/templates/react/src/main/webapp/app/shared/reducers/application-profile.ts.ejs b/generators/client/templates/react/src/main/webapp/app/shared/reducers/application-profile.ts.ejs new file mode 100644 index 000000000000..b6ed1890569b --- /dev/null +++ b/generators/client/templates/react/src/main/webapp/app/shared/reducers/application-profile.ts.ejs @@ -0,0 +1,51 @@ +<%# + Copyright 2013-2018 the original author or authors from the JHipster project. + + This file is part of the JHipster project, see https://www.jhipster.tech/ + for more information. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +-%> +import axios from 'axios'; + +import { SUCCESS } from 'app/shared/reducers/action-type.util'; + +export const ACTION_TYPES = { + GET_PROFILE: 'applicationProfile/GET_PROFILE' +}; + +const initialState = { + ribbonEnv: '', + inProduction: true, + isSwaggerEnabled: false +}; + +export default (state = initialState, action) => { + switch (action.type) { + case SUCCESS(ACTION_TYPES.GET_PROFILE): + const { data } = action.payload; + return { + ...state, + ribbonEnv: data.ribbonEnv, + inProduction: data.activeProfiles.includes('prod'), + isSwaggerEnabled: data.activeProfiles.includes('swagger') + }; + default: + return state; + } +}; + +export const getProfile = () => ({ + type: ACTION_TYPES.GET_PROFILE, + payload: axios.get('/api/profile-info') +}); diff --git a/generators/client/templates/react/src/main/webapp/app/shared/reducers/index.ts.ejs b/generators/client/templates/react/src/main/webapp/app/shared/reducers/index.ts.ejs index 75dd4d6c085c..0c0337b19ebe 100644 --- a/generators/client/templates/react/src/main/webapp/app/shared/reducers/index.ts.ejs +++ b/generators/client/templates/react/src/main/webapp/app/shared/reducers/index.ts.ejs @@ -23,6 +23,7 @@ import { loadingBarReducer as loadingBar } from 'react-redux-loading-bar'; import locale from './locale'; <%_ } _%> import authentication from './authentication'; +import applicationProfile from './application-profile'; import administration from 'app/modules/administration/administration.reducer'; <%_ if (!skipUserManagement) { _%> @@ -45,6 +46,7 @@ export default combineReducers({ <%_ if (enableTranslation) { _%> locale, <%_ } _%> + applicationProfile, administration, <%_ if (!skipUserManagement) { _%> userManagement, diff --git a/generators/client/templates/react/src/test/javascript/spec/app/shared/layout/header.spec.tsx.ejs b/generators/client/templates/react/src/test/javascript/spec/app/shared/layout/header.spec.tsx.ejs index 8cc248d53e0e..723157421717 100644 --- a/generators/client/templates/react/src/test/javascript/spec/app/shared/layout/header.spec.tsx.ejs +++ b/generators/client/templates/react/src/test/javascript/spec/app/shared/layout/header.spec.tsx.ejs @@ -35,10 +35,30 @@ describe('Header', () => { <% if (enableTranslation) { %> const localeSpy = sinon.spy(); <% } %> - const wrapper = () => { + const devWrapper = () => { if (!mountedWrapper) { mountedWrapper = shallow( -
currentLocale="en" onLocaleChange={localeSpy}<% } %>/> +
currentLocale="en" onLocaleChange={localeSpy}<% } %> + ribbonEnv="dev" + isInProduction={false} + isSwaggerEnabled + /> + ); + } + return mountedWrapper; + }; + const prodWrapper = () => { + if (!mountedWrapper) { + mountedWrapper = shallow( +
currentLocale="en" onLocaleChange={localeSpy}<% } %> + ribbonEnv="prod" + isInProduction + isSwaggerEnabled={false} + /> ); } return mountedWrapper; @@ -49,12 +69,25 @@ describe('Header', () => { }); // All tests will go here - it('Renders a component with LoadingBar, Navbar and Nav', () => { - const navbar = wrapper().find(Navbar); + it('Renders a Header component in dev profile with LoadingBar, Navbar, Nav and dev ribbon.', () => { + const navbar = devWrapper().find(Navbar); + expect(navbar.length).to.equal(1); + expect(navbar.find(NavbarBrand).find('.brand-logo').length).to.equal(1); + const nav = devWrapper().find(Nav); + expect(nav.length).to.equal(1); + expect(nav.find(NavItem).length).to.equal(1); + const ribbon = devWrapper().find('.ribbon .dev'); + expect(ribbon.length).to.equal(1); + }); + + it('Renders a Header component in prod profile with LoadingBar, Navbar, Nav.', () => { + const navbar = prodWrapper().find(Navbar); expect(navbar.length).to.equal(1); expect(navbar.find(NavbarBrand).find('.brand-logo').length).to.equal(1); - const nav = wrapper().find(Nav); + const nav = prodWrapper().find(Nav); expect(nav.length).to.equal(1); expect(nav.find(NavItem).length).to.equal(1); + const ribbon = prodWrapper().find('.ribbon .dev'); + expect(ribbon.length).to.equal(0); }); }); diff --git a/generators/client/templates/react/src/test/javascript/spec/app/shared/reducers/application-profile.spec.ts.ejs b/generators/client/templates/react/src/test/javascript/spec/app/shared/reducers/application-profile.spec.ts.ejs new file mode 100644 index 000000000000..226c03e407a8 --- /dev/null +++ b/generators/client/templates/react/src/test/javascript/spec/app/shared/reducers/application-profile.spec.ts.ejs @@ -0,0 +1,95 @@ +<%# + Copyright 2013-2018 the original author or authors from the JHipster project. + + This file is part of the JHipster project, see https://www.jhipster.tech/ + for more information. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +-%> +import { expect } from 'chai'; +import { REQUEST, SUCCESS } from 'app/shared/reducers/action-type.util'; +import thunk from 'redux-thunk'; +import axios from 'axios'; +import * as sinon from 'sinon'; +import configureStore from 'redux-mock-store'; +import promiseMiddleware from 'redux-promise-middleware'; + +import profile, { ACTION_TYPES, getProfile } from 'app/shared/reducers/application-profile'; + +describe('Profile reducer tests', () => { + const initialState = { + ribbonEnv: '', + inProduction: true, + isSwaggerEnabled: false + }; + describe('Common tests', () => { + it('should return the initial state', () => { + const toTest = profile(undefined, {}); + expect(toTest).to.eql(initialState); + }); + + it('should return the right payload in prod', () => { + const payload = { + data: { + ribbonEnv: 'awesome ribbon stuff', + activeProfiles: ['prod'] + } + }; + + expect(profile(undefined, { type: SUCCESS(ACTION_TYPES.GET_PROFILE), payload })).to.eql({ + ribbonEnv: 'awesome ribbon stuff', + inProduction: true, + isSwaggerEnabled: false + }); + }); + + it('should return the right payload in dev with swagger enabled', () => { + const payload = { + data: { + ribbonEnv: 'awesome ribbon stuff', + activeProfiles: ['dev', 'swagger'] + } + }; + + expect(profile(undefined, { type: SUCCESS(ACTION_TYPES.GET_PROFILE), payload })).to.eql({ + ribbonEnv: 'awesome ribbon stuff', + inProduction: false, + isSwaggerEnabled: true + }); + }); + }); + + describe('Actions', () => { + let store; + + const resolvedObject = { value: 'whatever' }; + beforeEach(() => { + const mockStore = configureStore([thunk, promiseMiddleware()]); + store = mockStore({}); + axios.get = sinon.stub().returns(Promise.resolve(resolvedObject)); + }); + + it('dispatches GET_SESSION_PENDING and GET_SESSION_FULFILLED actions', async () => { + const expectedActions = [ + { + type: REQUEST(ACTION_TYPES.GET_PROFILE) + }, + { + type: SUCCESS(ACTION_TYPES.GET_PROFILE), + payload: resolvedObject + } + ]; + await store.dispatch(getProfile()).then(() => expect(store.getActions()).to.eql(expectedActions)); + }); + }); +}); diff --git a/generators/client/templates/react/webpack/utils.js.ejs b/generators/client/templates/react/webpack/utils.js.ejs index da260c517612..981c08b93d43 100644 --- a/generators/client/templates/react/webpack/utils.js.ejs +++ b/generators/client/templates/react/webpack/utils.js.ejs @@ -54,7 +54,7 @@ function parseVersion() { // Returns a static version number when server is skipped function parseVersion() { return '0.0.1-SNAPSHOT'; -}; +} <%_ } _%> const _root = path.resolve(__dirname, '..'); diff --git a/generators/generator-base.js b/generators/generator-base.js index 1f6912f6aef1..f730251a0ae9 100644 --- a/generators/generator-base.js +++ b/generators/generator-base.js @@ -1478,7 +1478,7 @@ module.exports = class extends PrivateBase { /(import { ?translate, ?Translate ?} from 'react-jhipster';?)/, // translate imports /( Translate,|, ?Translate|import { ?Translate ?} from 'react-jhipster';?)/, // Translate import /( translate,|, ?translate|import { ?translate ?} from 'react-jhipster';?)/, // translate import - /|<\/Translate>/, // Translate component tag + /|<\/Translate>/, // Translate component tag ].map(r => r.source).join('|'), 'g'); jhipsterUtils.copyWebResource(source, dest, regex, 'jsx', _this, opt, template); From e17f0f31f763ed15b710b8a7b56688ced08b66ba Mon Sep 17 00:00:00 2001 From: Pierre Besson Date: Tue, 24 Apr 2018 17:16:49 +0200 Subject: [PATCH 15/19] fix #7527, fix the commented out file appender config in logback-spring.xml --- .../templates/src/main/resources/logback-spring.xml.ejs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/generators/server/templates/src/main/resources/logback-spring.xml.ejs b/generators/server/templates/src/main/resources/logback-spring.xml.ejs index b58f748ec16e..badba09d8d0f 100644 --- a/generators/server/templates/src/main/resources/logback-spring.xml.ejs +++ b/generators/server/templates/src/main/resources/logback-spring.xml.ejs @@ -39,6 +39,10 @@ 512 + + + + --> <%_ if (databaseType === 'cassandra') { _%> From 6808ac0c496efcceb18c4fd589b826bf95f143c0 Mon Sep 17 00:00:00 2001 From: Pascal Grimaud Date: Wed, 25 Apr 2018 06:46:29 +0200 Subject: [PATCH 16/19] Travis: use jhipster/jhipster master branch --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 59e665fa7d0c..8c83e4550a49 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ env: # if JHIPSTER_LIB_BRANCH value is release, use the release from Maven - JHIPSTER_LIB_REPO=https://github.com/jhipster/jhipster.git - - JHIPSTER_LIB_BRANCH=release + - JHIPSTER_LIB_BRANCH=master # if JHIPSTER_BRANCH value is release, use the release from NPM - JHIPSTER_REPO=https://github.com/jhipster/generator-jhipster.git - JHIPSTER_BRANCH=release From 0992ef196fec37015f929b923cf529f692b056aa Mon Sep 17 00:00:00 2001 From: Pascal Grimaud Date: Wed, 25 Apr 2018 07:19:46 +0200 Subject: [PATCH 17/19] Fix yarn test by removing ProfileInfoResourceIntTest.java --- test/utils/expected-files.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/utils/expected-files.js b/test/utils/expected-files.js index 7a234ca9d04a..33f819c16ec7 100644 --- a/test/utils/expected-files.js +++ b/test/utils/expected-files.js @@ -122,7 +122,6 @@ const expectedFiles = { `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/web/rest/AccountResourceIntTest.java`, `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/web/rest/AuditResourceIntTest.java`, `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/web/rest/LogsResourceIntTest.java`, - `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/web/rest/ProfileInfoResourceIntTest.java`, `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/web/rest/TestUtil.java`, `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/web/rest/UserResourceIntTest.java`, `${SERVER_TEST_RES_DIR}config/application.yml`, From dfe5b3a24ecb43906c478862eac79c77f9ea312a Mon Sep 17 00:00:00 2001 From: Pascal Grimaud Date: Wed, 25 Apr 2018 08:57:28 +0200 Subject: [PATCH 18/19] Docker: add _JAVA_OPTIONS commented to reduce memory use [ci skip] --- generators/server/templates/src/main/docker/app.yml.ejs | 1 + .../server/templates/src/main/docker/jhipster-registry.yml.ejs | 1 + 2 files changed, 2 insertions(+) diff --git a/generators/server/templates/src/main/docker/app.yml.ejs b/generators/server/templates/src/main/docker/app.yml.ejs index 19342a1725de..917a96cfbe14 100644 --- a/generators/server/templates/src/main/docker/app.yml.ejs +++ b/generators/server/templates/src/main/docker/app.yml.ejs @@ -21,6 +21,7 @@ services: <%= baseName.toLowerCase() %>-app: image: <%= baseName.toLowerCase() %> environment: + # - _JAVA_OPTIONS=-Xmx512m -Xms256m - SPRING_PROFILES_ACTIVE=prod,swagger <%_ if (serviceDiscoveryType === 'consul') { _%> - SPRING_CLOUD_CONSUL_HOST=consul diff --git a/generators/server/templates/src/main/docker/jhipster-registry.yml.ejs b/generators/server/templates/src/main/docker/jhipster-registry.yml.ejs index e79490de7d50..47ed08e828ea 100644 --- a/generators/server/templates/src/main/docker/jhipster-registry.yml.ejs +++ b/generators/server/templates/src/main/docker/jhipster-registry.yml.ejs @@ -27,6 +27,7 @@ services: # When run with the "prod" Spring profile, it will read the configuration from a Git repository # See https://www.jhipster.tech/microservices-architecture/#registry_app_configuration environment: + # - _JAVA_OPTIONS=-Xmx512m -Xms256m - SPRING_PROFILES_ACTIVE=dev,native,swagger<% if (authenticationType === 'oauth2') { %>,oauth2<% } %> - SPRING_SECURITY_USER_PASSWORD=admin - JHIPSTER_REGISTRY_PASSWORD=admin From 07fbbffca81e4209c119b439e942c61bb941d6a2 Mon Sep 17 00:00:00 2001 From: Duff Date: Thu, 26 Apr 2018 09:42:48 +0200 Subject: [PATCH 19/19] 7497 : fix gateway monitor issue cannot use setMetricRegistry() and setMetricsTrackerFactory() together (#7522) Fix #7497 fix #7497 --- .../src/main/java/package/config/MetricsConfiguration.java.ejs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/generators/server/templates/src/main/java/package/config/MetricsConfiguration.java.ejs b/generators/server/templates/src/main/java/package/config/MetricsConfiguration.java.ejs index 698ba56099e9..2a53afc52b61 100644 --- a/generators/server/templates/src/main/java/package/config/MetricsConfiguration.java.ejs +++ b/generators/server/templates/src/main/java/package/config/MetricsConfiguration.java.ejs @@ -111,6 +111,8 @@ public class MetricsConfiguration extends MetricsConfigurerAdapter { <%_ if (databaseType === 'sql') { _%> if (hikariDataSource != null) { log.debug("Monitoring the datasource"); + // remove the factory created by HikariDataSourceMetricsPostProcessor until JHipster migrate to Micrometer + hikariDataSource.setMetricsTrackerFactory(null); hikariDataSource.setMetricRegistry(metricRegistry); } <%_ } _%>