();
+ }
+ return entries;
+ }
+
+ public void deleteCar(Car car) {
+ car = em.merge(car);
+ em.remove(car);
+ }
+}
\ No newline at end of file
diff --git a/jee7/src/main/java/com/baeldung/arquillian/Component.java b/jee7/src/main/java/com/baeldung/arquillian/Component.java
new file mode 100644
index 0000000000..27e8d10f34
--- /dev/null
+++ b/jee7/src/main/java/com/baeldung/arquillian/Component.java
@@ -0,0 +1,13 @@
+package com.baeldung.arquillian;
+
+import java.io.PrintStream;
+
+public class Component {
+ public void sendMessage(PrintStream to, String msg) {
+ to.println(message(msg));
+ }
+
+ public String message(String msg) {
+ return "Message, " + msg;
+ }
+}
\ No newline at end of file
diff --git a/jee7/src/main/java/com/baeldung/arquillian/ConvertToLowerCase.java b/jee7/src/main/java/com/baeldung/arquillian/ConvertToLowerCase.java
new file mode 100644
index 0000000000..fd9b961308
--- /dev/null
+++ b/jee7/src/main/java/com/baeldung/arquillian/ConvertToLowerCase.java
@@ -0,0 +1,7 @@
+package com.baeldung.arquillian;
+
+public class ConvertToLowerCase {
+ public String convert(String word){
+ return word.toLowerCase();
+ }
+}
diff --git a/jee7/src/main/resources/META-INF/persistence.xml b/jee7/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000000..8a2c3eafe1
--- /dev/null
+++ b/jee7/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,13 @@
+
+
+ com.baeldung.arquillian.Car
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jee7/src/test/java/com/baeldung/arquillan/ArquillianTest.java b/jee7/src/test/java/com/baeldung/arquillan/ArquillianTest.java
new file mode 100644
index 0000000000..5219f221ca
--- /dev/null
+++ b/jee7/src/test/java/com/baeldung/arquillan/ArquillianTest.java
@@ -0,0 +1,73 @@
+package com.baeldung.arquillan;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import javax.inject.Inject;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.baeldung.arquillian.CapsConvertor;
+import com.baeldung.arquillian.CapsService;
+import com.baeldung.arquillian.Car;
+import com.baeldung.arquillian.CarEJB;
+import com.baeldung.arquillian.Component;
+import com.baeldung.arquillian.ConvertToLowerCase;
+
+@RunWith(Arquillian.class)
+public class ArquillianTest {
+
+ @Deployment
+ public static JavaArchive createDeployment() {
+ return ShrinkWrap.create(JavaArchive.class).addClasses(Component.class, CapsService.class, CapsConvertor.class, ConvertToLowerCase.class, Car.class, CarEJB.class).addAsResource("META-INF/persistence.xml").addAsManifestResource(EmptyAsset.INSTANCE,
+ "beans.xml");
+ }
+
+ @Inject
+ Component component;
+
+ @Test
+ public void givenMessage_WhenComponentSendMessage_ThenMessageReceived() {
+ Assert.assertEquals("Message, MESSAGE", component.message(("MESSAGE")));
+ component.sendMessage(System.out, "MESSAGE");
+ }
+
+ @Inject
+ private CapsService capsService;
+
+ @Test
+ public void givenWord_WhenUppercase_ThenLowercase() {
+ assertTrue("capitalize".equals(capsService.getConvertedCaps("CAPITALIZE")));
+ assertEquals("capitalize", capsService.getConvertedCaps("CAPITALIZE"));
+ }
+
+ @Inject
+ private CarEJB carEJB;
+
+ @Test
+ public void testCars() {
+ assertTrue(carEJB.findAllCars().isEmpty());
+ Car c1 = new Car();
+ c1.setName("Impala");
+ Car c2 = new Car();
+ c2.setName("Maverick");
+ Car c3 = new Car();
+ c3.setName("Aspen");
+ Car c4 = new Car();
+ c4.setName("Lincoln");
+ carEJB.saveCar(c1);
+ carEJB.saveCar(c2);
+ carEJB.saveCar(c3);
+ carEJB.saveCar(c4);
+ assertEquals(4, carEJB.findAllCars().size());
+ carEJB.deleteCar(c4);
+ assertEquals(3, carEJB.findAllCars().size());
+ }
+}
\ No newline at end of file
diff --git a/jee7/src/test/java/com/baeldung/convListVal/ConvListValTest.java b/jee7/src/test/java/com/baeldung/convListVal/ConvListValIntegrationTest.java
similarity index 98%
rename from jee7/src/test/java/com/baeldung/convListVal/ConvListValTest.java
rename to jee7/src/test/java/com/baeldung/convListVal/ConvListValIntegrationTest.java
index 4450a26f43..caeba95e45 100644
--- a/jee7/src/test/java/com/baeldung/convListVal/ConvListValTest.java
+++ b/jee7/src/test/java/com/baeldung/convListVal/ConvListValIntegrationTest.java
@@ -22,7 +22,7 @@ import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@RunWith(Arquillian.class)
-public class ConvListValTest {
+public class ConvListValIntegrationTest {
@ArquillianResource
private URL deploymentUrl;
diff --git a/jee7/src/test/resources/META-INF/persistence.xml b/jee7/src/test/resources/META-INF/persistence.xml
new file mode 100644
index 0000000000..8a2c3eafe1
--- /dev/null
+++ b/jee7/src/test/resources/META-INF/persistence.xml
@@ -0,0 +1,13 @@
+
+
+ com.baeldung.arquillian.Car
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jhipster/.editorconfig b/jhipster/jhipster-microservice/car-app/.editorconfig
similarity index 100%
rename from jhipster/.editorconfig
rename to jhipster/jhipster-microservice/car-app/.editorconfig
diff --git a/jhipster/.gitattributes b/jhipster/jhipster-microservice/car-app/.gitattributes
similarity index 100%
rename from jhipster/.gitattributes
rename to jhipster/jhipster-microservice/car-app/.gitattributes
diff --git a/jhipster/jhipster-microservice/car-app/.gitignore b/jhipster/jhipster-microservice/car-app/.gitignore
new file mode 100644
index 0000000000..74b29e2042
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/.gitignore
@@ -0,0 +1,141 @@
+######################
+# Project Specific
+######################
+/target/www/**
+/src/test/javascript/coverage/
+/src/test/javascript/PhantomJS*/
+
+######################
+# Node
+######################
+/node/
+node_tmp/
+node_modules/
+npm-debug.log.*
+
+######################
+# SASS
+######################
+.sass-cache/
+
+######################
+# Eclipse
+######################
+*.pydevproject
+.project
+.metadata
+tmp/
+tmp/**/*
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.classpath
+.settings/
+.loadpath
+.factorypath
+/src/main/resources/rebel.xml
+
+# External tool builders
+.externalToolBuilders/**
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# PDT-specific
+.buildpath
+
+######################
+# Intellij
+######################
+.idea/
+*.iml
+*.iws
+*.ipr
+*.ids
+*.orig
+
+######################
+# Visual Studio Code
+######################
+.vscode/
+
+######################
+# Maven
+######################
+/log/
+/target/
+
+######################
+# Gradle
+######################
+.gradle/
+/build/
+
+######################
+# Package Files
+######################
+*.jar
+*.war
+*.ear
+*.db
+
+######################
+# Windows
+######################
+# Windows image file caches
+Thumbs.db
+
+# Folder config file
+Desktop.ini
+
+######################
+# Mac OSX
+######################
+.DS_Store
+.svn
+
+# Thumbnails
+._*
+
+# Files that might appear on external disk
+.Spotlight-V100
+.Trashes
+
+######################
+# Directories
+######################
+/bin/
+/deploy/
+
+######################
+# Logs
+######################
+*.log
+
+######################
+# Others
+######################
+*.class
+*.*~
+*~
+.merge_file*
+
+######################
+# Gradle Wrapper
+######################
+!gradle/wrapper/gradle-wrapper.jar
+
+######################
+# Maven Wrapper
+######################
+!.mvn/wrapper/maven-wrapper.jar
+
+######################
+# ESLint
+######################
+.eslintcache
diff --git a/jhipster/jhipster-microservice/car-app/.jhipster/Car.json b/jhipster/jhipster-microservice/car-app/.jhipster/Car.json
new file mode 100644
index 0000000000..ceaef3cd63
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/.jhipster/Car.json
@@ -0,0 +1,25 @@
+{
+ "fluentMethods": true,
+ "relationships": [],
+ "fields": [
+ {
+ "fieldName": "make",
+ "fieldType": "String"
+ },
+ {
+ "fieldName": "brand",
+ "fieldType": "String"
+ },
+ {
+ "fieldName": "price",
+ "fieldType": "Double"
+ }
+ ],
+ "changelogDate": "20170503041524",
+ "dto": "no",
+ "service": "no",
+ "entityTableName": "car",
+ "pagination": "infinite-scroll",
+ "microserviceName": "carapp",
+ "searchEngine": false
+}
diff --git a/jhipster/.mvn/wrapper/maven-wrapper.jar b/jhipster/jhipster-microservice/car-app/.mvn/wrapper/maven-wrapper.jar
similarity index 100%
rename from jhipster/.mvn/wrapper/maven-wrapper.jar
rename to jhipster/jhipster-microservice/car-app/.mvn/wrapper/maven-wrapper.jar
diff --git a/jhipster/.mvn/wrapper/maven-wrapper.properties b/jhipster/jhipster-microservice/car-app/.mvn/wrapper/maven-wrapper.properties
similarity index 100%
rename from jhipster/.mvn/wrapper/maven-wrapper.properties
rename to jhipster/jhipster-microservice/car-app/.mvn/wrapper/maven-wrapper.properties
diff --git a/jhipster/jhipster-microservice/car-app/.yo-rc.json b/jhipster/jhipster-microservice/car-app/.yo-rc.json
new file mode 100644
index 0000000000..896ab47839
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/.yo-rc.json
@@ -0,0 +1,29 @@
+{
+ "generator-jhipster": {
+ "jhipsterVersion": "4.0.8",
+ "baseName": "carapp",
+ "packageName": "com.car.app",
+ "packageFolder": "com/car/app",
+ "serverPort": "8081",
+ "authenticationType": "jwt",
+ "hibernateCache": "hazelcast",
+ "clusteredHttpSession": false,
+ "websocket": false,
+ "databaseType": "sql",
+ "devDatabaseType": "h2Disk",
+ "prodDatabaseType": "mysql",
+ "searchEngine": false,
+ "messageBroker": false,
+ "serviceDiscoveryType": "eureka",
+ "buildTool": "maven",
+ "enableSocialSignIn": false,
+ "jwtSecretKey": "0ebd193e0552c4ac548217d353abbde0761a1997",
+ "enableTranslation": false,
+ "applicationType": "microservice",
+ "testFrameworks": [],
+ "jhiPrefix": "jhi",
+ "skipClient": true,
+ "skipUserManagement": true,
+ "clientPackageManager": "yarn"
+ }
+}
\ No newline at end of file
diff --git a/jhipster/jhipster-microservice/car-app/README.md b/jhipster/jhipster-microservice/car-app/README.md
new file mode 100644
index 0000000000..7dcbb23bb1
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/README.md
@@ -0,0 +1,75 @@
+# carapp
+This application was generated using JHipster 4.0.8, you can find documentation and help at [https://jhipster.github.io/documentation-archive/v4.0.8](https://jhipster.github.io/documentation-archive/v4.0.8).
+
+This is a "microservice" application intended to be part of a microservice architecture, please refer to the [Doing microservices with JHipster][] page of the documentation for more information.
+
+This application is configured for Service Discovery and Configuration with the JHipster-Registry. On launch, it will refuse to start if it is not able to connect to the JHipster-Registry at [http://localhost:8761](http://localhost:8761). For more information, read our documentation on [Service Discovery and Configuration with the JHipster-Registry][].
+
+## Development
+
+To start your application in the dev profile, simply run:
+
+ ./mvnw
+
+
+For further instructions on how to develop with JHipster, have a look at [Using JHipster in development][].
+
+
+## Building for production
+
+To optimize the carapp application for production, run:
+
+ ./mvnw -Pprod clean package
+
+To ensure everything worked, run:
+
+ java -jar target/*.war
+
+
+Refer to [Using JHipster in production][] for more details.
+
+## Testing
+
+To launch your application's tests, run:
+
+ ./mvnw clean test
+
+For more information, refer to the [Running tests page][].
+
+## Using Docker to simplify development (optional)
+
+You can use Docker to improve your JHipster development experience. A number of docker-compose configuration are available in the [src/main/docker](src/main/docker) folder to launch required third party services.
+For example, to start a mysql database in a docker container, run:
+
+ docker-compose -f src/main/docker/mysql.yml up -d
+
+To stop it and remove the container, run:
+
+ docker-compose -f src/main/docker/mysql.yml down
+
+You can also fully dockerize your application and all the services that it depends on.
+To achieve this, first build a docker image of your app by running:
+
+ ./mvnw package -Pprod docker:build
+
+Then run:
+
+ docker-compose -f src/main/docker/app.yml up -d
+
+For more information refer to [Using Docker and Docker-Compose][], this page also contains information on the docker-compose sub-generator (`yo jhipster:docker-compose`), which is able to generate docker configurations for one or several JHipster applications.
+
+## Continuous Integration (optional)
+
+To configure CI for your project, run the ci-cd sub-generator (`yo jhipster:ci-cd`), this will let you generate configuration files for a number of Continuous Integration systems. Consult the [Setting up Continuous Integration][] page for more information.
+
+[JHipster Homepage and latest documentation]: https://jhipster.github.io
+[JHipster 4.0.8 archive]: https://jhipster.github.io/documentation-archive/v4.0.8
+[Doing microservices with JHipster]: https://jhipster.github.io/documentation-archive/v4.0.8/microservices-architecture/
+[Using JHipster in development]: https://jhipster.github.io/documentation-archive/v4.0.8/development/
+[Service Discovery and Configuration with the JHipster-Registry]: https://jhipster.github.io/documentation-archive/v4.0.8/microservices-architecture/#jhipster-registry
+[Using Docker and Docker-Compose]: https://jhipster.github.io/documentation-archive/v4.0.8/docker-compose
+[Using JHipster in production]: https://jhipster.github.io/documentation-archive/v4.0.8/production/
+[Running tests page]: https://jhipster.github.io/documentation-archive/v4.0.8/running-tests/
+[Setting up Continuous Integration]: https://jhipster.github.io/documentation-archive/v4.0.8/setting-up-ci/
+
+
diff --git a/jhipster/mvnw b/jhipster/jhipster-microservice/car-app/mvnw
similarity index 100%
rename from jhipster/mvnw
rename to jhipster/jhipster-microservice/car-app/mvnw
diff --git a/jhipster/mvnw.cmd b/jhipster/jhipster-microservice/car-app/mvnw.cmd
similarity index 100%
rename from jhipster/mvnw.cmd
rename to jhipster/jhipster-microservice/car-app/mvnw.cmd
diff --git a/jhipster/jhipster-microservice/car-app/package.json b/jhipster/jhipster-microservice/car-app/package.json
new file mode 100644
index 0000000000..ac56dd89a7
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/package.json
@@ -0,0 +1,5 @@
+{
+ "devDependencies": {
+ "generator-jhipster": "4.0.8"
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/pom.xml b/jhipster/jhipster-microservice/car-app/pom.xml
new file mode 100644
index 0000000000..23da8767cb
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/pom.xml
@@ -0,0 +1,925 @@
+
+
+ 4.0.0
+
+
+ parent-boot-5
+ com.baeldung
+ 0.0.1-SNAPSHOT
+ ../../../parent-boot-5
+
+
+ com.car.app
+ carapp
+ 0.0.1-SNAPSHOT
+ war
+ Carapp
+
+
+ ${maven.version}
+
+
+
+ -Djava.security.egd=file:/dev/./urandom -Xmx256m
+ 3.6.2
+ 2.0.0
+ 2.5
+ 3.5
+ 0.4.13
+ 1.2
+ 5.2.8.Final
+ 2.6.0
+ 0.7.9
+ 1.8
+ 3.21.0-GA
+ 1.0.0
+ 1.1.0
+ 0.7.0
+ 3.6
+ 2.0.0
+ 4.8
+ jdt_apt
+ 1.1.0.Final
+ 1.4.1
+ 3.0.1
+ yyyyMMddHHmmss
+ 3.0.0
+ 3.1.3
+ v6.10.0
+
+
+
+
+ ${project.build.directory}/test-results
+ 0.0.20
+ false
+ 3.2.2
+ 2.12.1
+ 3.2
+
+ src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.*
+
+ S3437,UndocumentedApi,BoldAndItalicTagsCheck
+
+
+ src/main/webapp/app/**/*.*
+ Web:BoldAndItalicTagsCheck
+
+ src/main/java/**/*
+ squid:S3437
+
+ src/main/java/**/*
+ squid:UndocumentedApi
+
+ ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec
+ ${project.testresult.directory}/coverage/jacoco/jacoco.exec
+ jacoco
+
+ ${project.testresult.directory}/karma
+
+ ${project.testresult.directory}/coverage/report-lcov/lcov.info
+
+ ${project.testresult.directory}/coverage/report-lcov/lcov.info
+
+ ${project.basedir}/src/main/
+ ${project.testresult.directory}/surefire-reports
+ ${project.basedir}/src/test/
+
+ 2.5.0
+
+ Camden.SR5
+ 2.6.1
+ 1.4.10.Final
+ 1.1.0.Final
+ v0.21.3
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-hibernate5
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-hppc
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-json-org
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+ com.h2database
+ h2
+
+
+ com.hazelcast
+ hazelcast
+
+
+ com.hazelcast
+ hazelcast-hibernate52
+ ${hazelcast-hibernate52.version}
+
+
+ com.hazelcast
+ hazelcast-spring
+
+
+ com.jayway.jsonpath
+ json-path
+ test
+
+
+
+ com.mattbertolini
+ liquibase-slf4j
+ ${liquibase-slf4j.version}
+
+
+ com.ryantenney.metrics
+ metrics-spring
+ ${metrics-spring.version}
+
+
+ metrics-annotation
+ com.codahale.metrics
+
+
+ metrics-core
+ com.codahale.metrics
+
+
+ metrics-healthchecks
+ com.codahale.metrics
+
+
+
+
+ com.zaxxer
+ HikariCP
+
+
+ tools
+ com.sun
+
+
+
+
+
+ commons-io
+ commons-io
+ ${commons-io.version}
+
+
+ io.dropwizard.metrics
+ metrics-annotation
+ ${dropwizard-metrics.version}
+
+
+ io.dropwizard.metrics
+ metrics-core
+
+
+ io.dropwizard.metrics
+ metrics-json
+ ${dropwizard-metrics.version}
+
+
+ io.dropwizard.metrics
+ metrics-jvm
+ ${dropwizard-metrics.version}
+
+
+ io.dropwizard.metrics
+ metrics-servlet
+ ${dropwizard-metrics.version}
+
+
+ io.dropwizard.metrics
+ metrics-servlets
+
+
+ io.github.jhipster
+ jhipster
+ ${jhipster.server.version}
+
+
+ io.jsonwebtoken
+ jjwt
+ ${jjwt.version}
+
+
+ io.springfox
+ springfox-bean-validators
+ ${springfox.version}
+
+
+ io.springfox
+ springfox-swagger2
+ ${springfox.version}
+
+
+ mapstruct
+ org.mapstruct
+
+
+
+
+ javax.cache
+ cache-api
+
+
+ mysql
+ mysql-connector-java
+
+
+ net.logstash.logback
+ logstash-logback-encoder
+ ${logstash-logback-encoder.version}
+
+
+ logback-core
+ ch.qos.logback
+
+
+ logback-classic
+ ch.qos.logback
+
+
+ logback-access
+ ch.qos.logback
+
+
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang.version}
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+ org.awaitility
+ awaitility
+ ${awaitility.version}
+ test
+
+
+ org.hibernate
+ hibernate-envers
+
+
+ org.hibernate
+ hibernate-validator
+
+
+ org.liquibase
+ liquibase-core
+
+
+ jetty-servlet
+ org.eclipse.jetty
+
+
+
+
+ org.mapstruct
+ mapstruct-jdk8
+ ${mapstruct.version}
+
+
+ org.springframework
+ spring-context-support
+
+
+ org.springframework.boot
+ spring-boot-actuator
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+ org.springframework.boot
+ spring-boot-loader-tools
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+ org.springframework.boot
+ spring-boot-starter-cloud-connectors
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-logging
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ spring-boot-starter-tomcat
+ org.springframework.boot
+
+
+
+
+ org.springframework.boot
+ spring-boot-test
+ test
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter
+
+
+ org.springframework.cloud
+ spring-cloud-starter-config
+
+
+ org.springframework.cloud
+ spring-cloud-starter-eureka
+
+
+ org.springframework.cloud
+ spring-cloud-starter-feign
+
+
+ org.springframework.cloud
+ spring-cloud-starter-hystrix
+
+
+ org.springframework.cloud
+ spring-cloud-starter-ribbon
+
+
+
+ netty-transport-native-epoll
+ io.netty
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-spectator
+
+
+ org.springframework.retry
+ spring-retry
+
+
+
+ org.springframework.security
+ spring-security-data
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
+
+
+
+ spring-boot:run
+
+
+
+
+ org.eclipse.m2e
+ lifecycle-mapping
+ 1.0.0
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco-maven-plugin.version}
+
+ prepare-agent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ com.github.ekryd.sortpom
+ sortpom-maven-plugin
+ ${sortpom-maven-plugin.version}
+
+
+ verify
+
+ sort
+
+
+
+
+ true
+ 4
+ groupId,artifactId
+ groupId,artifactId
+ true
+ false
+
+
+
+ com.spotify
+ docker-maven-plugin
+ ${docker-maven-plugin.version}
+
+ carapp
+ src/main/docker
+
+
+ /
+ ${project.build.directory}
+ ${project.build.finalName}.war
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${mapstruct.version}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-eclipse-plugin
+
+ true
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ ${maven-enforcer-plugin.version}
+
+
+ enforce-versions
+
+ enforce
+
+
+
+
+
+
+ You are running an older version of Maven. JHipster requires at least Maven ${maven.version}
+ [${maven.version},)
+
+
+ You are running an older version of Java. JHipster requires at least JDK ${java.version}
+ [${java.version}.0,)
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ ${maven-resources-plugin.version}
+
+
+ default-resources
+ validate
+
+ copy-resources
+
+
+ target/classes
+ false
+
+ #
+
+
+
+ src/main/resources/
+ true
+
+ **/*.xml
+ **/*.yml
+
+
+
+ src/main/resources/
+ false
+
+ **/*.xml
+ **/*.yml
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ alphabetical
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco-maven-plugin.version}
+
+
+ pre-unit-tests
+
+ prepare-agent
+
+
+
+ ${project.testresult.directory}/coverage/jacoco/jacoco.exec
+
+
+
+
+ post-unit-test
+ test
+
+ report
+
+
+ ${project.testresult.directory}/coverage/jacoco/jacoco.exec
+ ${project.testresult.directory}/coverage/jacoco
+
+
+
+
+
+ org.liquibase
+ liquibase-maven-plugin
+ ${liquibase.version}
+
+
+ javax.validation
+ validation-api
+ ${validation-api.version}
+
+
+ org.javassist
+ javassist
+ ${javassist.version}
+
+
+ org.liquibase.ext
+ liquibase-hibernate5
+ ${liquibase-hibernate5.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+ ${project.parent.version}
+
+
+
+ src/main/resources/config/liquibase/master.xml
+ src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml
+ org.h2.Driver
+ jdbc:h2:file:./target/h2db/db/carapp
+
+ carapp
+
+ hibernate:spring:com.car.app.domain?dialect=org.hibernate.dialect.H2Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
+ true
+ debug
+
+
+
+ org.sonarsource.scanner.maven
+ sonar-maven-plugin
+ ${sonar-maven-plugin.version}
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+ true
+
+
+
+
+
+
+
+
+ no-liquibase
+
+ ,no-liquibase
+
+
+
+ swagger
+
+ ,swagger
+
+
+
+ dev
+
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+
+
+
+
+
+ DEBUG
+
+ dev${profile.no-liquibase}
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-undertow
+
+
+
+
+ prod
+
+
+
+ maven-clean-plugin
+
+
+
+ target/www/
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ build-info
+
+
+
+
+ true
+
+
+
+
+
+
+ INFO
+
+ prod${profile.swagger}${profile.no-liquibase}
+
+
+
+ org.springframework.boot
+ spring-boot-starter-undertow
+
+
+
+
+
+ cc
+
+
+
+ net.alchim31.maven
+ scala-maven-plugin
+ ${scala-maven-plugin.version}
+
+
+ compile
+ compile
+
+ add-source
+ compile
+
+
+
+ test-compile
+ test-compile
+
+ add-source
+ testCompile
+
+
+
+
+ incremental
+ true
+ ${scala.version}
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ default-compile
+ none
+
+
+ default-testCompile
+ none
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ src/main/webapp/
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+ DEBUG
+
+ dev,swagger
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-undertow
+
+
+
+
+
+ graphite
+
+
+ io.dropwizard.metrics
+ metrics-graphite
+
+
+
+
+
+ prometheus
+
+
+ io.prometheus
+ simpleclient
+ ${prometheus-simpleclient.version}
+
+
+ io.prometheus
+ simpleclient_dropwizard
+ ${prometheus-simpleclient.version}
+
+
+ io.prometheus
+ simpleclient_servlet
+ ${prometheus-simpleclient.version}
+
+
+
+
+
+ IDE
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${mapstruct.version}
+
+
+
+
+
diff --git a/jhipster/jhipster-microservice/car-app/src/main/docker/Dockerfile b/jhipster/jhipster-microservice/car-app/src/main/docker/Dockerfile
new file mode 100644
index 0000000000..037e197be6
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/docker/Dockerfile
@@ -0,0 +1,13 @@
+FROM openjdk:8-jre-alpine
+
+ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
+ JHIPSTER_SLEEP=0
+
+# add directly the war
+ADD *.war /app.war
+
+VOLUME /tmp
+EXPOSE 8081 5701/udp
+CMD echo "The application will start in ${JHIPSTER_SLEEP}s..." && \
+ sleep ${JHIPSTER_SLEEP} && \
+ java -Djava.security.egd=file:/dev/./urandom -jar /app.war
diff --git a/jhipster/jhipster-microservice/car-app/src/main/docker/app.yml b/jhipster/jhipster-microservice/car-app/src/main/docker/app.yml
new file mode 100644
index 0000000000..0904a7335d
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/docker/app.yml
@@ -0,0 +1,19 @@
+version: '2'
+services:
+ carapp-app:
+ image: carapp
+ environment:
+ - SPRING_PROFILES_ACTIVE=prod,swagger
+ - SPRING_CLOUD_CONFIG_URI=http://admin:$${jhipster.registry.password}@jhipster-registry:8761/config
+ - SPRING_DATASOURCE_URL=jdbc:mysql://carapp-mysql:3306/carapp?useUnicode=true&characterEncoding=utf8&useSSL=false
+ - JHIPSTER_SLEEP=10 # gives time for the database to boot before the application
+ carapp-mysql:
+ extends:
+ file: mysql.yml
+ service: carapp-mysql
+ jhipster-registry:
+ extends:
+ file: jhipster-registry.yml
+ service: jhipster-registry
+ environment:
+ - SPRING_CLOUD_CONFIG_SERVER_NATIVE_SEARCH_LOCATIONS=file:./central-config/docker-config/
diff --git a/jhipster/jhipster-microservice/car-app/src/main/docker/central-server-config/README.md b/jhipster/jhipster-microservice/car-app/src/main/docker/central-server-config/README.md
new file mode 100644
index 0000000000..022a152863
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/docker/central-server-config/README.md
@@ -0,0 +1,7 @@
+# Central configuration sources details
+
+The JHipster-Registry will use the following directories as its configuration source :
+- localhost-config : when running the registry in docker with the jhipster-registry.yml docker-compose file
+- docker-config : when running the registry and the app both in docker with the app.yml docker-compose file
+
+For more info, refer to http://jhipster.github.io/microservices-architecture/#registry_app_configuration
diff --git a/jhipster/jhipster-microservice/car-app/src/main/docker/central-server-config/docker-config/application.yml b/jhipster/jhipster-microservice/car-app/src/main/docker/central-server-config/docker-config/application.yml
new file mode 100644
index 0000000000..f11d367241
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/docker/central-server-config/docker-config/application.yml
@@ -0,0 +1,15 @@
+# Common configuration shared between all applications
+configserver:
+ name: Docker JHipster Registry
+ status: Connected to the JHipster Registry running in Docker
+
+jhipster:
+ security:
+ authentication:
+ jwt:
+ secret: my-secret-token-to-change-in-production
+
+eureka:
+ client:
+ serviceUrl:
+ defaultZone: http://admin:${jhipster.registry.password}@jhipster-registry:8761/eureka/
diff --git a/jhipster/jhipster-microservice/car-app/src/main/docker/central-server-config/localhost-config/application.yml b/jhipster/jhipster-microservice/car-app/src/main/docker/central-server-config/localhost-config/application.yml
new file mode 100644
index 0000000000..052a6d0535
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/docker/central-server-config/localhost-config/application.yml
@@ -0,0 +1,15 @@
+# Common configuration shared between all applications
+configserver:
+ name: Docker JHipster Registry
+ status: Connected to the JHipster Registry running in Docker
+
+jhipster:
+ security:
+ authentication:
+ jwt:
+ secret: my-secret-token-to-change-in-production
+
+eureka:
+ client:
+ serviceUrl:
+ defaultZone: http://admin:${jhipster.registry.password}@localhost:8761/eureka/
diff --git a/jhipster/jhipster-microservice/car-app/src/main/docker/jhipster-registry.yml b/jhipster/jhipster-microservice/car-app/src/main/docker/jhipster-registry.yml
new file mode 100644
index 0000000000..58feb685d4
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/docker/jhipster-registry.yml
@@ -0,0 +1,18 @@
+version: '2'
+services:
+ jhipster-registry:
+ image: jhipster/jhipster-registry:v2.5.8
+ volumes:
+ - ./central-server-config:/central-config
+ # When run with the "dev" Spring profile, the JHipster Registry will
+ # read the config from the local filesystem (central-server-config directory)
+ # When run with the "prod" Spring profile, it will read the config from a git repository
+ # See http://jhipster.github.io/microservices-architecture/#registry_app_configuration
+ environment:
+ - SPRING_PROFILES_ACTIVE=dev
+ - SECURITY_USER_PASSWORD=admin
+ - SPRING_CLOUD_CONFIG_SERVER_NATIVE_SEARCH_LOCATIONS=file:./central-config/localhost-config/
+ # - GIT_URI=https://github.com/jhipster/jhipster-registry/
+ # - GIT_SEARCH_PATHS=central-config
+ ports:
+ - 8761:8761
diff --git a/jhipster/jhipster-microservice/car-app/src/main/docker/mysql.yml b/jhipster/jhipster-microservice/car-app/src/main/docker/mysql.yml
new file mode 100644
index 0000000000..151facca36
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/docker/mysql.yml
@@ -0,0 +1,13 @@
+version: '2'
+services:
+ carapp-mysql:
+ image: mysql:5.7.13
+ # volumes:
+ # - ~/volumes/jhipster/carapp/mysql/:/var/lib/mysql/
+ environment:
+ - MYSQL_USER=root
+ - MYSQL_ALLOW_EMPTY_PASSWORD=yes
+ - MYSQL_DATABASE=carapp
+ ports:
+ - 3306:3306
+ command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8
diff --git a/jhipster/jhipster-microservice/car-app/src/main/docker/sonar.yml b/jhipster/jhipster-microservice/car-app/src/main/docker/sonar.yml
new file mode 100644
index 0000000000..353e034f40
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/docker/sonar.yml
@@ -0,0 +1,7 @@
+version: '2'
+services:
+ carapp-sonar:
+ image: sonarqube:6.2-alpine
+ ports:
+ - 9000:9000
+ - 9092:9092
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/ApplicationWebXml.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/ApplicationWebXml.java
new file mode 100644
index 0000000000..edd9098f8a
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/ApplicationWebXml.java
@@ -0,0 +1,21 @@
+package com.car.app;
+
+import com.car.app.config.DefaultProfileUtil;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+
+/**
+ * This is a helper Java class that provides an alternative to creating a web.xml.
+ * This will be invoked only when the application is deployed to a servlet container like Tomcat, JBoss etc.
+ */
+public class ApplicationWebXml extends SpringBootServletInitializer {
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ /**
+ * set a default to use when no profile is configured.
+ */
+ DefaultProfileUtil.addDefaultProfile(application.application());
+ return application.sources(CarappApp.class);
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/CarappApp.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/CarappApp.java
new file mode 100644
index 0000000000..b85a50b156
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/CarappApp.java
@@ -0,0 +1,91 @@
+package com.car.app;
+
+import com.car.app.config.ApplicationProperties;
+import com.car.app.config.DefaultProfileUtil;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.actuate.autoconfigure.*;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.core.env.Environment;
+
+import javax.annotation.PostConstruct;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.Collection;
+
+@ComponentScan
+@EnableAutoConfiguration(exclude = {MetricFilterAutoConfiguration.class, MetricRepositoryAutoConfiguration.class})
+@EnableConfigurationProperties({LiquibaseProperties.class, ApplicationProperties.class})
+@EnableDiscoveryClient
+public class CarappApp {
+
+ private static final Logger log = LoggerFactory.getLogger(CarappApp.class);
+
+ private final Environment env;
+
+ public CarappApp(Environment env) {
+ this.env = env;
+ }
+
+ /**
+ * Initializes carapp.
+ *
+ * Spring profiles can be configured with a program arguments --spring.profiles.active=your-active-profile
+ *
+ * You can find more information on how profiles work with JHipster on http://jhipster.github.io/profiles/.
+ */
+ @PostConstruct
+ public void initApplication() {
+ Collection activeProfiles = Arrays.asList(env.getActiveProfiles());
+ if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
+ log.error("You have misconfigured your application! It should not run " +
+ "with both the 'dev' and 'prod' profiles at the same time.");
+ }
+ if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD)) {
+ log.error("You have misconfigured your application! It should not" +
+ "run with both the 'dev' and 'cloud' profiles at the same time.");
+ }
+ }
+
+ /**
+ * Main method, used to run the application.
+ *
+ * @param args the command line arguments
+ * @throws UnknownHostException if the local host name could not be resolved into an address
+ */
+ public static void main(String[] args) throws UnknownHostException {
+ SpringApplication app = new SpringApplication(CarappApp.class);
+ DefaultProfileUtil.addDefaultProfile(app);
+ Environment env = app.run(args).getEnvironment();
+ String protocol = "http";
+ if (env.getProperty("server.ssl.key-store") != null) {
+ protocol = "https";
+ }
+ log.info("\n----------------------------------------------------------\n\t" +
+ "Application '{}' is running! Access URLs:\n\t" +
+ "Local: \t\t{}://localhost:{}\n\t" +
+ "External: \t{}://{}:{}\n\t" +
+ "Profile(s): \t{}\n----------------------------------------------------------",
+ env.getProperty("spring.application.name"),
+ protocol,
+ env.getProperty("server.port"),
+ protocol,
+ InetAddress.getLocalHost().getHostAddress(),
+ env.getProperty("server.port"),
+ env.getActiveProfiles());
+
+ String configServerStatus = env.getProperty("configserver.status");
+ log.info("\n----------------------------------------------------------\n\t" +
+ "Config Server: \t{}\n----------------------------------------------------------",
+ configServerStatus == null ? "Not found or not setup for this application" : configServerStatus);
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/aop/logging/LoggingAspect.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/aop/logging/LoggingAspect.java
new file mode 100644
index 0000000000..7171abbcd2
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/aop/logging/LoggingAspect.java
@@ -0,0 +1,79 @@
+package com.car.app.aop.logging;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.env.Environment;
+
+import java.util.Arrays;
+
+/**
+ * Aspect for logging execution of service and repository Spring components.
+ *
+ * By default, it only runs with the "dev" profile.
+ */
+@Aspect
+public class LoggingAspect {
+
+ private final Logger log = LoggerFactory.getLogger(this.getClass());
+
+ private final Environment env;
+
+ public LoggingAspect(Environment env) {
+ this.env = env;
+ }
+
+ /**
+ * Pointcut that matches all repositories, services and Web REST endpoints.
+ */
+ @Pointcut("within(com.car.app.repository..*) || within(com.car.app.service..*) || within(com.car.app.web.rest..*)")
+ public void loggingPointcut() {
+ // Method is empty as this is just a Pointcut, the implementations are in the advices.
+ }
+
+ /**
+ * Advice that logs methods throwing exceptions.
+ */
+ @AfterThrowing(pointcut = "loggingPointcut()", throwing = "e")
+ public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
+ log.error("Exception in {}.{}() with cause = \'{}\' and exception = \'{}\'", joinPoint.getSignature().getDeclaringTypeName(),
+ joinPoint.getSignature().getName(), e.getCause() != null? e.getCause() : "NULL", e.getMessage(), e);
+
+ } else {
+ log.error("Exception in {}.{}() with cause = {}", joinPoint.getSignature().getDeclaringTypeName(),
+ joinPoint.getSignature().getName(), e.getCause() != null? e.getCause() : "NULL");
+ }
+ }
+
+ /**
+ * Advice that logs when a method is entered and exited.
+ */
+ @Around("loggingPointcut()")
+ public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
+ if (log.isDebugEnabled()) {
+ log.debug("Enter: {}.{}() with argument[s] = {}", joinPoint.getSignature().getDeclaringTypeName(),
+ joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs()));
+ }
+ try {
+ Object result = joinPoint.proceed();
+ if (log.isDebugEnabled()) {
+ log.debug("Exit: {}.{}() with result = {}", joinPoint.getSignature().getDeclaringTypeName(),
+ joinPoint.getSignature().getName(), result);
+ }
+ return result;
+ } catch (IllegalArgumentException e) {
+ log.error("Illegal argument: {} in {}.{}()", Arrays.toString(joinPoint.getArgs()),
+ joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
+
+ throw e;
+ }
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/ApplicationProperties.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/ApplicationProperties.java
new file mode 100644
index 0000000000..1f69dd1529
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/ApplicationProperties.java
@@ -0,0 +1,15 @@
+package com.car.app.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Properties specific to JHipster.
+ *
+ *
+ * Properties are configured in the application.yml file.
+ *
+ */
+@ConfigurationProperties(prefix = "application", ignoreUnknownFields = false)
+public class ApplicationProperties {
+
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/AsyncConfiguration.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/AsyncConfiguration.java
new file mode 100644
index 0000000000..67cb2ad402
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/AsyncConfiguration.java
@@ -0,0 +1,46 @@
+package com.car.app.config;
+
+import io.github.jhipster.async.ExceptionHandlingAsyncTaskExecutor;
+import io.github.jhipster.config.JHipsterProperties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
+import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.*;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+
+@Configuration
+@EnableAsync
+@EnableScheduling
+public class AsyncConfiguration implements AsyncConfigurer {
+
+ private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class);
+
+ private final JHipsterProperties jHipsterProperties;
+
+ public AsyncConfiguration(JHipsterProperties jHipsterProperties) {
+ this.jHipsterProperties = jHipsterProperties;
+ }
+
+ @Override
+ @Bean(name = "taskExecutor")
+ public Executor getAsyncExecutor() {
+ log.debug("Creating Async Task Executor");
+ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+ executor.setCorePoolSize(jHipsterProperties.getAsync().getCorePoolSize());
+ executor.setMaxPoolSize(jHipsterProperties.getAsync().getMaxPoolSize());
+ executor.setQueueCapacity(jHipsterProperties.getAsync().getQueueCapacity());
+ executor.setThreadNamePrefix("carapp-Executor-");
+ return new ExceptionHandlingAsyncTaskExecutor(executor);
+ }
+
+ @Override
+ public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+ return new SimpleAsyncUncaughtExceptionHandler();
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/CacheConfiguration.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/CacheConfiguration.java
new file mode 100644
index 0000000000..0fdfff40f8
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/CacheConfiguration.java
@@ -0,0 +1,134 @@
+package com.car.app.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+import io.github.jhipster.config.JHipsterProperties;
+
+import com.hazelcast.config.Config;
+import com.hazelcast.core.HazelcastInstance;
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.config.MapConfig;
+import com.hazelcast.config.EvictionPolicy;
+import com.hazelcast.config.MaxSizeConfig;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.context.annotation.*;
+import org.springframework.core.env.Environment;
+
+import javax.annotation.PreDestroy;
+
+@Configuration
+@EnableCaching
+@AutoConfigureAfter(value = { MetricsConfiguration.class })
+@AutoConfigureBefore(value = { WebConfigurer.class, DatabaseConfiguration.class })
+public class CacheConfiguration {
+
+ private final Logger log = LoggerFactory.getLogger(CacheConfiguration.class);
+
+ private final Environment env;
+
+ private final DiscoveryClient discoveryClient;
+
+ private final ServerProperties serverProperties;
+
+ public CacheConfiguration(Environment env, DiscoveryClient discoveryClient, ServerProperties serverProperties) {
+ this.env = env;
+ this.discoveryClient = discoveryClient;
+ this.serverProperties = serverProperties;
+ }
+
+ @PreDestroy
+ public void destroy() {
+ log.info("Closing Cache Manager");
+ Hazelcast.shutdownAll();
+ }
+
+ @Bean
+ public CacheManager cacheManager(HazelcastInstance hazelcastInstance) {
+ log.debug("Starting HazelcastCacheManager");
+ CacheManager cacheManager = new com.hazelcast.spring.cache.HazelcastCacheManager(hazelcastInstance);
+ return cacheManager;
+ }
+
+ @Bean
+ public HazelcastInstance hazelcastInstance(JHipsterProperties jHipsterProperties) {
+ log.debug("Configuring Hazelcast");
+ Config config = new Config();
+ config.setInstanceName("carapp");
+ // The serviceId is by default the application's name, see Spring Boot's eureka.instance.appname property
+ String serviceId = discoveryClient.getLocalServiceInstance().getServiceId();
+ log.debug("Configuring Hazelcast clustering for instanceId: {}", serviceId);
+
+ // In development, everything goes through 127.0.0.1, with a different port
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
+ log.debug("Application is running with the \"dev\" profile, Hazelcast " +
+ "cluster will only work with localhost instances");
+
+ System.setProperty("hazelcast.local.localAddress", "127.0.0.1");
+ config.getNetworkConfig().setPort(serverProperties.getPort() + 5701);
+ config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(true);
+ for (ServiceInstance instance : discoveryClient.getInstances(serviceId)) {
+ String clusterMember = "127.0.0.1:" + (instance.getPort() + 5701);
+ log.debug("Adding Hazelcast (dev) cluster member " + clusterMember);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().addMember(clusterMember);
+ }
+ } else { // Production configuration, one host per instance all using port 5701
+ config.getNetworkConfig().setPort(5701);
+ config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(true);
+ for (ServiceInstance instance : discoveryClient.getInstances(serviceId)) {
+ String clusterMember = instance.getHost() + ":5701";
+ log.debug("Adding Hazelcast (prod) cluster member " + clusterMember);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().addMember(clusterMember);
+ }
+ }
+ config.getMapConfigs().put("default", initializeDefaultMapConfig());
+ config.getMapConfigs().put("com.car.app.domain.*", initializeDomainMapConfig(jHipsterProperties));
+ return Hazelcast.newHazelcastInstance(config);
+ }
+
+ private MapConfig initializeDefaultMapConfig() {
+ MapConfig mapConfig = new MapConfig();
+
+ /*
+ Number of backups. If 1 is set as the backup-count for example,
+ then all entries of the map will be copied to another JVM for
+ fail-safety. Valid numbers are 0 (no backup), 1, 2, 3.
+ */
+ mapConfig.setBackupCount(0);
+
+ /*
+ Valid values are:
+ NONE (no eviction),
+ LRU (Least Recently Used),
+ LFU (Least Frequently Used).
+ NONE is the default.
+ */
+ mapConfig.setEvictionPolicy(EvictionPolicy.LRU);
+
+ /*
+ Maximum size of the map. When max size is reached,
+ map is evicted based on the policy defined.
+ Any integer between 0 and Integer.MAX_VALUE. 0 means
+ Integer.MAX_VALUE. Default is 0.
+ */
+ mapConfig.setMaxSizeConfig(new MaxSizeConfig(0, MaxSizeConfig.MaxSizePolicy.USED_HEAP_SIZE));
+
+ return mapConfig;
+ }
+
+ private MapConfig initializeDomainMapConfig(JHipsterProperties jHipsterProperties) {
+ MapConfig mapConfig = new MapConfig();
+ mapConfig.setTimeToLiveSeconds(jHipsterProperties.getCache().getHazelcast().getTimeToLiveSeconds());
+ return mapConfig;
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/CloudDatabaseConfiguration.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/CloudDatabaseConfiguration.java
new file mode 100644
index 0000000000..2ca29491c9
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/CloudDatabaseConfiguration.java
@@ -0,0 +1,24 @@
+package com.car.app.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cache.CacheManager;
+import org.springframework.cloud.config.java.AbstractCloudConfig;
+import org.springframework.context.annotation.*;
+
+import javax.sql.DataSource;
+
+@Configuration
+@Profile(JHipsterConstants.SPRING_PROFILE_CLOUD)
+public class CloudDatabaseConfiguration extends AbstractCloudConfig {
+
+ private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class);
+
+ @Bean
+ public DataSource dataSource(CacheManager cacheManager) {
+ log.info("Configuring JDBC datasource from a cloud provider");
+ return connectionFactory().dataSource();
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/Constants.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/Constants.java
new file mode 100644
index 0000000000..260a3bbce8
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/Constants.java
@@ -0,0 +1,16 @@
+package com.car.app.config;
+
+/**
+ * Application constants.
+ */
+public final class Constants {
+
+ //Regex for acceptable logins
+ public static final String LOGIN_REGEX = "^[_'.@A-Za-z0-9-]*$";
+
+ public static final String SYSTEM_ACCOUNT = "system";
+ public static final String ANONYMOUS_USER = "anonymoususer";
+
+ private Constants() {
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/DatabaseConfiguration.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/DatabaseConfiguration.java
new file mode 100644
index 0000000000..35a8ee3f48
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/DatabaseConfiguration.java
@@ -0,0 +1,75 @@
+package com.car.app.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+import io.github.jhipster.config.liquibase.AsyncSpringLiquibase;
+
+import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
+import liquibase.integration.spring.SpringLiquibase;
+import org.h2.tools.Server;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.env.Environment;
+import org.springframework.core.task.TaskExecutor;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+
+@Configuration
+@EnableJpaRepositories("com.car.app.repository")
+@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
+@EnableTransactionManagement
+public class DatabaseConfiguration {
+
+ private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);
+
+ private final Environment env;
+
+ public DatabaseConfiguration(Environment env) {
+ this.env = env;
+ }
+
+ /**
+ * Open the TCP port for the H2 database, so it is available remotely.
+ *
+ * @return the H2 database TCP server
+ * @throws SQLException if the server failed to start
+ */
+ @Bean(initMethod = "start", destroyMethod = "stop")
+ @Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
+ public Server h2TCPServer() throws SQLException {
+ return Server.createTcpServer("-tcp","-tcpAllowOthers");
+ }
+
+ @Bean
+ public SpringLiquibase liquibase(@Qualifier("taskExecutor") TaskExecutor taskExecutor,
+ DataSource dataSource, LiquibaseProperties liquibaseProperties) {
+
+ // Use liquibase.integration.spring.SpringLiquibase if you don't want Liquibase to start asynchronously
+ SpringLiquibase liquibase = new AsyncSpringLiquibase(taskExecutor, env);
+ liquibase.setDataSource(dataSource);
+ liquibase.setChangeLog("classpath:config/liquibase/master.xml");
+ liquibase.setContexts(liquibaseProperties.getContexts());
+ liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema());
+ liquibase.setDropFirst(liquibaseProperties.isDropFirst());
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_NO_LIQUIBASE)) {
+ liquibase.setShouldRun(false);
+ } else {
+ liquibase.setShouldRun(liquibaseProperties.isEnabled());
+ log.debug("Configuring Liquibase");
+ }
+ return liquibase;
+ }
+
+ @Bean
+ public Hibernate5Module hibernate5Module() {
+ return new Hibernate5Module();
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/DateTimeFormatConfiguration.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/DateTimeFormatConfiguration.java
new file mode 100644
index 0000000000..67fff05c84
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/DateTimeFormatConfiguration.java
@@ -0,0 +1,17 @@
+package com.car.app.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@Configuration
+public class DateTimeFormatConfiguration extends WebMvcConfigurerAdapter {
+
+ @Override
+ public void addFormatters(FormatterRegistry registry) {
+ DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
+ registrar.setUseIsoFormat(true);
+ registrar.registerFormatters(registry);
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/DefaultProfileUtil.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/DefaultProfileUtil.java
new file mode 100644
index 0000000000..640458f9db
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/DefaultProfileUtil.java
@@ -0,0 +1,48 @@
+package com.car.app.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.core.env.Environment;
+
+import java.util.*;
+
+/**
+ * Utility class to load a Spring profile to be used as default
+ * when there is no spring.profiles.active set in the environment or as command line argument.
+ * If the value is not available in application.yml then dev profile will be used as default.
+ */
+public final class DefaultProfileUtil {
+
+ private static final String SPRING_PROFILE_DEFAULT = "spring.profiles.default";
+
+ private DefaultProfileUtil() {
+ }
+
+ /**
+ * Set a default to use when no profile is configured.
+ *
+ * @param app the Spring application
+ */
+ public static void addDefaultProfile(SpringApplication app) {
+ Map defProperties = new HashMap<>();
+ /*
+ * The default profile to use when no other profiles are defined
+ * This cannot be set in the application.yml file.
+ * See https://github.com/spring-projects/spring-boot/issues/1219
+ */
+ defProperties.put(SPRING_PROFILE_DEFAULT, JHipsterConstants.SPRING_PROFILE_DEVELOPMENT);
+ app.setDefaultProperties(defProperties);
+ }
+
+ /**
+ * Get the profiles that are applied else get default profiles.
+ */
+ public static String[] getActiveProfiles(Environment env) {
+ String[] profiles = env.getActiveProfiles();
+ if (profiles.length == 0) {
+ return env.getDefaultProfiles();
+ }
+ return profiles;
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/LocaleConfiguration.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/LocaleConfiguration.java
new file mode 100644
index 0000000000..92adfb7f66
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/LocaleConfiguration.java
@@ -0,0 +1,35 @@
+package com.car.app.config;
+
+import io.github.jhipster.config.locale.AngularCookieLocaleResolver;
+
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
+
+@Configuration
+public class LocaleConfiguration extends WebMvcConfigurerAdapter implements EnvironmentAware {
+
+ @Override
+ public void setEnvironment(Environment environment) {
+ // unused
+ }
+
+ @Bean(name = "localeResolver")
+ public LocaleResolver localeResolver() {
+ AngularCookieLocaleResolver cookieLocaleResolver = new AngularCookieLocaleResolver();
+ cookieLocaleResolver.setCookieName("NG_TRANSLATE_LANG_KEY");
+ return cookieLocaleResolver;
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
+ localeChangeInterceptor.setParamName("language");
+ registry.addInterceptor(localeChangeInterceptor);
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/LoggingAspectConfiguration.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/LoggingAspectConfiguration.java
new file mode 100644
index 0000000000..e7370c954f
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/LoggingAspectConfiguration.java
@@ -0,0 +1,19 @@
+package com.car.app.config;
+
+import com.car.app.aop.logging.LoggingAspect;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.springframework.context.annotation.*;
+import org.springframework.core.env.Environment;
+
+@Configuration
+@EnableAspectJAutoProxy
+public class LoggingAspectConfiguration {
+
+ @Bean
+ @Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
+ public LoggingAspect loggingAspect(Environment env) {
+ return new LoggingAspect(env);
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/LoggingConfiguration.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/LoggingConfiguration.java
new file mode 100644
index 0000000000..318323ae7c
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/LoggingConfiguration.java
@@ -0,0 +1,113 @@
+package com.car.app.config;
+
+import io.github.jhipster.config.JHipsterProperties;
+
+import ch.qos.logback.classic.AsyncAppender;
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.LoggerContextListener;
+import ch.qos.logback.core.spi.ContextAwareBase;
+import net.logstash.logback.appender.LogstashSocketAppender;
+import net.logstash.logback.stacktrace.ShortenedThrowableConverter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class LoggingConfiguration {
+
+ private final Logger log = LoggerFactory.getLogger(LoggingConfiguration.class);
+
+ private LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+
+ @Value("${spring.application.name}")
+ private String appName;
+
+ @Value("${server.port}")
+ private String serverPort;
+
+ @Value("${eureka.instance.instanceId}")
+ private String instanceId;
+
+ private final JHipsterProperties jHipsterProperties;
+
+ public LoggingConfiguration(JHipsterProperties jHipsterProperties) {
+ this.jHipsterProperties = jHipsterProperties;
+ if (jHipsterProperties.getLogging().getLogstash().isEnabled()) {
+ addLogstashAppender(context);
+
+ // Add context listener
+ LogbackLoggerContextListener loggerContextListener = new LogbackLoggerContextListener();
+ loggerContextListener.setContext(context);
+ context.addListener(loggerContextListener);
+ }
+ }
+
+ public void addLogstashAppender(LoggerContext context) {
+ log.info("Initializing Logstash logging");
+
+ LogstashSocketAppender logstashAppender = new LogstashSocketAppender();
+ logstashAppender.setName("LOGSTASH");
+ logstashAppender.setContext(context);
+ String customFields = "{\"app_name\":\"" + appName + "\",\"app_port\":\"" + serverPort + "\"," +
+ "\"instance_id\":\"" + instanceId + "\"}";
+
+ // Set the Logstash appender config from JHipster properties
+ logstashAppender.setSyslogHost(jHipsterProperties.getLogging().getLogstash().getHost());
+ logstashAppender.setPort(jHipsterProperties.getLogging().getLogstash().getPort());
+ logstashAppender.setCustomFields(customFields);
+
+ // Limit the maximum length of the forwarded stacktrace so that it won't exceed the 8KB UDP limit of logstash
+ ShortenedThrowableConverter throwableConverter = new ShortenedThrowableConverter();
+ throwableConverter.setMaxLength(7500);
+ throwableConverter.setRootCauseFirst(true);
+ logstashAppender.setThrowableConverter(throwableConverter);
+
+ logstashAppender.start();
+
+ // Wrap the appender in an Async appender for performance
+ AsyncAppender asyncLogstashAppender = new AsyncAppender();
+ asyncLogstashAppender.setContext(context);
+ asyncLogstashAppender.setName("ASYNC_LOGSTASH");
+ asyncLogstashAppender.setQueueSize(jHipsterProperties.getLogging().getLogstash().getQueueSize());
+ asyncLogstashAppender.addAppender(logstashAppender);
+ asyncLogstashAppender.start();
+
+ context.getLogger("ROOT").addAppender(asyncLogstashAppender);
+ }
+
+ /**
+ * Logback configuration is achieved by configuration file and API.
+ * When configuration file change is detected, the configuration is reset.
+ * This listener ensures that the programmatic configuration is also re-applied after reset.
+ */
+ class LogbackLoggerContextListener extends ContextAwareBase implements LoggerContextListener {
+
+ @Override
+ public boolean isResetResistant() {
+ return true;
+ }
+
+ @Override
+ public void onStart(LoggerContext context) {
+ addLogstashAppender(context);
+ }
+
+ @Override
+ public void onReset(LoggerContext context) {
+ addLogstashAppender(context);
+ }
+
+ @Override
+ public void onStop(LoggerContext context) {
+ // Nothing to do.
+ }
+
+ @Override
+ public void onLevelChange(ch.qos.logback.classic.Logger logger, Level level) {
+ // Nothing to do.
+ }
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/MetricsConfiguration.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/MetricsConfiguration.java
new file mode 100644
index 0000000000..27b617a190
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/MetricsConfiguration.java
@@ -0,0 +1,113 @@
+package com.car.app.config;
+
+import io.github.jhipster.config.JHipsterProperties;
+import io.github.jhipster.config.metrics.SpectatorLogMetricWriter;
+
+import com.netflix.spectator.api.Registry;
+import org.springframework.boot.actuate.autoconfigure.ExportMetricReader;
+import org.springframework.boot.actuate.autoconfigure.ExportMetricWriter;
+import org.springframework.boot.actuate.metrics.writer.MetricWriter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.netflix.metrics.spectator.SpectatorMetricReader;
+
+import com.codahale.metrics.JmxReporter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Slf4jReporter;
+import com.codahale.metrics.health.HealthCheckRegistry;
+import com.codahale.metrics.jvm.*;
+import com.ryantenney.metrics.spring.config.annotation.EnableMetrics;
+import com.ryantenney.metrics.spring.config.annotation.MetricsConfigurerAdapter;
+import com.zaxxer.hikari.HikariDataSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.*;
+
+import javax.annotation.PostConstruct;
+import java.lang.management.ManagementFactory;
+import java.util.concurrent.TimeUnit;
+
+@Configuration
+@EnableMetrics(proxyTargetClass = true)
+public class MetricsConfiguration extends MetricsConfigurerAdapter {
+
+ private static final String PROP_METRIC_REG_JVM_MEMORY = "jvm.memory";
+ private static final String PROP_METRIC_REG_JVM_GARBAGE = "jvm.garbage";
+ private static final String PROP_METRIC_REG_JVM_THREADS = "jvm.threads";
+ private static final String PROP_METRIC_REG_JVM_FILES = "jvm.files";
+ private static final String PROP_METRIC_REG_JVM_BUFFERS = "jvm.buffers";
+ private final Logger log = LoggerFactory.getLogger(MetricsConfiguration.class);
+
+ private MetricRegistry metricRegistry = new MetricRegistry();
+
+ private HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry();
+
+ private final JHipsterProperties jHipsterProperties;
+
+ private HikariDataSource hikariDataSource;
+
+ public MetricsConfiguration(JHipsterProperties jHipsterProperties) {
+ this.jHipsterProperties = jHipsterProperties;
+ }
+
+ @Autowired(required = false)
+ public void setHikariDataSource(HikariDataSource hikariDataSource) {
+ this.hikariDataSource = hikariDataSource;
+ }
+
+ @Override
+ @Bean
+ public MetricRegistry getMetricRegistry() {
+ return metricRegistry;
+ }
+
+ @Override
+ @Bean
+ public HealthCheckRegistry getHealthCheckRegistry() {
+ return healthCheckRegistry;
+ }
+
+ @PostConstruct
+ public void init() {
+ log.debug("Registering JVM gauges");
+ metricRegistry.register(PROP_METRIC_REG_JVM_MEMORY, new MemoryUsageGaugeSet());
+ metricRegistry.register(PROP_METRIC_REG_JVM_GARBAGE, new GarbageCollectorMetricSet());
+ metricRegistry.register(PROP_METRIC_REG_JVM_THREADS, new ThreadStatesGaugeSet());
+ metricRegistry.register(PROP_METRIC_REG_JVM_FILES, new FileDescriptorRatioGauge());
+ metricRegistry.register(PROP_METRIC_REG_JVM_BUFFERS, new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()));
+ if (hikariDataSource != null) {
+ log.debug("Monitoring the datasource");
+ hikariDataSource.setMetricRegistry(metricRegistry);
+ }
+ if (jHipsterProperties.getMetrics().getJmx().isEnabled()) {
+ log.debug("Initializing Metrics JMX reporting");
+ JmxReporter jmxReporter = JmxReporter.forRegistry(metricRegistry).build();
+ jmxReporter.start();
+ }
+ if (jHipsterProperties.getMetrics().getLogs().isEnabled()) {
+ log.info("Initializing Metrics Log reporting");
+ final Slf4jReporter reporter = Slf4jReporter.forRegistry(metricRegistry)
+ .outputTo(LoggerFactory.getLogger("metrics"))
+ .convertRatesTo(TimeUnit.SECONDS)
+ .convertDurationsTo(TimeUnit.MILLISECONDS)
+ .build();
+ reporter.start(jHipsterProperties.getMetrics().getLogs().getReportFrequency(), TimeUnit.SECONDS);
+ }
+ }
+
+ /* Spectator metrics log reporting */
+ @Bean
+ @ConditionalOnProperty("jhipster.logging.spectator-metrics.enabled")
+ @ExportMetricReader
+ public SpectatorMetricReader SpectatorMetricReader(Registry registry) {
+ log.info("Initializing Spectator Metrics Log reporting");
+ return new SpectatorMetricReader(registry);
+ }
+
+ @Bean
+ @ConditionalOnProperty("jhipster.logging.spectator-metrics.enabled")
+ @ExportMetricWriter
+ MetricWriter metricWriter() {
+ return new SpectatorLogMetricWriter();
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/MicroserviceSecurityConfiguration.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/MicroserviceSecurityConfiguration.java
new file mode 100644
index 0000000000..3e7b125ad6
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/MicroserviceSecurityConfiguration.java
@@ -0,0 +1,71 @@
+package com.car.app.config;
+
+import com.car.app.security.AuthoritiesConstants;
+import com.car.app.security.jwt.JWTConfigurer;
+import com.car.app.security.jwt.TokenProvider;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
+
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
+public class MicroserviceSecurityConfiguration extends WebSecurityConfigurerAdapter {
+
+ private final TokenProvider tokenProvider;
+
+ public MicroserviceSecurityConfiguration(TokenProvider tokenProvider) {
+ this.tokenProvider = tokenProvider;
+ }
+
+ @Override
+ public void configure(WebSecurity web) throws Exception {
+ web.ignoring()
+ .antMatchers(HttpMethod.OPTIONS, "/**")
+ .antMatchers("/app/**/*.{js,html}")
+ .antMatchers("/bower_components/**")
+ .antMatchers("/i18n/**")
+ .antMatchers("/content/**")
+ .antMatchers("/swagger-ui/index.html")
+ .antMatchers("/test/**")
+ .antMatchers("/h2-console/**");
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .csrf()
+ .disable()
+ .headers()
+ .frameOptions()
+ .disable()
+ .and()
+ .sessionManagement()
+ .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+ .and()
+ .authorizeRequests()
+ .antMatchers("/api/**").authenticated()
+ .antMatchers("/management/health").permitAll()
+ .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
+ .antMatchers("/swagger-resources/configuration/ui").permitAll()
+ .and()
+ .apply(securityConfigurerAdapter());
+ }
+
+ private JWTConfigurer securityConfigurerAdapter() {
+ return new JWTConfigurer(tokenProvider);
+ }
+
+ @Bean
+ public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
+ return new SecurityEvaluationContextExtension();
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/ThymeleafConfiguration.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/ThymeleafConfiguration.java
new file mode 100644
index 0000000000..d84ca403d2
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/ThymeleafConfiguration.java
@@ -0,0 +1,26 @@
+package com.car.app.config;
+
+import org.apache.commons.lang3.CharEncoding;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.*;
+import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
+
+@Configuration
+public class ThymeleafConfiguration {
+
+ @SuppressWarnings("unused")
+ private final Logger log = LoggerFactory.getLogger(ThymeleafConfiguration.class);
+
+ @Bean
+ @Description("Thymeleaf template resolver serving HTML 5 emails")
+ public ClassLoaderTemplateResolver emailTemplateResolver() {
+ ClassLoaderTemplateResolver emailTemplateResolver = new ClassLoaderTemplateResolver();
+ emailTemplateResolver.setPrefix("mails/");
+ emailTemplateResolver.setSuffix(".html");
+ emailTemplateResolver.setTemplateMode("HTML5");
+ emailTemplateResolver.setCharacterEncoding(CharEncoding.UTF_8);
+ emailTemplateResolver.setOrder(1);
+ return emailTemplateResolver;
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/WebConfigurer.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/WebConfigurer.java
new file mode 100644
index 0000000000..c66579e940
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/WebConfigurer.java
@@ -0,0 +1,144 @@
+package com.car.app.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+import io.github.jhipster.config.JHipsterProperties;
+
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.servlet.InstrumentedFilter;
+import com.codahale.metrics.servlets.MetricsServlet;
+import com.hazelcast.core.HazelcastInstance;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.embedded.*;
+import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
+import io.undertow.UndertowOptions;
+import org.springframework.boot.web.servlet.ServletContextInitializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+import java.util.*;
+import javax.servlet.*;
+
+/**
+ * Configuration of web application with Servlet 3.0 APIs.
+ */
+@Configuration
+public class WebConfigurer implements ServletContextInitializer, EmbeddedServletContainerCustomizer {
+
+ private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);
+
+ private final Environment env;
+
+ private final JHipsterProperties jHipsterProperties;
+
+ private final HazelcastInstance hazelcastInstance;
+
+ private MetricRegistry metricRegistry;
+
+ public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties, HazelcastInstance hazelcastInstance) {
+
+ this.env = env;
+ this.jHipsterProperties = jHipsterProperties;
+ this.hazelcastInstance = hazelcastInstance;
+ }
+
+ @Override
+ public void onStartup(ServletContext servletContext) throws ServletException {
+ if (env.getActiveProfiles().length != 0) {
+ log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles());
+ }
+ EnumSet disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
+ initMetrics(servletContext, disps);
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
+ initH2Console(servletContext);
+ }
+ log.info("Web application fully configured");
+ }
+
+ /**
+ * Customize the Servlet engine: Mime types, the document root, the cache.
+ */
+ @Override
+ public void customize(ConfigurableEmbeddedServletContainer container) {
+ MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
+ // IE issue, see https://github.com/jhipster/generator-jhipster/pull/711
+ mappings.add("html", "text/html;charset=utf-8");
+ // CloudFoundry issue, see https://github.com/cloudfoundry/gorouter/issues/64
+ mappings.add("json", "text/html;charset=utf-8");
+ container.setMimeMappings(mappings);
+
+ /*
+ * Enable HTTP/2 for Undertow - https://twitter.com/ankinson/status/829256167700492288
+ * HTTP/2 requires HTTPS, so HTTP requests will fallback to HTTP/1.1.
+ * See the JHipsterProperties class and your application-*.yml configuration files
+ * for more information.
+ */
+ if (jHipsterProperties.getHttp().getVersion().equals(JHipsterProperties.Http.Version.V_2_0) &&
+ container instanceof UndertowEmbeddedServletContainerFactory) {
+
+ ((UndertowEmbeddedServletContainerFactory) container)
+ .addBuilderCustomizers(builder ->
+ builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true));
+ }
+ }
+
+ /**
+ * Initializes Metrics.
+ */
+ private void initMetrics(ServletContext servletContext, EnumSet disps) {
+ log.debug("Initializing Metrics registries");
+ servletContext.setAttribute(InstrumentedFilter.REGISTRY_ATTRIBUTE,
+ metricRegistry);
+ servletContext.setAttribute(MetricsServlet.METRICS_REGISTRY,
+ metricRegistry);
+
+ log.debug("Registering Metrics Filter");
+ FilterRegistration.Dynamic metricsFilter = servletContext.addFilter("webappMetricsFilter",
+ new InstrumentedFilter());
+
+ metricsFilter.addMappingForUrlPatterns(disps, true, "/*");
+ metricsFilter.setAsyncSupported(true);
+
+ log.debug("Registering Metrics Servlet");
+ ServletRegistration.Dynamic metricsAdminServlet =
+ servletContext.addServlet("metricsServlet", new MetricsServlet());
+
+ metricsAdminServlet.addMapping("/management/metrics/*");
+ metricsAdminServlet.setAsyncSupported(true);
+ metricsAdminServlet.setLoadOnStartup(2);
+ }
+
+ @Bean
+ public CorsFilter corsFilter() {
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ CorsConfiguration config = jHipsterProperties.getCors();
+ if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
+ log.debug("Registering CORS filter");
+ source.registerCorsConfiguration("/api/**", config);
+ source.registerCorsConfiguration("/v2/api-docs", config);
+ }
+ return new CorsFilter(source);
+ }
+
+ /**
+ * Initializes H2 console.
+ */
+ private void initH2Console(ServletContext servletContext) {
+ log.debug("Initialize H2 console");
+ ServletRegistration.Dynamic h2ConsoleServlet = servletContext.addServlet("H2Console", new org.h2.server.web.WebServlet());
+ h2ConsoleServlet.addMapping("/h2-console/*");
+ h2ConsoleServlet.setInitParameter("-properties", "src/main/resources/");
+ h2ConsoleServlet.setLoadOnStartup(1);
+ }
+
+ @Autowired(required = false)
+ public void setMetricRegistry(MetricRegistry metricRegistry) {
+ this.metricRegistry = metricRegistry;
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/audit/AuditEventConverter.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/audit/AuditEventConverter.java
new file mode 100644
index 0000000000..93680c0ef1
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/audit/AuditEventConverter.java
@@ -0,0 +1,91 @@
+package com.car.app.config.audit;
+
+import com.car.app.domain.PersistentAuditEvent;
+
+import org.springframework.boot.actuate.audit.AuditEvent;
+import org.springframework.security.web.authentication.WebAuthenticationDetails;
+import org.springframework.stereotype.Component;
+
+import java.time.Instant;
+import java.time.ZoneId;
+import java.util.*;
+
+@Component
+public class AuditEventConverter {
+
+ /**
+ * Convert a list of PersistentAuditEvent to a list of AuditEvent
+ *
+ * @param persistentAuditEvents the list to convert
+ * @return the converted list.
+ */
+ public List convertToAuditEvent(Iterable persistentAuditEvents) {
+ if (persistentAuditEvents == null) {
+ return Collections.emptyList();
+ }
+ List auditEvents = new ArrayList<>();
+ for (PersistentAuditEvent persistentAuditEvent : persistentAuditEvents) {
+ auditEvents.add(convertToAuditEvent(persistentAuditEvent));
+ }
+ return auditEvents;
+ }
+
+ /**
+ * Convert a PersistentAuditEvent to an AuditEvent
+ *
+ * @param persistentAuditEvent the event to convert
+ * @return the converted list.
+ */
+ public AuditEvent convertToAuditEvent(PersistentAuditEvent persistentAuditEvent) {
+ Instant instant = persistentAuditEvent.getAuditEventDate().atZone(ZoneId.systemDefault()).toInstant();
+ return new AuditEvent(Date.from(instant), persistentAuditEvent.getPrincipal(),
+ persistentAuditEvent.getAuditEventType(), convertDataToObjects(persistentAuditEvent.getData()));
+ }
+
+ /**
+ * Internal conversion. This is needed to support the current SpringBoot actuator AuditEventRepository interface
+ *
+ * @param data the data to convert
+ * @return a map of String, Object
+ */
+ public Map convertDataToObjects(Map data) {
+ Map results = new HashMap<>();
+
+ if (data != null) {
+ for (Map.Entry entry : data.entrySet()) {
+ results.put(entry.getKey(), entry.getValue());
+ }
+ }
+ return results;
+ }
+
+ /**
+ * Internal conversion. This method will allow to save additional data.
+ * By default, it will save the object as string
+ *
+ * @param data the data to convert
+ * @return a map of String, String
+ */
+ public Map convertDataToStrings(Map data) {
+ Map results = new HashMap<>();
+
+ if (data != null) {
+ for (Map.Entry entry : data.entrySet()) {
+ Object object = entry.getValue();
+
+ // Extract the data that will be saved.
+ if (object instanceof WebAuthenticationDetails) {
+ WebAuthenticationDetails authenticationDetails = (WebAuthenticationDetails) object;
+ results.put("remoteAddress", authenticationDetails.getRemoteAddress());
+ results.put("sessionId", authenticationDetails.getSessionId());
+ } else if (object != null) {
+ results.put(entry.getKey(), object.toString());
+ } else {
+ results.put(entry.getKey(), "null");
+ }
+ }
+ }
+
+ return results;
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/audit/package-info.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/audit/package-info.java
new file mode 100644
index 0000000000..0d1f9d950e
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/audit/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Audit specific code.
+ */
+package com.car.app.config.audit;
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/package-info.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/package-info.java
new file mode 100644
index 0000000000..1d4b771794
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/config/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Spring Framework configuration files.
+ */
+package com.car.app.config;
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/domain/AbstractAuditingEntity.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/domain/AbstractAuditingEntity.java
new file mode 100644
index 0000000000..ee265f27ae
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/domain/AbstractAuditingEntity.java
@@ -0,0 +1,80 @@
+package com.car.app.domain;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.hibernate.envers.Audited;
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedBy;
+import org.springframework.data.annotation.LastModifiedDate;
+
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+import java.time.ZonedDateTime;
+import javax.persistence.Column;
+import javax.persistence.EntityListeners;
+import javax.persistence.MappedSuperclass;
+
+/**
+ * Base abstract class for entities which will hold definitions for created, last modified by and created,
+ * last modified by date.
+ */
+@MappedSuperclass
+@Audited
+@EntityListeners(AuditingEntityListener.class)
+public abstract class AbstractAuditingEntity implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @CreatedBy
+ @Column(name = "created_by", nullable = false, length = 50, updatable = false)
+ @JsonIgnore
+ private String createdBy;
+
+ @CreatedDate
+ @Column(name = "created_date", nullable = false)
+ @JsonIgnore
+ private ZonedDateTime createdDate = ZonedDateTime.now();
+
+ @LastModifiedBy
+ @Column(name = "last_modified_by", length = 50)
+ @JsonIgnore
+ private String lastModifiedBy;
+
+ @LastModifiedDate
+ @Column(name = "last_modified_date")
+ @JsonIgnore
+ private ZonedDateTime lastModifiedDate = ZonedDateTime.now();
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public ZonedDateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ public void setCreatedDate(ZonedDateTime createdDate) {
+ this.createdDate = createdDate;
+ }
+
+ public String getLastModifiedBy() {
+ return lastModifiedBy;
+ }
+
+ public void setLastModifiedBy(String lastModifiedBy) {
+ this.lastModifiedBy = lastModifiedBy;
+ }
+
+ public ZonedDateTime getLastModifiedDate() {
+ return lastModifiedDate;
+ }
+
+ public void setLastModifiedDate(ZonedDateTime lastModifiedDate) {
+ this.lastModifiedDate = lastModifiedDate;
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/domain/Car.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/domain/Car.java
new file mode 100644
index 0000000000..dad21815d3
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/domain/Car.java
@@ -0,0 +1,109 @@
+package com.car.app.domain;
+
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * A Car.
+ */
+@Entity
+@Table(name = "car")
+@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
+public class Car implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(name = "make")
+ private String make;
+
+ @Column(name = "brand")
+ private String brand;
+
+ @Column(name = "price")
+ private Double price;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getMake() {
+ return make;
+ }
+
+ public Car make(String make) {
+ this.make = make;
+ return this;
+ }
+
+ public void setMake(String make) {
+ this.make = make;
+ }
+
+ public String getBrand() {
+ return brand;
+ }
+
+ public Car brand(String brand) {
+ this.brand = brand;
+ return this;
+ }
+
+ public void setBrand(String brand) {
+ this.brand = brand;
+ }
+
+ public Double getPrice() {
+ return price;
+ }
+
+ public Car price(Double price) {
+ this.price = price;
+ return this;
+ }
+
+ public void setPrice(Double price) {
+ this.price = price;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Car car = (Car) o;
+ if (car.id == null || id == null) {
+ return false;
+ }
+ return Objects.equals(id, car.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(id);
+ }
+
+ @Override
+ public String toString() {
+ return "Car{" +
+ "id=" + id +
+ ", make='" + make + "'" +
+ ", brand='" + brand + "'" +
+ ", price='" + price + "'" +
+ '}';
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/domain/PersistentAuditEvent.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/domain/PersistentAuditEvent.java
new file mode 100644
index 0000000000..d3d8eb86dc
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/domain/PersistentAuditEvent.java
@@ -0,0 +1,78 @@
+package com.car.app.domain;
+
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import javax.persistence.*;
+import javax.validation.constraints.NotNull;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Persist AuditEvent managed by the Spring Boot actuator
+ * @see org.springframework.boot.actuate.audit.AuditEvent
+ */
+@Entity
+@Table(name = "jhi_persistent_audit_event")
+public class PersistentAuditEvent implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "event_id")
+ private Long id;
+
+ @NotNull
+ @Column(nullable = false)
+ private String principal;
+
+ @Column(name = "event_date")
+ private LocalDateTime auditEventDate;
+ @Column(name = "event_type")
+ private String auditEventType;
+
+ @ElementCollection
+ @MapKeyColumn(name = "name")
+ @Column(name = "value")
+ @CollectionTable(name = "jhi_persistent_audit_evt_data", joinColumns=@JoinColumn(name="event_id"))
+ private Map data = new HashMap<>();
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getPrincipal() {
+ return principal;
+ }
+
+ public void setPrincipal(String principal) {
+ this.principal = principal;
+ }
+
+ public LocalDateTime getAuditEventDate() {
+ return auditEventDate;
+ }
+
+ public void setAuditEventDate(LocalDateTime auditEventDate) {
+ this.auditEventDate = auditEventDate;
+ }
+
+ public String getAuditEventType() {
+ return auditEventType;
+ }
+
+ public void setAuditEventType(String auditEventType) {
+ this.auditEventType = auditEventType;
+ }
+
+ public Map getData() {
+ return data;
+ }
+
+ public void setData(Map data) {
+ this.data = data;
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/domain/package-info.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/domain/package-info.java
new file mode 100644
index 0000000000..99ddca6167
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/domain/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * JPA domain objects.
+ */
+package com.car.app.domain;
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/repository/CarRepository.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/repository/CarRepository.java
new file mode 100644
index 0000000000..6aea5a0be8
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/repository/CarRepository.java
@@ -0,0 +1,15 @@
+package com.car.app.repository;
+
+import com.car.app.domain.Car;
+
+import org.springframework.data.jpa.repository.*;
+
+import java.util.List;
+
+/**
+ * Spring Data JPA repository for the Car entity.
+ */
+@SuppressWarnings("unused")
+public interface CarRepository extends JpaRepository {
+
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/repository/package-info.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/repository/package-info.java
new file mode 100644
index 0000000000..55d8e8e5e5
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/repository/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Spring Data JPA repositories.
+ */
+package com.car.app.repository;
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/AuthoritiesConstants.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/AuthoritiesConstants.java
new file mode 100644
index 0000000000..ca36d02c5c
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/AuthoritiesConstants.java
@@ -0,0 +1,16 @@
+package com.car.app.security;
+
+/**
+ * Constants for Spring Security authorities.
+ */
+public final class AuthoritiesConstants {
+
+ public static final String ADMIN = "ROLE_ADMIN";
+
+ public static final String USER = "ROLE_USER";
+
+ public static final String ANONYMOUS = "ROLE_ANONYMOUS";
+
+ private AuthoritiesConstants() {
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/SecurityUtils.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/SecurityUtils.java
new file mode 100644
index 0000000000..dc399d4220
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/SecurityUtils.java
@@ -0,0 +1,68 @@
+package com.car.app.security;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+
+/**
+ * Utility class for Spring Security.
+ */
+public final class SecurityUtils {
+
+ private SecurityUtils() {
+ }
+
+ /**
+ * Get the login of the current user.
+ *
+ * @return the login of the current user
+ */
+ public static String getCurrentUserLogin() {
+ SecurityContext securityContext = SecurityContextHolder.getContext();
+ Authentication authentication = securityContext.getAuthentication();
+ String userName = null;
+ if (authentication != null) {
+ if (authentication.getPrincipal() instanceof UserDetails) {
+ UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
+ userName = springSecurityUser.getUsername();
+ } else if (authentication.getPrincipal() instanceof String) {
+ userName = (String) authentication.getPrincipal();
+ }
+ }
+ return userName;
+ }
+
+ /**
+ * Check if a user is authenticated.
+ *
+ * @return true if the user is authenticated, false otherwise
+ */
+ public static boolean isAuthenticated() {
+ SecurityContext securityContext = SecurityContextHolder.getContext();
+ Authentication authentication = securityContext.getAuthentication();
+ if (authentication != null) {
+ return authentication.getAuthorities().stream()
+ .noneMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(AuthoritiesConstants.ANONYMOUS));
+ }
+ return false;
+ }
+
+ /**
+ * If the current user has a specific authority (security role).
+ *
+ * The name of this method comes from the isUserInRole() method in the Servlet API
+ *
+ * @param authority the authority to check
+ * @return true if the current user has the authority, false otherwise
+ */
+ public static boolean isCurrentUserInRole(String authority) {
+ SecurityContext securityContext = SecurityContextHolder.getContext();
+ Authentication authentication = securityContext.getAuthentication();
+ if (authentication != null) {
+ return authentication.getAuthorities().stream()
+ .anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(authority));
+ }
+ return false;
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/SpringSecurityAuditorAware.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/SpringSecurityAuditorAware.java
new file mode 100644
index 0000000000..a99d9e5e88
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/SpringSecurityAuditorAware.java
@@ -0,0 +1,19 @@
+package com.car.app.security;
+
+import com.car.app.config.Constants;
+
+import org.springframework.data.domain.AuditorAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * Implementation of AuditorAware based on Spring Security.
+ */
+@Component
+public class SpringSecurityAuditorAware implements AuditorAware {
+
+ @Override
+ public String getCurrentAuditor() {
+ String userName = SecurityUtils.getCurrentUserLogin();
+ return userName != null ? userName : Constants.SYSTEM_ACCOUNT;
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/jwt/JWTConfigurer.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/jwt/JWTConfigurer.java
new file mode 100644
index 0000000000..957bae3f1e
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/jwt/JWTConfigurer.java
@@ -0,0 +1,23 @@
+package com.car.app.security.jwt;
+
+import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.web.DefaultSecurityFilterChain;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+public class JWTConfigurer extends SecurityConfigurerAdapter {
+
+ public static final String AUTHORIZATION_HEADER = "Authorization";
+
+ private TokenProvider tokenProvider;
+
+ public JWTConfigurer(TokenProvider tokenProvider) {
+ this.tokenProvider = tokenProvider;
+ }
+
+ @Override
+ public void configure(HttpSecurity http) throws Exception {
+ JWTFilter customFilter = new JWTFilter(tokenProvider);
+ http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/jwt/JWTFilter.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/jwt/JWTFilter.java
new file mode 100644
index 0000000000..2785714cc2
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/jwt/JWTFilter.java
@@ -0,0 +1,58 @@
+package com.car.app.security.jwt;
+
+import java.io.IOException;
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.util.StringUtils;
+import org.springframework.web.filter.GenericFilterBean;
+
+import io.jsonwebtoken.ExpiredJwtException;
+
+/**
+ * Filters incoming requests and installs a Spring Security principal if a header corresponding to a valid user is
+ * found.
+ */
+public class JWTFilter extends GenericFilterBean {
+
+ private final Logger log = LoggerFactory.getLogger(JWTFilter.class);
+
+ private TokenProvider tokenProvider;
+
+ public JWTFilter(TokenProvider tokenProvider) {
+ this.tokenProvider = tokenProvider;
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+ throws IOException, ServletException {
+ try {
+ HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
+ String jwt = resolveToken(httpServletRequest);
+ if (StringUtils.hasText(jwt) && this.tokenProvider.validateToken(jwt)) {
+ Authentication authentication = this.tokenProvider.getAuthentication(jwt);
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ }
+ filterChain.doFilter(servletRequest, servletResponse);
+ } catch (ExpiredJwtException eje) {
+ log.info("Security exception for user {} - {}",
+ eje.getClaims().getSubject(), eje.getMessage());
+
+ log.trace("Security exception trace: {}", eje);
+ ((HttpServletResponse) servletResponse).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ }
+ }
+
+ private String resolveToken(HttpServletRequest request){
+ String bearerToken = request.getHeader(JWTConfigurer.AUTHORIZATION_HEADER);
+ if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
+ return bearerToken.substring(7, bearerToken.length());
+ }
+ return null;
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/jwt/TokenProvider.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/jwt/TokenProvider.java
new file mode 100644
index 0000000000..3908bfa8f3
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/security/jwt/TokenProvider.java
@@ -0,0 +1,109 @@
+package com.car.app.security.jwt;
+
+import io.github.jhipster.config.JHipsterProperties;
+
+import java.util.*;
+import java.util.stream.Collectors;
+import javax.annotation.PostConstruct;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.stereotype.Component;
+
+import io.jsonwebtoken.*;
+
+@Component
+public class TokenProvider {
+
+ private final Logger log = LoggerFactory.getLogger(TokenProvider.class);
+
+ private static final String AUTHORITIES_KEY = "auth";
+
+ private String secretKey;
+
+ private long tokenValidityInMilliseconds;
+
+ private long tokenValidityInMillisecondsForRememberMe;
+
+ private final JHipsterProperties jHipsterProperties;
+
+ public TokenProvider(JHipsterProperties jHipsterProperties) {
+ this.jHipsterProperties = jHipsterProperties;
+ }
+
+ @PostConstruct
+ public void init() {
+ this.secretKey =
+ jHipsterProperties.getSecurity().getAuthentication().getJwt().getSecret();
+
+ this.tokenValidityInMilliseconds =
+ 1000 * jHipsterProperties.getSecurity().getAuthentication().getJwt().getTokenValidityInSeconds();
+ this.tokenValidityInMillisecondsForRememberMe =
+ 1000 * jHipsterProperties.getSecurity().getAuthentication().getJwt().getTokenValidityInSecondsForRememberMe();
+ }
+
+ public String createToken(Authentication authentication, Boolean rememberMe) {
+ String authorities = authentication.getAuthorities().stream()
+ .map(GrantedAuthority::getAuthority)
+ .collect(Collectors.joining(","));
+
+ long now = (new Date()).getTime();
+ Date validity;
+ if (rememberMe) {
+ validity = new Date(now + this.tokenValidityInMillisecondsForRememberMe);
+ } else {
+ validity = new Date(now + this.tokenValidityInMilliseconds);
+ }
+
+ return Jwts.builder()
+ .setSubject(authentication.getName())
+ .claim(AUTHORITIES_KEY, authorities)
+ .signWith(SignatureAlgorithm.HS512, secretKey)
+ .setExpiration(validity)
+ .compact();
+ }
+
+ public Authentication getAuthentication(String token) {
+ Claims claims = Jwts.parser()
+ .setSigningKey(secretKey)
+ .parseClaimsJws(token)
+ .getBody();
+
+ Collection extends GrantedAuthority> authorities =
+ Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(","))
+ .map(SimpleGrantedAuthority::new)
+ .collect(Collectors.toList());
+
+ User principal = new User(claims.getSubject(), "", authorities);
+
+ return new UsernamePasswordAuthenticationToken(principal, "", authorities);
+ }
+
+ public boolean validateToken(String authToken) {
+ try {
+ Jwts.parser().setSigningKey(secretKey).parseClaimsJws(authToken);
+ return true;
+ } catch (SignatureException e) {
+ log.info("Invalid JWT signature.");
+ log.trace("Invalid JWT signature trace: {}", e);
+ } catch (MalformedJwtException e) {
+ log.info("Invalid JWT token.");
+ log.trace("Invalid JWT token trace: {}", e);
+ } catch (ExpiredJwtException e) {
+ log.info("Expired JWT token.");
+ log.trace("Expired JWT token trace: {}", e);
+ } catch (UnsupportedJwtException e) {
+ log.info("Unsupported JWT token.");
+ log.trace("Unsupported JWT token trace: {}", e);
+ } catch (IllegalArgumentException e) {
+ log.info("JWT token compact of handler are invalid.");
+ log.trace("JWT token compact of handler are invalid trace: {}", e);
+ }
+ return false;
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/service/package-info.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/service/package-info.java
new file mode 100644
index 0000000000..2d3df85add
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/service/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Service layer beans.
+ */
+package com.car.app.service;
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/CarResource.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/CarResource.java
new file mode 100644
index 0000000000..1ac6caf83c
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/CarResource.java
@@ -0,0 +1,128 @@
+package com.car.app.web.rest;
+
+import com.codahale.metrics.annotation.Timed;
+import com.car.app.domain.Car;
+
+import com.car.app.repository.CarRepository;
+import com.car.app.web.rest.util.HeaderUtil;
+import com.car.app.web.rest.util.PaginationUtil;
+import io.swagger.annotations.ApiParam;
+import io.github.jhipster.web.util.ResponseUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * REST controller for managing Car.
+ */
+@RestController
+@RequestMapping("/api")
+public class CarResource {
+
+ private final Logger log = LoggerFactory.getLogger(CarResource.class);
+
+ private static final String ENTITY_NAME = "car";
+
+ private final CarRepository carRepository;
+
+ public CarResource(CarRepository carRepository) {
+ this.carRepository = carRepository;
+ }
+
+ /**
+ * POST /cars : Create a new car.
+ *
+ * @param car the car to create
+ * @return the ResponseEntity with status 201 (Created) and with body the new car, or with status 400 (Bad Request) if the car has already an ID
+ * @throws URISyntaxException if the Location URI syntax is incorrect
+ */
+ @PostMapping("/cars")
+ @Timed
+ public ResponseEntity createCar(@RequestBody Car car) throws URISyntaxException {
+ log.debug("REST request to save Car : {}", car);
+ if (car.getId() != null) {
+ return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(ENTITY_NAME, "idexists", "A new car cannot already have an ID")).body(null);
+ }
+ Car result = carRepository.save(car);
+ return ResponseEntity.created(new URI("/api/cars/" + result.getId()))
+ .headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString()))
+ .body(result);
+ }
+
+ /**
+ * PUT /cars : Updates an existing car.
+ *
+ * @param car the car to update
+ * @return the ResponseEntity with status 200 (OK) and with body the updated car,
+ * or with status 400 (Bad Request) if the car is not valid,
+ * or with status 500 (Internal Server Error) if the car couldnt be updated
+ * @throws URISyntaxException if the Location URI syntax is incorrect
+ */
+ @PutMapping("/cars")
+ @Timed
+ public ResponseEntity updateCar(@RequestBody Car car) throws URISyntaxException {
+ log.debug("REST request to update Car : {}", car);
+ if (car.getId() == null) {
+ return createCar(car);
+ }
+ Car result = carRepository.save(car);
+ return ResponseEntity.ok()
+ .headers(HeaderUtil.createEntityUpdateAlert(ENTITY_NAME, car.getId().toString()))
+ .body(result);
+ }
+
+ /**
+ * GET /cars : get all the cars.
+ *
+ * @param pageable the pagination information
+ * @return the ResponseEntity with status 200 (OK) and the list of cars in body
+ * @throws URISyntaxException if there is an error to generate the pagination HTTP headers
+ */
+ @GetMapping("/cars")
+ @Timed
+ public ResponseEntity> getAllCars(@ApiParam Pageable pageable) {
+ log.debug("REST request to get a page of Cars");
+ Page page = carRepository.findAll(pageable);
+ HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/cars");
+ return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
+ }
+
+ /**
+ * GET /cars/:id : get the "id" car.
+ *
+ * @param id the id of the car to retrieve
+ * @return the ResponseEntity with status 200 (OK) and with body the car, or with status 404 (Not Found)
+ */
+ @GetMapping("/cars/{id}")
+ @Timed
+ public ResponseEntity getCar(@PathVariable Long id) {
+ log.debug("REST request to get Car : {}", id);
+ Car car = carRepository.findOne(id);
+ return ResponseUtil.wrapOrNotFound(Optional.ofNullable(car));
+ }
+
+ /**
+ * DELETE /cars/:id : delete the "id" car.
+ *
+ * @param id the id of the car to delete
+ * @return the ResponseEntity with status 200 (OK)
+ */
+ @DeleteMapping("/cars/{id}")
+ @Timed
+ public ResponseEntity deleteCar(@PathVariable Long id) {
+ log.debug("REST request to delete Car : {}", id);
+ carRepository.delete(id);
+ return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert(ENTITY_NAME, id.toString())).build();
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/LogsResource.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/LogsResource.java
new file mode 100644
index 0000000000..b9054ac4f7
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/LogsResource.java
@@ -0,0 +1,39 @@
+package com.car.app.web.rest;
+
+import com.car.app.web.rest.vm.LoggerVM;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.LoggerContext;
+import com.codahale.metrics.annotation.Timed;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Controller for view and managing Log Level at runtime.
+ */
+@RestController
+@RequestMapping("/management")
+public class LogsResource {
+
+ @GetMapping("/logs")
+ @Timed
+ public List getList() {
+ LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+ return context.getLoggerList()
+ .stream()
+ .map(LoggerVM::new)
+ .collect(Collectors.toList());
+ }
+
+ @PutMapping("/logs")
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ @Timed
+ public void changeLevel(@RequestBody LoggerVM jsonLogger) {
+ LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+ context.getLogger(jsonLogger.getName()).setLevel(Level.valueOf(jsonLogger.getLevel()));
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/ProfileInfoResource.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/ProfileInfoResource.java
new file mode 100644
index 0000000000..ad2262f458
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/ProfileInfoResource.java
@@ -0,0 +1,69 @@
+package com.car.app.web.rest;
+
+import com.car.app.config.DefaultProfileUtil;
+
+import io.github.jhipster.config.JHipsterProperties;
+
+import org.springframework.core.env.Environment;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Resource to return information about the currently running Spring profiles.
+ */
+@RestController
+@RequestMapping("/api")
+public class ProfileInfoResource {
+
+ private final Environment env;
+
+ private final JHipsterProperties jHipsterProperties;
+
+ public ProfileInfoResource(Environment env, JHipsterProperties jHipsterProperties) {
+ this.env = env;
+ this.jHipsterProperties = jHipsterProperties;
+ }
+
+ @GetMapping("/profile-info")
+ public ProfileInfoVM getActiveProfiles() {
+ String[] activeProfiles = DefaultProfileUtil.getActiveProfiles(env);
+ return new ProfileInfoVM(activeProfiles, getRibbonEnv(activeProfiles));
+ }
+
+ private String getRibbonEnv(String[] activeProfiles) {
+ String[] displayOnActiveProfiles = jHipsterProperties.getRibbon().getDisplayOnActiveProfiles();
+ if (displayOnActiveProfiles == null) {
+ return null;
+ }
+ List ribbonProfiles = new ArrayList<>(Arrays.asList(displayOnActiveProfiles));
+ List springBootProfiles = Arrays.asList(activeProfiles);
+ ribbonProfiles.retainAll(springBootProfiles);
+ if (!ribbonProfiles.isEmpty()) {
+ return ribbonProfiles.get(0);
+ }
+ return null;
+ }
+
+ class ProfileInfoVM {
+
+ private String[] activeProfiles;
+
+ private String ribbonEnv;
+
+ ProfileInfoVM(String[] activeProfiles, String ribbonEnv) {
+ this.activeProfiles = activeProfiles;
+ this.ribbonEnv = ribbonEnv;
+ }
+
+ public String[] getActiveProfiles() {
+ return activeProfiles;
+ }
+
+ public String getRibbonEnv() {
+ return ribbonEnv;
+ }
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/CustomParameterizedException.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/CustomParameterizedException.java
new file mode 100644
index 0000000000..0bf41f2fdb
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/CustomParameterizedException.java
@@ -0,0 +1,34 @@
+package com.car.app.web.rest.errors;
+
+/**
+ * Custom, parameterized exception, which can be translated on the client side.
+ * For example:
+ *
+ *
+ * throw new CustomParameterizedException("myCustomError", "hello", "world");
+ *
+ *
+ * Can be translated with:
+ *
+ *
+ * "error.myCustomError" : "The server says {{params[0]}} to {{params[1]}}"
+ *
+ */
+public class CustomParameterizedException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String message;
+ private final String[] params;
+
+ public CustomParameterizedException(String message, String... params) {
+ super(message);
+ this.message = message;
+ this.params = params;
+ }
+
+ public ParameterizedErrorVM getErrorVM() {
+ return new ParameterizedErrorVM(message, params);
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/ErrorConstants.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/ErrorConstants.java
new file mode 100644
index 0000000000..f6db48f223
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/ErrorConstants.java
@@ -0,0 +1,14 @@
+package com.car.app.web.rest.errors;
+
+public final class ErrorConstants {
+
+ public static final String ERR_CONCURRENCY_FAILURE = "error.concurrencyFailure";
+ public static final String ERR_ACCESS_DENIED = "error.accessDenied";
+ public static final String ERR_VALIDATION = "error.validation";
+ public static final String ERR_METHOD_NOT_SUPPORTED = "error.methodNotSupported";
+ public static final String ERR_INTERNAL_SERVER_ERROR = "error.internalServerError";
+
+ private ErrorConstants() {
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/ErrorVM.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/ErrorVM.java
new file mode 100644
index 0000000000..69d00c00d5
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/ErrorVM.java
@@ -0,0 +1,52 @@
+package com.car.app.web.rest.errors;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * View Model for transferring error message with a list of field errors.
+ */
+public class ErrorVM implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String message;
+ private final String description;
+
+ private List fieldErrors;
+
+ public ErrorVM(String message) {
+ this(message, null);
+ }
+
+ public ErrorVM(String message, String description) {
+ this.message = message;
+ this.description = description;
+ }
+
+ public ErrorVM(String message, String description, List fieldErrors) {
+ this.message = message;
+ this.description = description;
+ this.fieldErrors = fieldErrors;
+ }
+
+ public void add(String objectName, String field, String message) {
+ if (fieldErrors == null) {
+ fieldErrors = new ArrayList<>();
+ }
+ fieldErrors.add(new FieldErrorVM(objectName, field, message));
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public List getFieldErrors() {
+ return fieldErrors;
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/ExceptionTranslator.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/ExceptionTranslator.java
new file mode 100644
index 0000000000..6282b816e1
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/ExceptionTranslator.java
@@ -0,0 +1,85 @@
+package com.car.app.web.rest.errors;
+
+import java.util.List;
+
+import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.dao.ConcurrencyFailureException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.ResponseEntity.BodyBuilder;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.FieldError;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * Controller advice to translate the server side exceptions to client-friendly json structures.
+ */
+@ControllerAdvice
+public class ExceptionTranslator {
+
+ @ExceptionHandler(ConcurrencyFailureException.class)
+ @ResponseStatus(HttpStatus.CONFLICT)
+ @ResponseBody
+ public ErrorVM processConcurrencyError(ConcurrencyFailureException ex) {
+ return new ErrorVM(ErrorConstants.ERR_CONCURRENCY_FAILURE);
+ }
+
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ @ResponseBody
+ public ErrorVM processValidationError(MethodArgumentNotValidException ex) {
+ BindingResult result = ex.getBindingResult();
+ List fieldErrors = result.getFieldErrors();
+
+ return processFieldErrors(fieldErrors);
+ }
+
+ @ExceptionHandler(CustomParameterizedException.class)
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ @ResponseBody
+ public ParameterizedErrorVM processParameterizedValidationError(CustomParameterizedException ex) {
+ return ex.getErrorVM();
+ }
+
+ @ExceptionHandler(AccessDeniedException.class)
+ @ResponseStatus(HttpStatus.FORBIDDEN)
+ @ResponseBody
+ public ErrorVM processAccessDeniedException(AccessDeniedException e) {
+ return new ErrorVM(ErrorConstants.ERR_ACCESS_DENIED, e.getMessage());
+ }
+
+ private ErrorVM processFieldErrors(List fieldErrors) {
+ ErrorVM dto = new ErrorVM(ErrorConstants.ERR_VALIDATION);
+
+ for (FieldError fieldError : fieldErrors) {
+ dto.add(fieldError.getObjectName(), fieldError.getField(), fieldError.getCode());
+ }
+
+ return dto;
+ }
+
+ @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
+ @ResponseBody
+ @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
+ public ErrorVM processMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) {
+ return new ErrorVM(ErrorConstants.ERR_METHOD_NOT_SUPPORTED, exception.getMessage());
+ }
+
+ @ExceptionHandler(Exception.class)
+ public ResponseEntity processRuntimeException(Exception ex) {
+ BodyBuilder builder;
+ ErrorVM errorVM;
+ ResponseStatus responseStatus = AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class);
+ if (responseStatus != null) {
+ builder = ResponseEntity.status(responseStatus.value());
+ errorVM = new ErrorVM("error." + responseStatus.value().value(), responseStatus.reason());
+ } else {
+ builder = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
+ errorVM = new ErrorVM(ErrorConstants.ERR_INTERNAL_SERVER_ERROR, "Internal server error");
+ }
+ return builder.body(errorVM);
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/FieldErrorVM.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/FieldErrorVM.java
new file mode 100644
index 0000000000..cdb2fc07e5
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/FieldErrorVM.java
@@ -0,0 +1,33 @@
+package com.car.app.web.rest.errors;
+
+import java.io.Serializable;
+
+public class FieldErrorVM implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String objectName;
+
+ private final String field;
+
+ private final String message;
+
+ public FieldErrorVM(String dto, String field, String message) {
+ this.objectName = dto;
+ this.field = field;
+ this.message = message;
+ }
+
+ public String getObjectName() {
+ return objectName;
+ }
+
+ public String getField() {
+ return field;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/ParameterizedErrorVM.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/ParameterizedErrorVM.java
new file mode 100644
index 0000000000..b0c40c9cbb
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/errors/ParameterizedErrorVM.java
@@ -0,0 +1,27 @@
+package com.car.app.web.rest.errors;
+
+import java.io.Serializable;
+
+/**
+ * View Model for sending a parameterized error message.
+ */
+public class ParameterizedErrorVM implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private final String message;
+ private final String[] params;
+
+ public ParameterizedErrorVM(String message, String... params) {
+ this.message = message;
+ this.params = params;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String[] getParams() {
+ return params;
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/package-info.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/package-info.java
new file mode 100644
index 0000000000..fb696c0d89
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Spring MVC REST controllers.
+ */
+package com.car.app.web.rest;
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/util/HeaderUtil.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/util/HeaderUtil.java
new file mode 100644
index 0000000000..f6f9c1abb3
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/util/HeaderUtil.java
@@ -0,0 +1,43 @@
+package com.car.app.web.rest.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpHeaders;
+
+/**
+ * Utility class for HTTP headers creation.
+ */
+public final class HeaderUtil {
+
+ private static final Logger log = LoggerFactory.getLogger(HeaderUtil.class);
+
+ private HeaderUtil() {
+ }
+
+ public static HttpHeaders createAlert(String message, String param) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("X-carappApp-alert", message);
+ headers.add("X-carappApp-params", param);
+ return headers;
+ }
+
+ public static HttpHeaders createEntityCreationAlert(String entityName, String param) {
+ return createAlert("A new " + entityName + " is created with identifier " + param, param);
+ }
+
+ public static HttpHeaders createEntityUpdateAlert(String entityName, String param) {
+ return createAlert("A " + entityName + " is updated with identifier " + param, param);
+ }
+
+ public static HttpHeaders createEntityDeletionAlert(String entityName, String param) {
+ return createAlert("A " + entityName + " is deleted with identifier " + param, param);
+ }
+
+ public static HttpHeaders createFailureAlert(String entityName, String errorKey, String defaultMessage) {
+ log.error("Entity creation failed, {}", defaultMessage);
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("X-carappApp-error", defaultMessage);
+ headers.add("X-carappApp-params", entityName);
+ return headers;
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/util/PaginationUtil.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/util/PaginationUtil.java
new file mode 100644
index 0000000000..9ba36f7a44
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/util/PaginationUtil.java
@@ -0,0 +1,47 @@
+package com.car.app.web.rest.util;
+
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpHeaders;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.net.URISyntaxException;
+
+/**
+ * Utility class for handling pagination.
+ *
+ *
+ * Pagination uses the same principles as the Github API,
+ * and follow RFC 5988 (Link header).
+ */
+public final class PaginationUtil {
+
+ private PaginationUtil() {
+ }
+
+ public static HttpHeaders generatePaginationHttpHeaders(Page page, String baseUrl) {
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("X-Total-Count", "" + Long.toString(page.getTotalElements()));
+ String link = "";
+ if ((page.getNumber() + 1) < page.getTotalPages()) {
+ link = "<" + generateUri(baseUrl, page.getNumber() + 1, page.getSize()) + ">; rel=\"next\",";
+ }
+ // prev link
+ if ((page.getNumber()) > 0) {
+ link += "<" + generateUri(baseUrl, page.getNumber() - 1, page.getSize()) + ">; rel=\"prev\",";
+ }
+ // last and first link
+ int lastPage = 0;
+ if (page.getTotalPages() > 0) {
+ lastPage = page.getTotalPages() - 1;
+ }
+ link += "<" + generateUri(baseUrl, lastPage, page.getSize()) + ">; rel=\"last\",";
+ link += "<" + generateUri(baseUrl, 0, page.getSize()) + ">; rel=\"first\"";
+ headers.add(HttpHeaders.LINK, link);
+ return headers;
+ }
+
+ private static String generateUri(String baseUrl, int page, int size) {
+ return UriComponentsBuilder.fromUriString(baseUrl).queryParam("page", page).queryParam("size", size).toUriString();
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/vm/LoggerVM.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/vm/LoggerVM.java
new file mode 100644
index 0000000000..ff76466df7
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/vm/LoggerVM.java
@@ -0,0 +1,48 @@
+package com.car.app.web.rest.vm;
+
+import ch.qos.logback.classic.Logger;
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+/**
+ * View Model object for storing a Logback logger.
+ */
+public class LoggerVM {
+
+ private String name;
+
+ private String level;
+
+ public LoggerVM(Logger logger) {
+ this.name = logger.getName();
+ this.level = logger.getEffectiveLevel().toString();
+ }
+
+ @JsonCreator
+ public LoggerVM() {
+ // Empty public constructor used by Jackson.
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLevel() {
+ return level;
+ }
+
+ public void setLevel(String level) {
+ this.level = level;
+ }
+
+ @Override
+ public String toString() {
+ return "LoggerVM{" +
+ "name='" + name + '\'' +
+ ", level='" + level + '\'' +
+ '}';
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/vm/package-info.java b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/vm/package-info.java
new file mode 100644
index 0000000000..02b0247926
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/java/com/car/app/web/rest/vm/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * View Models used by Spring MVC REST controllers.
+ */
+package com.car.app.web.rest.vm;
diff --git a/jhipster/jhipster-microservice/car-app/src/main/resources/.h2.server.properties b/jhipster/jhipster-microservice/car-app/src/main/resources/.h2.server.properties
new file mode 100644
index 0000000000..54cdead92e
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/resources/.h2.server.properties
@@ -0,0 +1,5 @@
+#H2 Server Properties
+0=JHipster H2 (Disk)|org.h2.Driver|jdbc\:h2\:file\:./target/h2db/db/carapp|carapp
+webAllowOthers=true
+webPort=8082
+webSSL=false
diff --git a/jhipster/src/main/resources/banner.txt b/jhipster/jhipster-microservice/car-app/src/main/resources/banner.txt
similarity index 100%
rename from jhipster/src/main/resources/banner.txt
rename to jhipster/jhipster-microservice/car-app/src/main/resources/banner.txt
diff --git a/jhipster/jhipster-microservice/car-app/src/main/resources/config/application-dev.yml b/jhipster/jhipster-microservice/car-app/src/main/resources/config/application-dev.yml
new file mode 100644
index 0000000000..87462edc75
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/resources/config/application-dev.yml
@@ -0,0 +1,148 @@
+# ===================================================================
+# Spring Boot configuration for the "dev" profile.
+#
+# This configuration overrides the application.yml file.
+#
+# More information on profiles: https://jhipster.github.io/profiles/
+# More information on configuration properties: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+# ===================================================================
+# Standard Spring Boot properties.
+# Full reference is available at:
+# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
+# ===================================================================
+
+eureka:
+ instance:
+ prefer-ip-address: true
+ client:
+ enabled: true
+ healthcheck:
+ enabled: true
+ registerWithEureka: true
+ fetchRegistry: true
+ serviceUrl:
+ defaultZone: http://admin:${jhipster.registry.password}@localhost:8761/eureka/
+
+spring:
+ profiles:
+ active: dev
+ include: swagger
+ devtools:
+ restart:
+ enabled: true
+ livereload:
+ enabled: false # we use gulp + BrowserSync for livereload
+ jackson:
+ serialization.indent_output: true
+ datasource:
+ type: com.zaxxer.hikari.HikariDataSource
+ url: jdbc:h2:file:./target/h2db/db/carapp;DB_CLOSE_DELAY=-1
+ username: carapp
+ password:
+ h2:
+ console:
+ enabled: false
+ jpa:
+ database-platform: io.github.jhipster.domain.util.FixedH2Dialect
+ database: H2
+ show-sql: true
+ properties:
+ hibernate.id.new_generator_mappings: true
+ hibernate.cache.use_second_level_cache: true
+ hibernate.cache.use_query_cache: false
+ hibernate.generate_statistics: true
+ hibernate.cache.region.factory_class: com.hazelcast.hibernate.HazelcastCacheRegionFactory
+ hibernate.cache.hazelcast.instance_name: carapp
+ hibernate.cache.use_minimal_puts: true
+ hibernate.cache.hazelcast.use_lite_member: true
+ mail:
+ host: localhost
+ port: 25
+ username:
+ password:
+ messages:
+ cache-seconds: 1
+ thymeleaf:
+ cache: false
+
+liquibase:
+ contexts: dev
+
+# ===================================================================
+# To enable SSL, generate a certificate using:
+# keytool -genkey -alias carapp -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
+#
+# You can also use Let's Encrypt:
+# https://maximilian-boehm.com/hp2121/Create-a-Java-Keystore-JKS-from-Let-s-Encrypt-Certificates.htm
+#
+# Then, modify the server.ssl properties so your "server" configuration looks like:
+#
+# server:
+# port: 8443
+# ssl:
+# key-store: keystore.p12
+# key-store-password:
+# keyStoreType: PKCS12
+# keyAlias: carapp
+# ===================================================================
+server:
+ port: 8081
+
+# ===================================================================
+# JHipster specific properties
+#
+# Full reference is available at: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+jhipster:
+ http:
+ version: V_1_1 # To use HTTP/2 you will need SSL support (see above the "server.ssl" configuration)
+ cache: # Cache configuration
+ hazelcast: # Hazelcast distributed cache
+ time-to-live-seconds: 3600
+ backup-count: 1
+ security:
+ authentication:
+ jwt:
+ secret: my-secret-token-to-change-in-production
+ # Token is valid 24 hours
+ token-validity-in-seconds: 86400
+ token-validity-in-seconds-for-remember-me: 2592000
+ mail: # specific JHipster mail property, for standard properties see MailProperties
+ from: carapp@localhost
+ base-url: http://127.0.0.1:8081
+ metrics: # DropWizard Metrics configuration, used by MetricsConfiguration
+ jmx.enabled: true
+ graphite: # Use the "graphite" Maven profile to have the Graphite dependencies
+ enabled: false
+ host: localhost
+ port: 2003
+ prefix: carapp
+ prometheus: # Use the "prometheus" Maven profile to have the Prometheus dependencies
+ enabled: false
+ endpoint: /prometheusMetrics
+ logs: # Reports Dropwizard metrics in the logs
+ enabled: false
+ reportFrequency: 60 # in seconds
+ logging:
+ logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration
+ enabled: false
+ host: localhost
+ port: 5000
+ queue-size: 512
+ spectator-metrics: # Reports Spectator Circuit Breaker metrics in the logs
+ enabled: false
+ # edit spring.metrics.export.delay-millis to set report frequency
+
+# ===================================================================
+# 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://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+application:
diff --git a/jhipster/jhipster-microservice/car-app/src/main/resources/config/application-prod.yml b/jhipster/jhipster-microservice/car-app/src/main/resources/config/application-prod.yml
new file mode 100644
index 0000000000..9a7f557371
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/resources/config/application-prod.yml
@@ -0,0 +1,150 @@
+# ===================================================================
+# Spring Boot configuration for the "prod" profile.
+#
+# This configuration overrides the application.yml file.
+#
+# More information on profiles: https://jhipster.github.io/profiles/
+# More information on configuration properties: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+# ===================================================================
+# Standard Spring Boot properties.
+# Full reference is available at:
+# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
+# ===================================================================
+
+eureka:
+ instance:
+ prefer-ip-address: true
+ client:
+ enabled: true
+ healthcheck:
+ enabled: true
+ registerWithEureka: true
+ fetchRegistry: true
+ serviceUrl:
+ defaultZone: http://admin:${jhipster.registry.password}@localhost:8761/eureka/
+
+spring:
+ devtools:
+ restart:
+ enabled: false
+ livereload:
+ enabled: false
+ datasource:
+ type: com.zaxxer.hikari.HikariDataSource
+ url: jdbc:mysql://localhost:3306/carapp?useUnicode=true&characterEncoding=utf8&useSSL=false
+ username: root
+ password:
+ hikari:
+ data-source-properties:
+ cachePrepStmts: true
+ prepStmtCacheSize: 250
+ prepStmtCacheSqlLimit: 2048
+ useServerPrepStmts: true
+ jpa:
+ database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
+ database: MYSQL
+ show-sql: false
+ properties:
+ hibernate.id.new_generator_mappings: true
+ hibernate.cache.use_second_level_cache: true
+ hibernate.cache.use_query_cache: false
+ hibernate.generate_statistics: false
+ hibernate.cache.region.factory_class: com.hazelcast.hibernate.HazelcastCacheRegionFactory
+ hibernate.cache.hazelcast.instance_name: carapp
+ hibernate.cache.use_minimal_puts: true
+ hibernate.cache.hazelcast.use_lite_member: true
+ mail:
+ host: localhost
+ port: 25
+ username:
+ password:
+ thymeleaf:
+ cache: true
+
+liquibase:
+ contexts: prod
+
+# ===================================================================
+# To enable SSL, generate a certificate using:
+# keytool -genkey -alias carapp -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
+#
+# You can also use Let's Encrypt:
+# https://maximilian-boehm.com/hp2121/Create-a-Java-Keystore-JKS-from-Let-s-Encrypt-Certificates.htm
+#
+# Then, modify the server.ssl properties so your "server" configuration looks like:
+#
+# server:
+# port: 443
+# ssl:
+# key-store: keystore.p12
+# key-store-password:
+# keyStoreType: PKCS12
+# keyAlias: carapp
+# ===================================================================
+server:
+ port: 8081
+ compression:
+ enabled: true
+ mime-types: text/html,text/xml,text/plain,text/css, application/javascript, application/json
+ min-response-size: 1024
+
+# ===================================================================
+# JHipster specific properties
+#
+# Full reference is available at: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+jhipster:
+ http:
+ version: V_1_1 # To use HTTP/2 you will need SSL support (see above the "server.ssl" configuration)
+ cache: # Used by the CachingHttpHeadersFilter
+ timeToLiveInDays: 1461
+ cache: # Cache configuration
+ hazelcast: # Hazelcast distributed cache
+ time-to-live-seconds: 3600
+ backup-count: 1
+ security:
+ authentication:
+ jwt:
+ secret: 0ebd193e0552c4ac548217d353abbde0761a1997
+ # Token is valid 24 hours
+ token-validity-in-seconds: 86400
+ token-validity-in-seconds-for-remember-me: 2592000
+ mail: # specific JHipster mail property, for standard properties see MailProperties
+ from: carapp@localhost
+ base-url: http://my-server-url-to-change # Modify according to your server's URL
+ metrics: # DropWizard Metrics configuration, used by MetricsConfiguration
+ jmx.enabled: true
+ graphite:
+ enabled: false
+ host: localhost
+ port: 2003
+ prefix: carapp
+ prometheus:
+ enabled: false
+ endpoint: /prometheusMetrics
+ logs: # Reports Dropwizard metrics in the logs
+ enabled: false
+ reportFrequency: 60 # in seconds
+ logging:
+ logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration
+ enabled: false
+ host: localhost
+ port: 5000
+ queue-size: 512
+ spectator-metrics: # Reports Spectator Circuit Breaker metrics in the logs
+ enabled: false
+ # edit spring.metrics.export.delay-millis to set report frequency
+
+# ===================================================================
+# 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://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+application:
diff --git a/jhipster/jhipster-microservice/car-app/src/main/resources/config/application.yml b/jhipster/jhipster-microservice/car-app/src/main/resources/config/application.yml
new file mode 100644
index 0000000000..40ccb38cad
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/resources/config/application.yml
@@ -0,0 +1,119 @@
+# ===================================================================
+# Spring Boot configuration.
+#
+# This configuration will be overriden by the Spring profile you use,
+# for example application-dev.yml if you use the "dev" profile.
+#
+# More information on profiles: https://jhipster.github.io/profiles/
+# More information on configuration properties: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+# ===================================================================
+# Standard Spring Boot properties.
+# Full reference is available at:
+# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
+# ===================================================================
+
+eureka:
+ instance:
+ appname: carapp
+ instanceId: carapp:${spring.application.instance_id:${random.value}}
+ statusPageUrlPath: ${management.context-path}/info
+ healthCheckUrlPath: ${management.context-path}/health
+ metadata-map:
+ profile: ${spring.profiles.active}
+ version: ${info.project.version}
+ribbon:
+ eureka:
+ enabled: true
+# See https://github.com/Netflix/Hystrix/wiki/Configuration
+#hystrix:
+# command:
+# default:
+# execution:
+# isolation:
+# thread:
+# timeoutInMilliseconds: 10000
+
+management:
+ security:
+ roles: ADMIN
+ context-path: /management
+ health:
+ mail:
+ enabled: false # When using the MailService, configure an SMTP server and set this to true
+spring:
+ application:
+ name: carapp
+ jackson:
+ serialization.write_dates_as_timestamps: false
+ jpa:
+ open-in-view: false
+ hibernate:
+ ddl-auto: none
+ naming:
+ physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
+ implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
+ messages:
+ basename: i18n/messages
+ mvc:
+ favicon:
+ enabled: false
+ thymeleaf:
+ mode: XHTML
+
+security:
+ basic:
+ enabled: false
+
+server:
+ session:
+ cookie:
+ http-only: true
+
+
+# ===================================================================
+# JHipster specific properties
+#
+# Full reference is available at: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+jhipster:
+ async:
+ core-pool-size: 2
+ max-pool-size: 50
+ queue-capacity: 10000
+ # By default CORS is disabled. Uncomment to enable.
+ #cors:
+ #allowed-origins: "*"
+ #allowed-methods: GET, PUT, POST, DELETE, OPTIONS
+ #allowed-headers: "*"
+ #exposed-headers:
+ #allow-credentials: true
+ #max-age: 1800
+ mail:
+ from: carapp@localhost
+ swagger:
+ default-include-pattern: /api/.*
+ title: carapp API
+ description: carapp API documentation
+ version: 0.0.1
+ terms-of-service-url:
+ contact-name:
+ contact-url:
+ contact-email:
+ license:
+ license-url:
+ ribbon:
+ display-on-active-profiles: dev
+
+# ===================================================================
+# 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://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+application:
diff --git a/jhipster/jhipster-microservice/car-app/src/main/resources/config/bootstrap-prod.yml b/jhipster/jhipster-microservice/car-app/src/main/resources/config/bootstrap-prod.yml
new file mode 100644
index 0000000000..524e37ea53
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/resources/config/bootstrap-prod.yml
@@ -0,0 +1,22 @@
+# ===================================================================
+# Spring Cloud Config bootstrap configuration for the "prod" profile
+# ===================================================================
+
+spring:
+ cloud:
+ config:
+ fail-fast: true
+ retry:
+ initial-interval: 1000
+ max-interval: 2000
+ max-attempts: 100
+ 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: carapp
+ 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 config source git repository
+
+jhipster:
+ registry:
+ password: admin
diff --git a/jhipster/jhipster-microservice/car-app/src/main/resources/config/bootstrap.yml b/jhipster/jhipster-microservice/car-app/src/main/resources/config/bootstrap.yml
new file mode 100644
index 0000000000..c1a608c4a5
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/resources/config/bootstrap.yml
@@ -0,0 +1,30 @@
+# ===================================================================
+# Spring Cloud Config bootstrap configuration for the "dev" profile
+# In prod profile, properties will be overwriten by the ones defined in bootstrap-prod.yml
+# ===================================================================
+
+jhipster:
+ registry:
+ password: admin
+
+spring:
+ application:
+ name: carapp
+ profiles:
+ # The commented value for `active` can be replaced with valid Spring profiles to load.
+ # Otherwise, it will be filled in by maven when building the WAR file
+ # Either way, it can be overridden by `--spring.profiles.active` value passed in the commandline or `-Dspring.profiles.active` set in `JAVA_OPTS`
+ active: #spring.profiles.active#
+ cloud:
+ config:
+ fail-fast: true
+ 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: carapp
+ profile: dev # 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 config source git repository
+
+info:
+ project:
+ version: #project.version#
diff --git a/jhipster/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml b/jhipster/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml
new file mode 100644
index 0000000000..2a1ee4d6bf
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jhipster/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/20170503041524_added_entity_Car.xml b/jhipster/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/20170503041524_added_entity_Car.xml
new file mode 100644
index 0000000000..0b8c3f5136
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/20170503041524_added_entity_Car.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jhipster/jhipster-microservice/car-app/src/main/resources/config/liquibase/master.xml b/jhipster/jhipster-microservice/car-app/src/main/resources/config/liquibase/master.xml
new file mode 100644
index 0000000000..398b615ea1
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/resources/config/liquibase/master.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/jhipster/jhipster-microservice/car-app/src/main/resources/i18n/messages.properties b/jhipster/jhipster-microservice/car-app/src/main/resources/i18n/messages.properties
new file mode 100644
index 0000000000..9a850cb789
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/resources/i18n/messages.properties
@@ -0,0 +1,22 @@
+# Error page
+error.title=Your request cannot be processed
+error.subtitle=Sorry, an error has occurred.
+error.status=Status:
+error.message=Message:
+
+# Activation e-mail
+email.activation.title=carapp account activation
+email.activation.greeting=Dear {0}
+email.activation.text1=Your carapp account has been created, please click on the URL below to activate it:
+email.activation.text2=Regards,
+email.signature=carapp Team.
+
+# Creation email
+email.creation.text1=Your carapp account has been created, please click on the URL below to access it:
+
+# Reset e-mail
+email.reset.title=carapp password reset
+email.reset.greeting=Dear {0}
+email.reset.text1=For your carapp account a password reset was requested, please click on the URL below to reset it:
+email.reset.text2=Regards,
+
diff --git a/jhipster/jhipster-microservice/car-app/src/main/resources/logback-spring.xml b/jhipster/jhipster-microservice/car-app/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000000..33c3d4fde4
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/main/resources/logback-spring.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
diff --git a/jhipster/src/main/resources/templates/error.html b/jhipster/jhipster-microservice/car-app/src/main/resources/templates/error.html
similarity index 100%
rename from jhipster/src/main/resources/templates/error.html
rename to jhipster/jhipster-microservice/car-app/src/main/resources/templates/error.html
diff --git a/jhipster/jhipster-microservice/car-app/src/test/java/com/car/app/web/rest/CarResourceIntegrationTest.java b/jhipster/jhipster-microservice/car-app/src/test/java/com/car/app/web/rest/CarResourceIntegrationTest.java
new file mode 100644
index 0000000000..446df399da
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/test/java/com/car/app/web/rest/CarResourceIntegrationTest.java
@@ -0,0 +1,244 @@
+package com.car.app.web.rest;
+
+import com.car.app.CarappApp;
+
+import com.car.app.domain.Car;
+import com.car.app.repository.CarRepository;
+import com.car.app.web.rest.errors.ExceptionTranslator;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.persistence.EntityManager;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.hasItem;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+/**
+ * Test class for the CarResource REST controller.
+ *
+ * @see CarResource
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = CarappApp.class)
+public class CarResourceIntegrationTest {
+
+ private static final String DEFAULT_MAKE = "AAAAAAAAAA";
+ private static final String UPDATED_MAKE = "BBBBBBBBBB";
+
+ private static final String DEFAULT_BRAND = "AAAAAAAAAA";
+ private static final String UPDATED_BRAND = "BBBBBBBBBB";
+
+ private static final Double DEFAULT_PRICE = 1D;
+ private static final Double UPDATED_PRICE = 2D;
+
+ @Autowired
+ private CarRepository carRepository;
+
+ @Autowired
+ private MappingJackson2HttpMessageConverter jacksonMessageConverter;
+
+ @Autowired
+ private PageableHandlerMethodArgumentResolver pageableArgumentResolver;
+
+ @Autowired
+ private ExceptionTranslator exceptionTranslator;
+
+ @Autowired
+ private EntityManager em;
+
+ private MockMvc restCarMockMvc;
+
+ private Car car;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ CarResource carResource = new CarResource(carRepository);
+ this.restCarMockMvc = MockMvcBuilders.standaloneSetup(carResource)
+ .setCustomArgumentResolvers(pageableArgumentResolver)
+ .setControllerAdvice(exceptionTranslator)
+ .setMessageConverters(jacksonMessageConverter).build();
+ }
+
+ /**
+ * Create an entity for this test.
+ *
+ * This is a static method, as tests for other entities might also need it,
+ * if they test an entity which requires the current entity.
+ */
+ public static Car createEntity(EntityManager em) {
+ Car car = new Car()
+ .make(DEFAULT_MAKE)
+ .brand(DEFAULT_BRAND)
+ .price(DEFAULT_PRICE);
+ return car;
+ }
+
+ @Before
+ public void initTest() {
+ car = createEntity(em);
+ }
+
+ @Test
+ @Transactional
+ public void createCar() throws Exception {
+ int databaseSizeBeforeCreate = carRepository.findAll().size();
+
+ // Create the Car
+ restCarMockMvc.perform(post("/api/cars")
+ .contentType(TestUtil.APPLICATION_JSON_UTF8)
+ .content(TestUtil.convertObjectToJsonBytes(car)))
+ .andExpect(status().isCreated());
+
+ // Validate the Car in the database
+ List carList = carRepository.findAll();
+ assertThat(carList).hasSize(databaseSizeBeforeCreate + 1);
+ Car testCar = carList.get(carList.size() - 1);
+ assertThat(testCar.getMake()).isEqualTo(DEFAULT_MAKE);
+ assertThat(testCar.getBrand()).isEqualTo(DEFAULT_BRAND);
+ assertThat(testCar.getPrice()).isEqualTo(DEFAULT_PRICE);
+ }
+
+ @Test
+ @Transactional
+ public void createCarWithExistingId() throws Exception {
+ int databaseSizeBeforeCreate = carRepository.findAll().size();
+
+ // Create the Car with an existing ID
+ car.setId(1L);
+
+ // An entity with an existing ID cannot be created, so this API call must fail
+ restCarMockMvc.perform(post("/api/cars")
+ .contentType(TestUtil.APPLICATION_JSON_UTF8)
+ .content(TestUtil.convertObjectToJsonBytes(car)))
+ .andExpect(status().isBadRequest());
+
+ // Validate the Alice in the database
+ List carList = carRepository.findAll();
+ assertThat(carList).hasSize(databaseSizeBeforeCreate);
+ }
+
+ @Test
+ @Transactional
+ public void getAllCars() throws Exception {
+ // Initialize the database
+ carRepository.saveAndFlush(car);
+
+ // Get all the carList
+ restCarMockMvc.perform(get("/api/cars?sort=id,desc"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
+ .andExpect(jsonPath("$.[*].id").value(hasItem(car.getId().intValue())))
+ .andExpect(jsonPath("$.[*].make").value(hasItem(DEFAULT_MAKE.toString())))
+ .andExpect(jsonPath("$.[*].brand").value(hasItem(DEFAULT_BRAND.toString())))
+ .andExpect(jsonPath("$.[*].price").value(hasItem(DEFAULT_PRICE.doubleValue())));
+ }
+
+ @Test
+ @Transactional
+ public void getCar() throws Exception {
+ // Initialize the database
+ carRepository.saveAndFlush(car);
+
+ // Get the car
+ restCarMockMvc.perform(get("/api/cars/{id}", car.getId()))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
+ .andExpect(jsonPath("$.id").value(car.getId().intValue()))
+ .andExpect(jsonPath("$.make").value(DEFAULT_MAKE.toString()))
+ .andExpect(jsonPath("$.brand").value(DEFAULT_BRAND.toString()))
+ .andExpect(jsonPath("$.price").value(DEFAULT_PRICE.doubleValue()));
+ }
+
+ @Test
+ @Transactional
+ public void getNonExistingCar() throws Exception {
+ // Get the car
+ restCarMockMvc.perform(get("/api/cars/{id}", Long.MAX_VALUE))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @Transactional
+ public void updateCar() throws Exception {
+ // Initialize the database
+ carRepository.saveAndFlush(car);
+ int databaseSizeBeforeUpdate = carRepository.findAll().size();
+
+ // Update the car
+ Car updatedCar = carRepository.findOne(car.getId());
+ updatedCar
+ .make(UPDATED_MAKE)
+ .brand(UPDATED_BRAND)
+ .price(UPDATED_PRICE);
+
+ restCarMockMvc.perform(put("/api/cars")
+ .contentType(TestUtil.APPLICATION_JSON_UTF8)
+ .content(TestUtil.convertObjectToJsonBytes(updatedCar)))
+ .andExpect(status().isOk());
+
+ // Validate the Car in the database
+ List carList = carRepository.findAll();
+ assertThat(carList).hasSize(databaseSizeBeforeUpdate);
+ Car testCar = carList.get(carList.size() - 1);
+ assertThat(testCar.getMake()).isEqualTo(UPDATED_MAKE);
+ assertThat(testCar.getBrand()).isEqualTo(UPDATED_BRAND);
+ assertThat(testCar.getPrice()).isEqualTo(UPDATED_PRICE);
+ }
+
+ @Test
+ @Transactional
+ public void updateNonExistingCar() throws Exception {
+ int databaseSizeBeforeUpdate = carRepository.findAll().size();
+
+ // Create the Car
+
+ // If the entity doesn't have an ID, it will be created instead of just being updated
+ restCarMockMvc.perform(put("/api/cars")
+ .contentType(TestUtil.APPLICATION_JSON_UTF8)
+ .content(TestUtil.convertObjectToJsonBytes(car)))
+ .andExpect(status().isCreated());
+
+ // Validate the Car in the database
+ List carList = carRepository.findAll();
+ assertThat(carList).hasSize(databaseSizeBeforeUpdate + 1);
+ }
+
+ @Test
+ @Transactional
+ public void deleteCar() throws Exception {
+ // Initialize the database
+ carRepository.saveAndFlush(car);
+ int databaseSizeBeforeDelete = carRepository.findAll().size();
+
+ // Get the car
+ restCarMockMvc.perform(delete("/api/cars/{id}", car.getId())
+ .accept(TestUtil.APPLICATION_JSON_UTF8))
+ .andExpect(status().isOk());
+
+ // Validate the database is empty
+ List carList = carRepository.findAll();
+ assertThat(carList).hasSize(databaseSizeBeforeDelete - 1);
+ }
+
+ @Test
+ @Transactional
+ public void equalsVerifier() throws Exception {
+ TestUtil.equalsVerifier(Car.class);
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/test/java/com/car/app/web/rest/TestUtil.java b/jhipster/jhipster-microservice/car-app/src/test/java/com/car/app/web/rest/TestUtil.java
new file mode 100644
index 0000000000..631200376b
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/test/java/com/car/app/web/rest/TestUtil.java
@@ -0,0 +1,120 @@
+package com.car.app.web.rest;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.http.MediaType;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeParseException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Utility class for testing REST controllers.
+ */
+public class TestUtil {
+
+ /** MediaType for JSON UTF8 */
+ public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(
+ MediaType.APPLICATION_JSON.getType(),
+ MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
+
+ /**
+ * Convert an object to JSON byte array.
+ *
+ * @param object
+ * the object to convert
+ * @return the JSON byte array
+ * @throws IOException
+ */
+ public static byte[] convertObjectToJsonBytes(Object object)
+ throws IOException {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+
+ JavaTimeModule module = new JavaTimeModule();
+ mapper.registerModule(module);
+
+ return mapper.writeValueAsBytes(object);
+ }
+
+ /**
+ * Create a byte array with a specific size filled with specified data.
+ *
+ * @param size the size of the byte array
+ * @param data the data to put in the byte array
+ * @return the JSON byte array
+ */
+ public static byte[] createByteArray(int size, String data) {
+ byte[] byteArray = new byte[size];
+ for (int i = 0; i < size; i++) {
+ byteArray[i] = Byte.parseByte(data, 2);
+ }
+ return byteArray;
+ }
+
+ /**
+ * A matcher that tests that the examined string represents the same instant as the reference datetime.
+ */
+ public static class ZonedDateTimeMatcher extends TypeSafeDiagnosingMatcher {
+
+ private final ZonedDateTime date;
+
+ public ZonedDateTimeMatcher(ZonedDateTime date) {
+ this.date = date;
+ }
+
+ @Override
+ protected boolean matchesSafely(String item, Description mismatchDescription) {
+ try {
+ if (!date.isEqual(ZonedDateTime.parse(item))) {
+ mismatchDescription.appendText("was ").appendValue(item);
+ return false;
+ }
+ return true;
+ } catch (DateTimeParseException e) {
+ mismatchDescription.appendText("was ").appendValue(item)
+ .appendText(", which could not be parsed as a ZonedDateTime");
+ return false;
+ }
+
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("a String representing the same Instant as ").appendValue(date);
+ }
+ }
+
+ /**
+ * Creates a matcher that matches when the examined string reprensents the same instant as the reference datetime
+ * @param date the reference datetime against which the examined string is checked
+ */
+ public static ZonedDateTimeMatcher sameInstant(ZonedDateTime date) {
+ return new ZonedDateTimeMatcher(date);
+ }
+
+ /**
+ * Verifies the equals/hashcode contract on the domain object.
+ */
+ public static void equalsVerifier(Class clazz) throws Exception {
+ Object domainObject1 = clazz.getConstructor().newInstance();
+ assertThat(domainObject1.toString()).isNotNull();
+ assertThat(domainObject1).isEqualTo(domainObject1);
+ assertThat(domainObject1.hashCode()).isEqualTo(domainObject1.hashCode());
+ // Test with an instance of another class
+ Object testOtherObject = new Object();
+ assertThat(domainObject1).isNotEqualTo(testOtherObject);
+ // Test with an instance of the same class
+ Object domainObject2 = clazz.getConstructor().newInstance();
+ assertThat(domainObject1).isNotEqualTo(domainObject2);
+ // HashCodes are equals because the objects are not persisted yet
+ assertThat(domainObject1.hashCode()).isEqualTo(domainObject2.hashCode());
+ }
+}
diff --git a/jhipster/jhipster-microservice/car-app/src/test/resources/config/application.yml b/jhipster/jhipster-microservice/car-app/src/test/resources/config/application.yml
new file mode 100644
index 0000000000..a9e3b02b64
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/test/resources/config/application.yml
@@ -0,0 +1,102 @@
+# ===================================================================
+# Spring Boot configuration.
+#
+# This configuration is used for unit/integration tests.
+#
+# More information on profiles: https://jhipster.github.io/profiles/
+# More information on configuration properties: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+# ===================================================================
+# Standard Spring Boot properties.
+# Full reference is available at:
+# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
+# ===================================================================
+
+eureka:
+ client:
+ enabled: false
+ instance:
+ appname: carapp
+ instanceId: carapp:${spring.application.instance_id:${random.value}}
+
+spring:
+ application:
+ name: carapp
+ jackson:
+ serialization.write_dates_as_timestamps: false
+ cache:
+ type: none
+ datasource:
+ type: com.zaxxer.hikari.HikariDataSource
+ url: jdbc:h2:mem:carapp;DB_CLOSE_DELAY=-1
+ name:
+ username:
+ password:
+ jpa:
+ database-platform: io.github.jhipster.domain.util.FixedH2Dialect
+ database: H2
+ open-in-view: false
+ show-sql: true
+ hibernate:
+ ddl-auto: none
+ naming:
+ physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
+ implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
+ properties:
+ hibernate.id.new_generator_mappings: true
+ hibernate.cache.use_second_level_cache: false
+ hibernate.cache.use_query_cache: false
+ hibernate.generate_statistics: true
+ hibernate.hbm2ddl.auto: validate
+ mail:
+ host: localhost
+ messages:
+ basename: i18n/messages
+ mvc:
+ favicon:
+ enabled: false
+ thymeleaf:
+ mode: XHTML
+
+liquibase:
+ contexts: test
+
+security:
+ basic:
+ enabled: false
+
+server:
+ port: 10344
+ address: localhost
+
+# ===================================================================
+# JHipster specific properties
+#
+# Full reference is available at: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+jhipster:
+ async:
+ core-pool-size: 2
+ max-pool-size: 50
+ queue-capacity: 10000
+ security:
+ authentication:
+ jwt:
+ secret: 0ebd193e0552c4ac548217d353abbde0761a1997
+ # Token is valid 24 hours
+ token-validity-in-seconds: 86400
+ metrics: # DropWizard Metrics configuration, used by MetricsConfiguration
+ jmx.enabled: true
+
+# ===================================================================
+# 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://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+application:
diff --git a/jhipster/jhipster-microservice/car-app/src/test/resources/config/bootstrap.yml b/jhipster/jhipster-microservice/car-app/src/test/resources/config/bootstrap.yml
new file mode 100644
index 0000000000..11cd6af21c
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/test/resources/config/bootstrap.yml
@@ -0,0 +1,4 @@
+spring:
+ cloud:
+ config:
+ enabled: false
diff --git a/jhipster/jhipster-microservice/car-app/src/test/resources/logback-test.xml b/jhipster/jhipster-microservice/car-app/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..aace473c4c
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/src/test/resources/logback-test.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jhipster/jhipster-microservice/car-app/yarn.lock b/jhipster/jhipster-microservice/car-app/yarn.lock
new file mode 100644
index 0000000000..4333a516f1
--- /dev/null
+++ b/jhipster/jhipster-microservice/car-app/yarn.lock
@@ -0,0 +1,2439 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+abbrev@1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f"
+
+acorn-jsx@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
+ dependencies:
+ acorn "^3.0.4"
+
+acorn@^3.0.4:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
+
+ajv@^4.9.1:
+ version "4.11.8"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
+ dependencies:
+ co "^4.6.0"
+ json-stable-stringify "^1.0.1"
+
+amdefine@>=0.0.4:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
+
+ansi-escapes@^1.1.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
+
+ansi-regex@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+
+ansi-styles@^2.0.0, ansi-styles@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
+
+ansi@^0.3.0, ansi@~0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21"
+
+are-we-there-yet@~1.1.2:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d"
+ dependencies:
+ delegates "^1.0.0"
+ readable-stream "^2.0.6"
+
+argparse@^1.0.7:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
+ dependencies:
+ sprintf-js "~1.0.2"
+
+array-differ@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031"
+
+array-find-index@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
+
+array-union@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
+ dependencies:
+ array-uniq "^1.0.1"
+
+array-uniq@^1.0.0, array-uniq@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
+
+arrify@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
+
+asn1@~0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
+
+assert-plus@1.0.0, assert-plus@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+
+assert-plus@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
+
+ast-query@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/ast-query/-/ast-query-2.0.0.tgz#3588e79ad8de07ce50df1e781cc2bda1fd69a453"
+ dependencies:
+ acorn-jsx "^3.0.1"
+ class-extend "^0.1.1"
+ escodegen-wallaby "^1.6.7"
+ lodash "^4.6.1"
+ traverse "^0.6.6"
+
+async@^1.0.0, async@^1.4.2:
+ version "1.5.2"
+ resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
+
+async@^2.0.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/async/-/async-2.4.0.tgz#4990200f18ea5b837c2cc4f8c031a6985c385611"
+ dependencies:
+ lodash "^4.14.0"
+
+asynckit@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+
+aws-sign2@~0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
+
+aws4@^1.2.1:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
+
+balanced-match@^0.4.1:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
+
+bcrypt-pbkdf@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
+ dependencies:
+ tweetnacl "^0.14.3"
+
+bin-version-check@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/bin-version-check/-/bin-version-check-2.1.0.tgz#e4e5df290b9069f7d111324031efc13fdd11a5b0"
+ dependencies:
+ bin-version "^1.0.0"
+ minimist "^1.1.0"
+ semver "^4.0.3"
+ semver-truncate "^1.0.0"
+
+bin-version@^1.0.0:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/bin-version/-/bin-version-1.0.4.tgz#9eb498ee6fd76f7ab9a7c160436f89579435d78e"
+ dependencies:
+ find-versions "^1.0.0"
+
+"binaryextensions@1 || 2":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.0.0.tgz#e597d1a7a6a3558a2d1c7241a16c99965e6aa40f"
+
+boolbase@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
+
+boom@2.x.x:
+ version "2.10.1"
+ resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
+ dependencies:
+ hoek "2.x.x"
+
+boxen@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/boxen/-/boxen-0.3.1.tgz#a7d898243ae622f7abb6bb604d740a76c6a5461b"
+ dependencies:
+ chalk "^1.1.1"
+ filled-array "^1.0.0"
+ object-assign "^4.0.1"
+ repeating "^2.0.0"
+ string-width "^1.0.1"
+ widest-line "^1.0.0"
+
+brace-expansion@^1.0.0:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59"
+ dependencies:
+ balanced-match "^0.4.1"
+ concat-map "0.0.1"
+
+buffer-shims@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51"
+
+builtin-modules@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
+
+camelcase-keys@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
+ dependencies:
+ camelcase "^2.0.0"
+ map-obj "^1.0.0"
+
+camelcase@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
+
+capture-stack-trace@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d"
+
+caseless@~0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
+
+chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
+ dependencies:
+ ansi-styles "^2.2.1"
+ escape-string-regexp "^1.0.2"
+ has-ansi "^2.0.0"
+ strip-ansi "^3.0.0"
+ supports-color "^2.0.0"
+
+cheerio@0.22.0:
+ version "0.22.0"
+ resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e"
+ dependencies:
+ css-select "~1.2.0"
+ dom-serializer "~0.1.0"
+ entities "~1.1.1"
+ htmlparser2 "^3.9.1"
+ lodash.assignin "^4.0.9"
+ lodash.bind "^4.1.4"
+ lodash.defaults "^4.0.1"
+ lodash.filter "^4.4.0"
+ lodash.flatten "^4.2.0"
+ lodash.foreach "^4.3.0"
+ lodash.map "^4.4.0"
+ lodash.merge "^4.4.0"
+ lodash.pick "^4.2.1"
+ lodash.reduce "^4.4.0"
+ lodash.reject "^4.4.0"
+ lodash.some "^4.4.0"
+
+cheerio@^0.19.0:
+ version "0.19.0"
+ resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.19.0.tgz#772e7015f2ee29965096d71ea4175b75ab354925"
+ dependencies:
+ css-select "~1.0.0"
+ dom-serializer "~0.1.0"
+ entities "~1.1.1"
+ htmlparser2 "~3.8.1"
+ lodash "^3.2.0"
+
+class-extend@^0.1.0, class-extend@^0.1.1:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/class-extend/-/class-extend-0.1.2.tgz#8057a82b00f53f82a5d62c50ef8cffdec6fabc34"
+ dependencies:
+ object-assign "^2.0.0"
+
+cli-boxes@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
+
+cli-cursor@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
+ dependencies:
+ restore-cursor "^1.0.1"
+
+cli-list@^0.1.1:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/cli-list/-/cli-list-0.1.8.tgz#aee6d45c4c59bf80068bb968089fb06f1aeddc0a"
+
+cli-table@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23"
+ dependencies:
+ colors "1.0.3"
+
+cli-width@^1.0.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-1.1.1.tgz#a4d293ef67ebb7b88d4a4d42c0ccf00c4d1e366d"
+
+cli-width@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a"
+
+clone-regexp@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-1.0.0.tgz#eae0a2413f55c0942f818c229fefce845d7f3b1c"
+ dependencies:
+ is-regexp "^1.0.0"
+ is-supported-regexp-flag "^1.0.0"
+
+clone-stats@^0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1"
+
+clone@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149"
+
+co@^4.6.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
+
+code-point-at@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+
+colors@1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
+
+combined-stream@^1.0.5, combined-stream@~1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
+ dependencies:
+ delayed-stream "~1.0.0"
+
+commondir@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
+
+concat-map@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+
+concat-stream@^1.4.7:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7"
+ dependencies:
+ inherits "^2.0.3"
+ readable-stream "^2.2.2"
+ typedarray "^0.0.6"
+
+config-chain@~1.1.8:
+ version "1.1.11"
+ resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.11.tgz#aba09747dfbe4c3e70e766a6e41586e1859fc6f2"
+ dependencies:
+ ini "^1.3.4"
+ proto-list "~1.2.1"
+
+configstore@^1.0.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/configstore/-/configstore-1.4.0.tgz#c35781d0501d268c25c54b8b17f6240e8a4fb021"
+ dependencies:
+ graceful-fs "^4.1.2"
+ mkdirp "^0.5.0"
+ object-assign "^4.0.1"
+ os-tmpdir "^1.0.0"
+ osenv "^0.1.0"
+ uuid "^2.0.1"
+ write-file-atomic "^1.1.2"
+ xdg-basedir "^2.0.0"
+
+configstore@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/configstore/-/configstore-2.1.0.tgz#737a3a7036e9886102aa6099e47bb33ab1aba1a1"
+ dependencies:
+ dot-prop "^3.0.0"
+ graceful-fs "^4.1.2"
+ mkdirp "^0.5.0"
+ object-assign "^4.0.1"
+ os-tmpdir "^1.0.0"
+ osenv "^0.1.0"
+ uuid "^2.0.1"
+ write-file-atomic "^1.1.2"
+ xdg-basedir "^2.0.0"
+
+core-util-is@~1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+
+create-error-class@^3.0.1:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6"
+ dependencies:
+ capture-stack-trace "^1.0.0"
+
+cross-spawn@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982"
+ dependencies:
+ lru-cache "^4.0.1"
+ which "^1.2.9"
+
+cross-spawn@^4.0.0:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41"
+ dependencies:
+ lru-cache "^4.0.1"
+ which "^1.2.9"
+
+cryptiles@2.x.x:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
+ dependencies:
+ boom "2.x.x"
+
+css-select@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.0.0.tgz#b1121ca51848dd264e2244d058cee254deeb44b0"
+ dependencies:
+ boolbase "~1.0.0"
+ css-what "1.0"
+ domutils "1.4"
+ nth-check "~1.0.0"
+
+css-select@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
+ dependencies:
+ boolbase "~1.0.0"
+ css-what "2.1"
+ domutils "1.5.1"
+ nth-check "~1.0.1"
+
+css-what@1.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/css-what/-/css-what-1.0.0.tgz#d7cc2df45180666f99d2b14462639469e00f736c"
+
+css-what@2.1:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd"
+
+currently-unhandled@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
+ dependencies:
+ array-find-index "^1.0.1"
+
+dargs@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+dashdash@^1.12.0:
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
+ dependencies:
+ assert-plus "^1.0.0"
+
+dateformat@^1.0.11:
+ version "1.0.12"
+ resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9"
+ dependencies:
+ get-stdin "^4.0.1"
+ meow "^3.3.0"
+
+debug@^2.0.0, debug@^2.1.0, debug@^2.2.0:
+ version "2.6.6"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.6.tgz#a9fa6fbe9ca43cf1e79f73b75c0189cbb7d6db5a"
+ dependencies:
+ ms "0.7.3"
+
+decamelize@^1.0.0, decamelize@^1.1.2:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
+
+deep-extend@^0.4.0, deep-extend@~0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253"
+
+deep-is@~0.1.3:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
+
+default-uid@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/default-uid/-/default-uid-1.0.0.tgz#fcefa9df9f5ac40c8916d912dd1fe1146aa3c59e"
+
+delayed-stream@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+
+delegates@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
+
+detect-conflict@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/detect-conflict/-/detect-conflict-1.0.1.tgz#088657a66a961c05019db7c4230883b1c6b4176e"
+
+detect-newline@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-1.0.3.tgz#e97b1003877d70c09af1af35bfadff168de4920d"
+ dependencies:
+ get-stdin "^4.0.1"
+ minimist "^1.1.0"
+
+diff@^2.1.2:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-2.2.3.tgz#60eafd0d28ee906e4e8ff0a52c1229521033bf99"
+
+discontinuous-range@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
+
+dom-serializer@0, dom-serializer@~0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
+ dependencies:
+ domelementtype "~1.1.1"
+ entities "~1.1.1"
+
+domelementtype@1, domelementtype@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
+
+domelementtype@~1.1.1:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
+
+domhandler@2.3, domhandler@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738"
+ dependencies:
+ domelementtype "1"
+
+domutils@1.4:
+ version "1.4.3"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.4.3.tgz#0865513796c6b306031850e175516baf80b72a6f"
+ dependencies:
+ domelementtype "1"
+
+domutils@1.5, domutils@1.5.1, domutils@^1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
+ dependencies:
+ dom-serializer "0"
+ domelementtype "1"
+
+dot-prop@^2.0.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-2.4.0.tgz#848e28f7f1d50740c6747ab3cb07670462b6f89c"
+ dependencies:
+ is-obj "^1.0.0"
+
+dot-prop@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177"
+ dependencies:
+ is-obj "^1.0.0"
+
+downgrade-root@^1.0.0:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/downgrade-root/-/downgrade-root-1.2.2.tgz#531319715b0e81ffcc22eb28478ba27643e12c6c"
+ dependencies:
+ default-uid "^1.0.0"
+ is-root "^1.0.0"
+
+duplexer2@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
+ dependencies:
+ readable-stream "^2.0.2"
+
+each-async@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/each-async/-/each-async-1.1.1.tgz#dee5229bdf0ab6ba2012a395e1b869abf8813473"
+ dependencies:
+ onetime "^1.0.0"
+ set-immediate-shim "^1.0.0"
+
+ecc-jsbn@~0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
+ dependencies:
+ jsbn "~0.1.0"
+
+editions@^1.1.1:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.3.tgz#0907101bdda20fac3cbe334c27cbd0688dc99a5b"
+
+ejs@2.5.6, ejs@^2.3.1:
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.6.tgz#479636bfa3fe3b1debd52087f0acb204b4f19c88"
+
+entities@1.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26"
+
+entities@^1.1.1, entities@~1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
+
+error-ex@^1.2.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
+ dependencies:
+ is-arrayish "^0.2.1"
+
+error@^7.0.2:
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02"
+ dependencies:
+ string-template "~0.2.1"
+ xtend "~4.0.0"
+
+escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+
+escodegen-wallaby@^1.6.7:
+ version "1.6.11"
+ resolved "https://registry.yarnpkg.com/escodegen-wallaby/-/escodegen-wallaby-1.6.11.tgz#39100cde743f9acdd24bd868db5a12fbacde6ed1"
+ dependencies:
+ esprima "^2.7.1"
+ estraverse "^1.9.1"
+ esutils "^2.0.2"
+ optionator "^0.8.1"
+ optionalDependencies:
+ source-map "~0.2.0"
+
+esprima@^2.7.1:
+ version "2.7.3"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
+
+esprima@^3.1.1:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
+
+estraverse@^1.9.1:
+ version "1.9.3"
+ resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44"
+
+esutils@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
+
+execall@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/execall/-/execall-1.0.0.tgz#73d0904e395b3cab0658b08d09ec25307f29bb73"
+ dependencies:
+ clone-regexp "^1.0.0"
+
+exit-hook@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
+
+extend@^3.0.0, extend@~3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
+
+external-editor@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-1.1.1.tgz#12d7b0db850f7ff7e7081baf4005700060c4600b"
+ dependencies:
+ extend "^3.0.0"
+ spawn-sync "^1.0.15"
+ tmp "^0.0.29"
+
+extsprintf@1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550"
+
+fast-levenshtein@~2.0.4:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
+
+figures@^1.3.5:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
+ dependencies:
+ escape-string-regexp "^1.0.5"
+ object-assign "^4.1.0"
+
+filled-array@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/filled-array/-/filled-array-1.1.0.tgz#c3c4f6c663b923459a9aa29912d2d031f1507f84"
+
+find-up@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
+ dependencies:
+ path-exists "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+find-versions@^1.0.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-1.2.1.tgz#cbde9f12e38575a0af1be1b9a2c5d5fd8f186b62"
+ dependencies:
+ array-uniq "^1.0.0"
+ get-stdin "^4.0.1"
+ meow "^3.5.0"
+ semver-regex "^1.0.0"
+
+first-chunk-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70"
+ dependencies:
+ readable-stream "^2.0.2"
+
+foreachasync@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/foreachasync/-/foreachasync-3.0.0.tgz#5502987dc8714be3392097f32e0071c9dee07cf6"
+
+forever-agent@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+
+form-data@~2.1.1:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1"
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.5"
+ mime-types "^2.1.12"
+
+formatio@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.1.1.tgz#5ed3ccd636551097383465d996199100e86161e9"
+ dependencies:
+ samsam "~1.1"
+
+fs.realpath@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+
+fullname@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/fullname/-/fullname-2.1.0.tgz#c46bf0f7c3f24fd5b3358d00e4a41380eef87350"
+ dependencies:
+ npmconf "^2.1.1"
+ pify "^2.2.0"
+ pinkie-promise "^2.0.0"
+
+gauge@~1.2.5:
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93"
+ dependencies:
+ ansi "^0.3.0"
+ has-unicode "^2.0.0"
+ lodash.pad "^4.1.0"
+ lodash.padend "^4.1.0"
+ lodash.padstart "^4.1.0"
+
+generator-jhipster@4.0.8:
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/generator-jhipster/-/generator-jhipster-4.0.8.tgz#9daff076cc628500726026fad6cfb0a8b55eb1b0"
+ dependencies:
+ chalk "1.1.3"
+ cheerio "0.22.0"
+ ejs "2.5.6"
+ glob "7.1.1"
+ html-wiring "1.2.0"
+ insight "0.8.4"
+ jhipster-core "1.2.8"
+ js-yaml "3.8.1"
+ lodash "4.17.4"
+ mkdirp "0.5.1"
+ pluralize "3.1.0"
+ randexp "0.4.4"
+ semver "5.3.0"
+ shelljs "0.7.6"
+ yeoman-generator "0.24.1"
+ yo "1.8.5"
+
+get-stdin@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
+
+getpass@^0.1.1:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
+ dependencies:
+ assert-plus "^1.0.0"
+
+gh-got@^2.2.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-2.4.0.tgz#aa51418911ca5e4f92437114cd1209383a4aa019"
+ dependencies:
+ got "^5.2.0"
+ object-assign "^4.0.1"
+ pinkie-promise "^2.0.0"
+
+github-username@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/github-username/-/github-username-2.1.0.tgz#200e5a104af42ba08a54096c708d4b6ec2fa256b"
+ dependencies:
+ gh-got "^2.2.0"
+ meow "^3.5.0"
+
+glob@7.1.1, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.0.2"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+glob@^6.0.1:
+ version "6.0.4"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
+ dependencies:
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "2 || 3"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+globby@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-4.1.0.tgz#080f54549ec1b82a6c60e631fc82e1211dbe95f8"
+ dependencies:
+ array-union "^1.0.1"
+ arrify "^1.0.0"
+ glob "^6.0.1"
+ object-assign "^4.0.1"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+got@^5.0.0, got@^5.2.0:
+ version "5.7.1"
+ resolved "https://registry.yarnpkg.com/got/-/got-5.7.1.tgz#5f81635a61e4a6589f180569ea4e381680a51f35"
+ dependencies:
+ create-error-class "^3.0.1"
+ duplexer2 "^0.1.4"
+ is-redirect "^1.0.0"
+ is-retry-allowed "^1.0.0"
+ is-stream "^1.0.0"
+ lowercase-keys "^1.0.0"
+ node-status-codes "^1.0.0"
+ object-assign "^4.0.1"
+ parse-json "^2.1.0"
+ pinkie-promise "^2.0.0"
+ read-all-stream "^3.0.0"
+ readable-stream "^2.0.5"
+ timed-out "^3.0.0"
+ unzip-response "^1.0.2"
+ url-parse-lax "^1.0.0"
+
+graceful-fs@^4.1.11, graceful-fs@^4.1.2:
+ version "4.1.11"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
+
+grouped-queue@^0.3.0:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/grouped-queue/-/grouped-queue-0.3.3.tgz#c167d2a5319c5a0e0964ef6a25b7c2df8996c85c"
+ dependencies:
+ lodash "^4.17.2"
+
+gruntfile-editor@^1.0.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/gruntfile-editor/-/gruntfile-editor-1.2.1.tgz#366fc1f93cbf045813e1448aef1da9f18289d5eb"
+ dependencies:
+ ast-query "^2.0.0"
+ lodash "^4.6.1"
+
+har-schema@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
+
+har-validator@~4.2.1:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
+ dependencies:
+ ajv "^4.9.1"
+ har-schema "^1.0.5"
+
+has-ansi@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+has-flag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
+
+has-unicode@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
+
+hawk@~3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
+ dependencies:
+ boom "2.x.x"
+ cryptiles "2.x.x"
+ hoek "2.x.x"
+ sntp "1.x.x"
+
+hoek@2.x.x:
+ version "2.16.3"
+ resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
+
+hosted-git-info@^2.1.4:
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67"
+
+html-wiring@1.2.0, html-wiring@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/html-wiring/-/html-wiring-1.2.0.tgz#c5f90a776e0a27241dc6df9022c37186d0270f9e"
+ dependencies:
+ cheerio "^0.19.0"
+ detect-newline "^1.0.3"
+
+htmlparser2@^3.9.1:
+ version "3.9.2"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338"
+ dependencies:
+ domelementtype "^1.3.0"
+ domhandler "^2.3.0"
+ domutils "^1.5.1"
+ entities "^1.1.1"
+ inherits "^2.0.1"
+ readable-stream "^2.0.2"
+
+htmlparser2@~3.8.1:
+ version "3.8.3"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068"
+ dependencies:
+ domelementtype "1"
+ domhandler "2.3"
+ domutils "1.5"
+ entities "1.0"
+ readable-stream "1.1"
+
+http-signature@~1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
+ dependencies:
+ assert-plus "^0.2.0"
+ jsprim "^1.2.2"
+ sshpk "^1.7.0"
+
+humanize-string@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/humanize-string/-/humanize-string-1.0.1.tgz#fce2d6c545efc25dea1f23235182c98da0180b42"
+ dependencies:
+ decamelize "^1.0.0"
+
+imurmurhash@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
+
+indent-string@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80"
+ dependencies:
+ repeating "^2.0.0"
+
+inflight@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+ dependencies:
+ once "^1.3.0"
+ wrappy "1"
+
+inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+
+inherits@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
+
+ini@^1.2.0, ini@^1.3.4, ini@~1.3.0:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
+
+inquirer@^0.10.0:
+ version "0.10.1"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.10.1.tgz#ea25e4ce69ca145e05c99e46dcfec05e4012594a"
+ dependencies:
+ ansi-escapes "^1.1.0"
+ ansi-regex "^2.0.0"
+ chalk "^1.0.0"
+ cli-cursor "^1.0.1"
+ cli-width "^1.0.1"
+ figures "^1.3.5"
+ lodash "^3.3.1"
+ readline2 "^1.0.1"
+ run-async "^0.1.0"
+ rx-lite "^3.1.2"
+ strip-ansi "^3.0.0"
+ through "^2.3.6"
+
+inquirer@^0.11.0:
+ version "0.11.4"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.11.4.tgz#81e3374e8361beaff2d97016206d359d0b32fa4d"
+ dependencies:
+ ansi-escapes "^1.1.0"
+ ansi-regex "^2.0.0"
+ chalk "^1.0.0"
+ cli-cursor "^1.0.1"
+ cli-width "^1.0.1"
+ figures "^1.3.5"
+ lodash "^3.3.1"
+ readline2 "^1.0.1"
+ run-async "^0.1.0"
+ rx-lite "^3.1.2"
+ string-width "^1.0.1"
+ strip-ansi "^3.0.0"
+ through "^2.3.6"
+
+inquirer@^1.0.2:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-1.2.3.tgz#4dec6f32f37ef7bb0b2ed3f1d1a5c3f545074918"
+ dependencies:
+ ansi-escapes "^1.1.0"
+ chalk "^1.0.0"
+ cli-cursor "^1.0.1"
+ cli-width "^2.0.0"
+ external-editor "^1.1.0"
+ figures "^1.3.5"
+ lodash "^4.3.0"
+ mute-stream "0.0.6"
+ pinkie-promise "^2.0.0"
+ run-async "^2.2.0"
+ rx "^4.1.0"
+ string-width "^1.0.1"
+ strip-ansi "^3.0.0"
+ through "^2.3.6"
+
+insight@0.8.4:
+ version "0.8.4"
+ resolved "https://registry.yarnpkg.com/insight/-/insight-0.8.4.tgz#671caf65b47c9fe8c3d1b3206cf45bb211b75884"
+ dependencies:
+ async "^1.4.2"
+ chalk "^1.0.0"
+ configstore "^1.0.0"
+ inquirer "^0.10.0"
+ lodash.debounce "^3.0.1"
+ object-assign "^4.0.1"
+ os-name "^1.0.0"
+ request "^2.74.0"
+ tough-cookie "^2.0.0"
+ uuid "^3.0.0"
+
+insight@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/insight/-/insight-0.7.0.tgz#061f9189835bd38a97a60c2b76ea0c6b30099ff6"
+ dependencies:
+ async "^1.4.2"
+ chalk "^1.0.0"
+ configstore "^1.0.0"
+ inquirer "^0.10.0"
+ lodash.debounce "^3.0.1"
+ object-assign "^4.0.1"
+ os-name "^1.0.0"
+ request "^2.40.0"
+ tough-cookie "^2.0.0"
+
+interpret@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90"
+
+is-arrayish@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
+
+is-builtin-module@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"
+ dependencies:
+ builtin-modules "^1.0.0"
+
+is-docker@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-1.1.0.tgz#f04374d4eee5310e9a8e113bf1495411e46176a1"
+
+is-finite@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+is-fullwidth-code-point@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+is-npm@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
+
+is-obj@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
+
+is-promise@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
+
+is-redirect@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24"
+
+is-regexp@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
+
+is-retry-allowed@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
+
+is-root@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-root/-/is-root-1.0.0.tgz#07b6c233bc394cd9d02ba15c966bd6660d6342d5"
+
+is-stream@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+
+is-supported-regexp-flag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.0.tgz#8b520c85fae7a253382d4b02652e045576e13bb8"
+
+is-typedarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
+
+is-utf8@^0.2.0:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
+
+isarray@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
+
+isarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+
+isexe@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+
+isstream@~0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
+
+istextorbinary@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.1.0.tgz#dbed2a6f51be2f7475b68f89465811141b758874"
+ dependencies:
+ binaryextensions "1 || 2"
+ editions "^1.1.1"
+ textextensions "1 || 2"
+
+jhipster-core@1.2.8:
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/jhipster-core/-/jhipster-core-1.2.8.tgz#2211a468761a7132c5ddc7f101400e2fc57d5be4"
+ dependencies:
+ lodash "4.17.4"
+
+jodid25519@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967"
+ dependencies:
+ jsbn "~0.1.0"
+
+js-yaml@3.8.1:
+ version "3.8.1"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.1.tgz#782ba50200be7b9e5a8537001b7804db3ad02628"
+ dependencies:
+ argparse "^1.0.7"
+ esprima "^3.1.1"
+
+jsbn@~0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+
+json-schema@0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
+
+json-stable-stringify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
+ dependencies:
+ jsonify "~0.0.0"
+
+json-stringify-safe@~5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+
+jsonify@~0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
+
+jsprim@^1.2.2:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918"
+ dependencies:
+ assert-plus "1.0.0"
+ extsprintf "1.0.2"
+ json-schema "0.2.3"
+ verror "1.3.6"
+
+latest-version@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-2.0.0.tgz#56f8d6139620847b8017f8f1f4d78e211324168b"
+ dependencies:
+ package-json "^2.0.0"
+
+levn@~0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
+ dependencies:
+ prelude-ls "~1.1.2"
+ type-check "~0.3.2"
+
+load-json-file@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
+ dependencies:
+ graceful-fs "^4.1.2"
+ parse-json "^2.2.0"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+ strip-bom "^2.0.0"
+
+lodash._getnative@^3.0.0:
+ version "3.9.1"
+ resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
+
+lodash.assignin@^4.0.9:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2"
+
+lodash.bind@^4.1.4:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35"
+
+lodash.debounce@^3.0.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-3.1.1.tgz#812211c378a94cc29d5aa4e3346cf0bfce3a7df5"
+ dependencies:
+ lodash._getnative "^3.0.0"
+
+lodash.defaults@^4.0.1:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
+
+lodash.filter@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace"
+
+lodash.flatten@^4.2.0:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
+
+lodash.foreach@^4.3.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
+
+lodash.map@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
+
+lodash.merge@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5"
+
+lodash.pad@^4.1.0:
+ version "4.5.1"
+ resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70"
+
+lodash.padend@^4.1.0:
+ version "4.6.1"
+ resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e"
+
+lodash.padstart@^4.1.0:
+ version "4.6.1"
+ resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b"
+
+lodash.pick@^4.2.1:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
+
+lodash.reduce@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b"
+
+lodash.reject@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415"
+
+lodash.some@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
+
+lodash@4.17.4, lodash@^4.11.1, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.3.0, lodash@^4.6.1:
+ version "4.17.4"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
+
+lodash@^3.2.0, lodash@^3.3.1:
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
+
+log-symbols@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
+ dependencies:
+ chalk "^1.0.0"
+
+lolex@1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31"
+
+loud-rejection@^1.0.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f"
+ dependencies:
+ currently-unhandled "^0.4.1"
+ signal-exit "^3.0.0"
+
+lowercase-keys@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306"
+
+lru-cache@^4.0.1:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e"
+ dependencies:
+ pseudomap "^1.0.1"
+ yallist "^2.0.0"
+
+map-obj@^1.0.0, map-obj@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
+
+mem-fs-editor@^2.0.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-2.3.0.tgz#42a0ae1f55e76fd03f09e7c7b15b6307bdf5cb13"
+ dependencies:
+ commondir "^1.0.1"
+ deep-extend "^0.4.0"
+ ejs "^2.3.1"
+ glob "^7.0.3"
+ globby "^4.0.0"
+ mkdirp "^0.5.0"
+ multimatch "^2.0.0"
+ rimraf "^2.2.8"
+ through2 "^2.0.0"
+ vinyl "^1.1.0"
+
+mem-fs@^1.1.0:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/mem-fs/-/mem-fs-1.1.3.tgz#b8ae8d2e3fcb6f5d3f9165c12d4551a065d989cc"
+ dependencies:
+ through2 "^2.0.0"
+ vinyl "^1.1.0"
+ vinyl-file "^2.0.0"
+
+meow@^3.0.0, meow@^3.3.0, meow@^3.5.0:
+ version "3.7.0"
+ resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb"
+ dependencies:
+ camelcase-keys "^2.0.0"
+ decamelize "^1.1.2"
+ loud-rejection "^1.0.0"
+ map-obj "^1.0.1"
+ minimist "^1.1.3"
+ normalize-package-data "^2.3.4"
+ object-assign "^4.0.1"
+ read-pkg-up "^1.0.1"
+ redent "^1.0.0"
+ trim-newlines "^1.0.0"
+
+mime-db@~1.27.0:
+ version "1.27.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1"
+
+mime-types@^2.1.12, mime-types@~2.1.7:
+ version "2.1.15"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed"
+ dependencies:
+ mime-db "~1.27.0"
+
+"minimatch@2 || 3", minimatch@3.0.x, minimatch@^3.0.0, minimatch@^3.0.2:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774"
+ dependencies:
+ brace-expansion "^1.0.0"
+
+minimist@0.0.8:
+ version "0.0.8"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
+
+minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
+
+mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
+ dependencies:
+ minimist "0.0.8"
+
+ms@0.7.3:
+ version "0.7.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff"
+
+multimatch@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b"
+ dependencies:
+ array-differ "^1.0.0"
+ array-union "^1.0.1"
+ arrify "^1.0.0"
+ minimatch "^3.0.0"
+
+mute-stream@0.0.5:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0"
+
+mute-stream@0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.6.tgz#48962b19e169fd1dfc240b3f1e7317627bbc47db"
+
+node-status-codes@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f"
+
+nopt@^3.0.0, nopt@~3.0.1:
+ version "3.0.6"
+ resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
+ dependencies:
+ abbrev "1"
+
+normalize-package-data@^2.3.2, normalize-package-data@^2.3.4:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb"
+ dependencies:
+ hosted-git-info "^2.1.4"
+ is-builtin-module "^1.0.0"
+ semver "2 || 3 || 4 || 5"
+ validate-npm-package-license "^3.0.1"
+
+npm-keyword@^4.1.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/npm-keyword/-/npm-keyword-4.2.0.tgz#98ffebfdbb1336f27ef5fe1baca0dcacd0acf6c0"
+ dependencies:
+ got "^5.0.0"
+ object-assign "^4.0.1"
+ pinkie-promise "^2.0.0"
+ registry-url "^3.0.3"
+
+npmconf@^2.1.1:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/npmconf/-/npmconf-2.1.2.tgz#66606a4a736f1e77a059aa071a79c94ab781853a"
+ dependencies:
+ config-chain "~1.1.8"
+ inherits "~2.0.0"
+ ini "^1.2.0"
+ mkdirp "^0.5.0"
+ nopt "~3.0.1"
+ once "~1.3.0"
+ osenv "^0.1.0"
+ semver "2 || 3 || 4"
+ uid-number "0.0.5"
+
+npmlog@^2.0.3:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692"
+ dependencies:
+ ansi "~0.3.1"
+ are-we-there-yet "~1.1.2"
+ gauge "~1.2.5"
+
+nth-check@~1.0.0, nth-check@~1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4"
+ dependencies:
+ boolbase "~1.0.0"
+
+number-is-nan@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
+
+oauth-sign@~0.8.1:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
+
+object-assign@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa"
+
+object-assign@^4.0.1, object-assign@^4.1.0:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+
+object-values@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/object-values/-/object-values-1.0.0.tgz#72af839630119e5b98c3b02bb8c27e3237158105"
+
+once@^1.3.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+ dependencies:
+ wrappy "1"
+
+once@~1.3.0:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20"
+ dependencies:
+ wrappy "1"
+
+onetime@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
+
+opn@^3.0.2:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/opn/-/opn-3.0.3.tgz#b6d99e7399f78d65c3baaffef1fb288e9b85243a"
+ dependencies:
+ object-assign "^4.0.1"
+
+optionator@^0.8.1:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
+ dependencies:
+ deep-is "~0.1.3"
+ fast-levenshtein "~2.0.4"
+ levn "~0.3.0"
+ prelude-ls "~1.1.2"
+ type-check "~0.3.2"
+ wordwrap "~1.0.0"
+
+os-homedir@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
+
+os-name@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/os-name/-/os-name-1.0.3.tgz#1b379f64835af7c5a7f498b357cb95215c159edf"
+ dependencies:
+ osx-release "^1.0.0"
+ win-release "^1.0.0"
+
+os-shim@^0.1.2:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917"
+
+os-tmpdir@^1.0.0, os-tmpdir@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
+
+osenv@^0.1.0:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644"
+ dependencies:
+ os-homedir "^1.0.0"
+ os-tmpdir "^1.0.0"
+
+osx-release@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/osx-release/-/osx-release-1.1.0.tgz#f217911a28136949af1bf9308b241e2737d3cd6c"
+ dependencies:
+ minimist "^1.1.0"
+
+package-json@^2.0.0, package-json@^2.1.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/package-json/-/package-json-2.4.0.tgz#0d15bd67d1cbbddbb2ca222ff2edb86bcb31a8bb"
+ dependencies:
+ got "^5.0.0"
+ registry-auth-token "^3.0.1"
+ registry-url "^3.0.3"
+ semver "^5.1.0"
+
+pad-component@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/pad-component/-/pad-component-0.0.1.tgz#ad1f22ce1bf0fdc0d6ddd908af17f351a404b8ac"
+
+parse-help@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/parse-help/-/parse-help-0.1.1.tgz#2f4df942e77a5581bba9967c0c3f48e4c66d7dda"
+ dependencies:
+ execall "^1.0.0"
+
+parse-json@^2.1.0, parse-json@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
+ dependencies:
+ error-ex "^1.2.0"
+
+path-exists@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
+ dependencies:
+ pinkie-promise "^2.0.0"
+
+path-is-absolute@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+
+path-parse@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
+
+path-type@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
+ dependencies:
+ graceful-fs "^4.1.2"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+performance-now@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
+
+pify@^2.0.0, pify@^2.2.0, pify@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
+
+pinkie-promise@^2.0.0, pinkie-promise@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
+ dependencies:
+ pinkie "^2.0.0"
+
+pinkie@^2.0.0:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
+
+pluralize@3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-3.1.0.tgz#84213d0a12356069daa84060c559242633161368"
+
+prelude-ls@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
+
+prepend-http@^1.0.1:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
+
+pretty-bytes@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-3.0.1.tgz#27d0008d778063a0b4811bb35c79f1bd5d5fbccf"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+process-nextick-args@~1.0.6:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
+
+proto-list@~1.2.1:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
+
+pseudomap@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
+
+punycode@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
+
+qs@~6.4.0:
+ version "6.4.0"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
+
+randexp@0.4.4:
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.4.tgz#ba68265f4a9f9e85f5814d34e160291f939f168e"
+ dependencies:
+ discontinuous-range "1.0.0"
+ ret "~0.1.10"
+
+rc@^1.0.1, rc@^1.1.6:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95"
+ dependencies:
+ deep-extend "~0.4.0"
+ ini "~1.3.0"
+ minimist "^1.2.0"
+ strip-json-comments "~2.0.1"
+
+read-all-stream@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa"
+ dependencies:
+ pinkie-promise "^2.0.0"
+ readable-stream "^2.0.0"
+
+read-chunk@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-1.0.1.tgz#5f68cab307e663f19993527d9b589cace4661194"
+
+read-pkg-up@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
+ dependencies:
+ find-up "^1.0.0"
+ read-pkg "^1.0.0"
+
+read-pkg@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
+ dependencies:
+ load-json-file "^1.0.0"
+ normalize-package-data "^2.3.2"
+ path-type "^1.0.0"
+
+readable-stream@1.1:
+ version "1.1.13"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e"
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "0.0.1"
+ string_decoder "~0.10.x"
+
+readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2:
+ version "2.2.9"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.9.tgz#cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8"
+ dependencies:
+ buffer-shims "~1.0.0"
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "~1.0.0"
+ process-nextick-args "~1.0.6"
+ string_decoder "~1.0.0"
+ util-deprecate "~1.0.1"
+
+readline2@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35"
+ dependencies:
+ code-point-at "^1.0.0"
+ is-fullwidth-code-point "^1.0.0"
+ mute-stream "0.0.5"
+
+rechoir@^0.6.2:
+ version "0.6.2"
+ resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
+ dependencies:
+ resolve "^1.1.6"
+
+redent@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde"
+ dependencies:
+ indent-string "^2.1.0"
+ strip-indent "^1.0.1"
+
+registry-auth-token@^3.0.1:
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006"
+ dependencies:
+ rc "^1.1.6"
+ safe-buffer "^5.0.1"
+
+registry-url@^3.0.3:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942"
+ dependencies:
+ rc "^1.0.1"
+
+repeating@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
+ dependencies:
+ is-finite "^1.0.0"
+
+replace-ext@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924"
+
+request@^2.40.0, request@^2.74.0:
+ version "2.81.0"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
+ dependencies:
+ aws-sign2 "~0.6.0"
+ aws4 "^1.2.1"
+ caseless "~0.12.0"
+ combined-stream "~1.0.5"
+ extend "~3.0.0"
+ forever-agent "~0.6.1"
+ form-data "~2.1.1"
+ har-validator "~4.2.1"
+ hawk "~3.1.3"
+ http-signature "~1.1.0"
+ is-typedarray "~1.0.0"
+ isstream "~0.1.2"
+ json-stringify-safe "~5.0.1"
+ mime-types "~2.1.7"
+ oauth-sign "~0.8.1"
+ performance-now "^0.2.0"
+ qs "~6.4.0"
+ safe-buffer "^5.0.1"
+ stringstream "~0.0.4"
+ tough-cookie "~2.3.0"
+ tunnel-agent "^0.6.0"
+ uuid "^3.0.0"
+
+resolve@^1.1.6:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
+ dependencies:
+ path-parse "^1.0.5"
+
+restore-cursor@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
+ dependencies:
+ exit-hook "^1.0.0"
+ onetime "^1.0.0"
+
+ret@~0.1.10:
+ version "0.1.14"
+ resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.14.tgz#58c636837b12e161f8a380cf081c6a230fd1664e"
+
+rimraf@^2.2.0, rimraf@^2.2.8, rimraf@^2.4.4:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
+ dependencies:
+ glob "^7.0.5"
+
+root-check@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/root-check/-/root-check-1.0.0.tgz#c52a794bf0db9fad567536e41898f0c9e0a86697"
+ dependencies:
+ downgrade-root "^1.0.0"
+ sudo-block "^1.1.0"
+
+run-async@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389"
+ dependencies:
+ once "^1.3.0"
+
+run-async@^2.0.0, run-async@^2.2.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
+ dependencies:
+ is-promise "^2.1.0"
+
+rx-lite@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
+
+rx@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
+
+safe-buffer@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7"
+
+samsam@1.1.2, samsam@~1.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567"
+
+semver-diff@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
+ dependencies:
+ semver "^5.0.3"
+
+semver-regex@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-1.0.0.tgz#92a4969065f9c70c694753d55248fc68f8f652c9"
+
+semver-truncate@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/semver-truncate/-/semver-truncate-1.1.2.tgz#57f41de69707a62709a7e0104ba2117109ea47e8"
+ dependencies:
+ semver "^5.3.0"
+
+"semver@2 || 3 || 4", semver@^4.0.3:
+ version "4.3.6"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da"
+
+"semver@2 || 3 || 4 || 5", semver@5.3.0, semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
+
+set-immediate-shim@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
+
+shelljs@0.7.6, shelljs@^0.7.0:
+ version "0.7.6"
+ resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.6.tgz#379cccfb56b91c8601e4793356eb5382924de9ad"
+ dependencies:
+ glob "^7.0.0"
+ interpret "^1.0.0"
+ rechoir "^0.6.2"
+
+signal-exit@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
+
+sinon@^1.17.2:
+ version "1.17.7"
+ resolved "https://registry.yarnpkg.com/sinon/-/sinon-1.17.7.tgz#4542a4f49ba0c45c05eb2e9dd9d203e2b8efe0bf"
+ dependencies:
+ formatio "1.1.1"
+ lolex "1.3.2"
+ samsam "1.1.2"
+ util ">=0.10.3 <1"
+
+slide@^1.1.5:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707"
+
+sntp@1.x.x:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
+ dependencies:
+ hoek "2.x.x"
+
+sort-on@^1.0.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/sort-on/-/sort-on-1.3.0.tgz#0dfd5b364b23df7f2acd86985daeb889e1a7c840"
+ dependencies:
+ arrify "^1.0.0"
+ dot-prop "^2.0.0"
+
+source-map@~0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d"
+ dependencies:
+ amdefine ">=0.0.4"
+
+spawn-sync@^1.0.15:
+ version "1.0.15"
+ resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476"
+ dependencies:
+ concat-stream "^1.4.7"
+ os-shim "^0.1.2"
+
+spdx-correct@~1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
+ dependencies:
+ spdx-license-ids "^1.0.2"
+
+spdx-expression-parse@~1.0.0:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c"
+
+spdx-license-ids@^1.0.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
+
+sprintf-js@^1.0.3, sprintf-js@~1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
+
+sshpk@^1.7.0:
+ version "1.13.0"
+ resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c"
+ dependencies:
+ asn1 "~0.2.3"
+ assert-plus "^1.0.0"
+ dashdash "^1.12.0"
+ getpass "^0.1.1"
+ optionalDependencies:
+ bcrypt-pbkdf "^1.0.0"
+ ecc-jsbn "~0.1.1"
+ jodid25519 "^1.0.0"
+ jsbn "~0.1.0"
+ tweetnacl "~0.14.0"
+
+string-length@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/string-length/-/string-length-1.0.1.tgz#56970fb1c38558e9e70b728bf3de269ac45adfac"
+ dependencies:
+ strip-ansi "^3.0.0"
+
+string-template@~0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add"
+
+string-width@^1.0.0, string-width@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
+ dependencies:
+ code-point-at "^1.0.0"
+ is-fullwidth-code-point "^1.0.0"
+ strip-ansi "^3.0.0"
+
+string_decoder@~0.10.x:
+ version "0.10.31"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
+
+string_decoder@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.0.tgz#f06f41157b664d86069f84bdbdc9b0d8ab281667"
+ dependencies:
+ buffer-shims "~1.0.0"
+
+stringstream@~0.0.4:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
+
+strip-ansi@^3.0.0, strip-ansi@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+strip-bom-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca"
+ dependencies:
+ first-chunk-stream "^2.0.0"
+ strip-bom "^2.0.0"
+
+strip-bom@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
+ dependencies:
+ is-utf8 "^0.2.0"
+
+strip-indent@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2"
+ dependencies:
+ get-stdin "^4.0.1"
+
+strip-json-comments@~2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
+
+sudo-block@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/sudo-block/-/sudo-block-1.2.0.tgz#cc539bf8191624d4f507d83eeb45b4cea27f3463"
+ dependencies:
+ chalk "^1.0.0"
+ is-docker "^1.0.0"
+ is-root "^1.0.0"
+
+supports-color@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
+
+supports-color@^3.1.2:
+ version "3.2.3"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
+ dependencies:
+ has-flag "^1.0.0"
+
+tabtab@^1.3.0:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/tabtab/-/tabtab-1.3.2.tgz#bb9c2ca6324f659fde7634c2caf3c096e1187ca7"
+ dependencies:
+ debug "^2.2.0"
+ inquirer "^1.0.2"
+ minimist "^1.2.0"
+ mkdirp "^0.5.1"
+ npmlog "^2.0.3"
+ object-assign "^4.1.0"
+
+taketalk@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/taketalk/-/taketalk-1.0.0.tgz#b4d4f0deed206ae7df775b129ea2ca6de52f26dd"
+ dependencies:
+ get-stdin "^4.0.1"
+ minimist "^1.1.0"
+
+text-table@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
+
+"textextensions@1 || 2":
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.1.0.tgz#1be0dc2a0dc244d44be8a09af6a85afb93c4dbc3"
+
+through2@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
+ dependencies:
+ readable-stream "^2.1.5"
+ xtend "~4.0.1"
+
+through@^2.3.6:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+
+timed-out@^3.0.0:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.3.tgz#95860bfcc5c76c277f8f8326fd0f5b2e20eba217"
+
+titleize@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/titleize/-/titleize-1.0.0.tgz#7d350722061830ba6617631e0cfd3ea08398d95a"
+
+tmp@^0.0.29:
+ version "0.0.29"
+ resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.29.tgz#f25125ff0dd9da3ccb0c2dd371ee1288bb9128c0"
+ dependencies:
+ os-tmpdir "~1.0.1"
+
+tough-cookie@^2.0.0, tough-cookie@~2.3.0:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a"
+ dependencies:
+ punycode "^1.4.1"
+
+traverse@^0.6.6:
+ version "0.6.6"
+ resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137"
+
+trim-newlines@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
+
+tunnel-agent@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
+ dependencies:
+ safe-buffer "^5.0.1"
+
+tweetnacl@^0.14.3, tweetnacl@~0.14.0:
+ version "0.14.5"
+ resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+
+twig@^0.8.2:
+ version "0.8.9"
+ resolved "https://registry.yarnpkg.com/twig/-/twig-0.8.9.tgz#b1594f002b684e5f029de3e54e87bec4f084b6c2"
+ dependencies:
+ minimatch "3.0.x"
+ walk "2.3.x"
+
+type-check@~0.3.2:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
+ dependencies:
+ prelude-ls "~1.1.2"
+
+typedarray@^0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
+
+uid-number@0.0.5:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.5.tgz#5a3db23ef5dbd55b81fce0ec9a2ac6fccdebb81e"
+
+underscore.string@^3.0.3:
+ version "3.3.4"
+ resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.3.4.tgz#2c2a3f9f83e64762fdc45e6ceac65142864213db"
+ dependencies:
+ sprintf-js "^1.0.3"
+ util-deprecate "^1.0.2"
+
+untildify@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0"
+ dependencies:
+ os-homedir "^1.0.0"
+
+unzip-response@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe"
+
+update-notifier@^0.6.0:
+ version "0.6.3"
+ resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-0.6.3.tgz#776dec8daa13e962a341e8a1d98354306b67ae08"
+ dependencies:
+ boxen "^0.3.1"
+ chalk "^1.0.0"
+ configstore "^2.0.0"
+ is-npm "^1.0.0"
+ latest-version "^2.0.0"
+ semver-diff "^2.0.0"
+
+url-parse-lax@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
+ dependencies:
+ prepend-http "^1.0.1"
+
+user-home@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f"
+ dependencies:
+ os-homedir "^1.0.0"
+
+util-deprecate@^1.0.2, util-deprecate@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+
+"util@>=0.10.3 <1":
+ version "0.10.3"
+ resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
+ dependencies:
+ inherits "2.0.1"
+
+uuid@^2.0.1:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a"
+
+uuid@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1"
+
+validate-npm-package-license@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"
+ dependencies:
+ spdx-correct "~1.0.0"
+ spdx-expression-parse "~1.0.0"
+
+verror@1.3.6:
+ version "1.3.6"
+ resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c"
+ dependencies:
+ extsprintf "1.0.2"
+
+vinyl-file@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/vinyl-file/-/vinyl-file-2.0.0.tgz#a7ebf5ffbefda1b7d18d140fcb07b223efb6751a"
+ dependencies:
+ graceful-fs "^4.1.2"
+ pify "^2.3.0"
+ pinkie-promise "^2.0.0"
+ strip-bom "^2.0.0"
+ strip-bom-stream "^2.0.0"
+ vinyl "^1.1.0"
+
+vinyl@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884"
+ dependencies:
+ clone "^1.0.0"
+ clone-stats "^0.0.1"
+ replace-ext "0.0.1"
+
+walk@2.3.x:
+ version "2.3.9"
+ resolved "https://registry.yarnpkg.com/walk/-/walk-2.3.9.tgz#31b4db6678f2ae01c39ea9fb8725a9031e558a7b"
+ dependencies:
+ foreachasync "^3.0.0"
+
+which@^1.2.9:
+ version "1.2.14"
+ resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
+ dependencies:
+ isexe "^2.0.0"
+
+widest-line@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c"
+ dependencies:
+ string-width "^1.0.1"
+
+win-release@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/win-release/-/win-release-1.1.1.tgz#5fa55e02be7ca934edfc12665632e849b72e5209"
+ dependencies:
+ semver "^5.0.1"
+
+wordwrap@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
+
+wrap-ansi@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
+ dependencies:
+ string-width "^1.0.1"
+ strip-ansi "^3.0.1"
+
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+
+write-file-atomic@^1.1.2:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f"
+ dependencies:
+ graceful-fs "^4.1.11"
+ imurmurhash "^0.1.4"
+ slide "^1.1.5"
+
+xdg-basedir@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2"
+ dependencies:
+ os-homedir "^1.0.0"
+
+xtend@~4.0.0, xtend@~4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
+
+yallist@^2.0.0:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
+
+yeoman-assert@^2.0.0:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/yeoman-assert/-/yeoman-assert-2.2.3.tgz#a5682a83632c50ac0ee84173a5a10fd6f3206474"
+
+yeoman-character@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/yeoman-character/-/yeoman-character-1.1.0.tgz#90d4b5beaf92759086177015b2fdfa2e0684d7c7"
+ dependencies:
+ supports-color "^3.1.2"
+
+yeoman-doctor@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/yeoman-doctor/-/yeoman-doctor-2.1.0.tgz#94ab784896a64f53a9fac452d5e9133e2750a236"
+ dependencies:
+ bin-version-check "^2.1.0"
+ chalk "^1.0.0"
+ each-async "^1.1.1"
+ log-symbols "^1.0.1"
+ object-values "^1.0.0"
+ semver "^5.0.3"
+ twig "^0.8.2"
+ user-home "^2.0.0"
+
+yeoman-environment@^1.1.0, yeoman-environment@^1.5.2, yeoman-environment@^1.6.1:
+ version "1.6.6"
+ resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-1.6.6.tgz#cd85fa67d156060e440d7807d7ef7cf0d2d1d671"
+ dependencies:
+ chalk "^1.0.0"
+ debug "^2.0.0"
+ diff "^2.1.2"
+ escape-string-regexp "^1.0.2"
+ globby "^4.0.0"
+ grouped-queue "^0.3.0"
+ inquirer "^1.0.2"
+ lodash "^4.11.1"
+ log-symbols "^1.0.1"
+ mem-fs "^1.1.0"
+ text-table "^0.2.0"
+ untildify "^2.0.0"
+
+yeoman-generator@0.24.1, yeoman-generator@^0.24.1:
+ version "0.24.1"
+ resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-0.24.1.tgz#1ca74429d9c5c95db0b22859ec180a2599bc1f8e"
+ dependencies:
+ async "^2.0.0"
+ chalk "^1.0.0"
+ class-extend "^0.1.0"
+ cli-table "^0.3.1"
+ cross-spawn "^4.0.0"
+ dargs "^4.0.0"
+ dateformat "^1.0.11"
+ debug "^2.1.0"
+ detect-conflict "^1.0.0"
+ error "^7.0.2"
+ find-up "^1.0.0"
+ github-username "^2.0.0"
+ glob "^7.0.3"
+ gruntfile-editor "^1.0.0"
+ html-wiring "^1.0.0"
+ istextorbinary "^2.1.0"
+ lodash "^4.11.1"
+ mem-fs-editor "^2.0.0"
+ mkdirp "^0.5.0"
+ nopt "^3.0.0"
+ path-exists "^2.0.0"
+ path-is-absolute "^1.0.0"
+ pretty-bytes "^3.0.1"
+ read-chunk "^1.0.0"
+ read-pkg-up "^1.0.1"
+ rimraf "^2.2.0"
+ run-async "^2.0.0"
+ shelljs "^0.7.0"
+ text-table "^0.2.0"
+ through2 "^2.0.0"
+ underscore.string "^3.0.3"
+ user-home "^2.0.0"
+ yeoman-assert "^2.0.0"
+ yeoman-environment "^1.1.0"
+ yeoman-test "^1.0.0"
+ yeoman-welcome "^1.0.0"
+
+yeoman-test@^1.0.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/yeoman-test/-/yeoman-test-1.6.0.tgz#abff291733e16e8923d9eefc8691c632888bf948"
+ dependencies:
+ inquirer "^1.0.2"
+ lodash "^4.3.0"
+ mkdirp "^0.5.1"
+ pinkie-promise "^2.0.1"
+ rimraf "^2.4.4"
+ sinon "^1.17.2"
+ yeoman-environment "^1.5.2"
+ yeoman-generator "^0.24.1"
+
+yeoman-welcome@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/yeoman-welcome/-/yeoman-welcome-1.0.1.tgz#f6cf198fd4fba8a771672c26cdfb8a64795c84ec"
+ dependencies:
+ chalk "^1.0.0"
+
+yo@1.8.5:
+ version "1.8.5"
+ resolved "https://registry.yarnpkg.com/yo/-/yo-1.8.5.tgz#776ab9ec79a7882f8d4f7a9e10214fdab050d928"
+ dependencies:
+ async "^1.0.0"
+ chalk "^1.0.0"
+ cli-list "^0.1.1"
+ configstore "^1.0.0"
+ cross-spawn "^3.0.1"
+ figures "^1.3.5"
+ fullname "^2.0.0"
+ got "^5.0.0"
+ humanize-string "^1.0.0"
+ inquirer "^0.11.0"
+ insight "^0.7.0"
+ lodash "^3.2.0"
+ meow "^3.0.0"
+ npm-keyword "^4.1.0"
+ opn "^3.0.2"
+ package-json "^2.1.0"
+ parse-help "^0.1.1"
+ read-pkg-up "^1.0.1"
+ repeating "^2.0.0"
+ root-check "^1.0.0"
+ sort-on "^1.0.0"
+ string-length "^1.0.0"
+ tabtab "^1.3.0"
+ titleize "^1.0.0"
+ update-notifier "^0.6.0"
+ user-home "^2.0.0"
+ yeoman-character "^1.0.0"
+ yeoman-doctor "^2.0.0"
+ yeoman-environment "^1.6.1"
+ yosay "^1.0.0"
+
+yosay@^1.0.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/yosay/-/yosay-1.2.1.tgz#9466ef969830e85b474e267b50f7688693ed3b5b"
+ dependencies:
+ ansi-regex "^2.0.0"
+ ansi-styles "^2.0.0"
+ chalk "^1.0.0"
+ cli-boxes "^1.0.0"
+ pad-component "0.0.1"
+ repeating "^2.0.0"
+ string-width "^1.0.0"
+ strip-ansi "^3.0.0"
+ taketalk "^1.0.0"
+ wrap-ansi "^2.0.0"
diff --git a/jhipster/jhipster-microservice/dealer-app/.editorconfig b/jhipster/jhipster-microservice/dealer-app/.editorconfig
new file mode 100644
index 0000000000..a03599dd04
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/.editorconfig
@@ -0,0 +1,24 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+[*]
+
+# Change these settings to your own preference
+indent_style = space
+indent_size = 4
+
+# We recommend you to keep these unchanged
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[{package,bower}.json]
+indent_style = space
+indent_size = 2
diff --git a/jhipster/jhipster-microservice/dealer-app/.gitattributes b/jhipster/jhipster-microservice/dealer-app/.gitattributes
new file mode 100644
index 0000000000..2a13efa88f
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/.gitattributes
@@ -0,0 +1,22 @@
+# All text files should have the "lf" (Unix) line endings
+* text eol=lf
+
+# Explicitly declare text files you want to always be normalized and converted
+# to native line endings on checkout.
+*.java text
+*.js text
+*.css text
+*.html text
+
+# Denote all files that are truly binary and should not be modified.
+*.png binary
+*.jpg binary
+*.jar binary
+*.pdf binary
+*.eot binary
+*.ttf binary
+*.gzip binary
+*.gz binary
+*.ai binary
+*.eps binary
+*.swf binary
diff --git a/jhipster/jhipster-microservice/dealer-app/.gitignore b/jhipster/jhipster-microservice/dealer-app/.gitignore
new file mode 100644
index 0000000000..74b29e2042
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/.gitignore
@@ -0,0 +1,141 @@
+######################
+# Project Specific
+######################
+/target/www/**
+/src/test/javascript/coverage/
+/src/test/javascript/PhantomJS*/
+
+######################
+# Node
+######################
+/node/
+node_tmp/
+node_modules/
+npm-debug.log.*
+
+######################
+# SASS
+######################
+.sass-cache/
+
+######################
+# Eclipse
+######################
+*.pydevproject
+.project
+.metadata
+tmp/
+tmp/**/*
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.classpath
+.settings/
+.loadpath
+.factorypath
+/src/main/resources/rebel.xml
+
+# External tool builders
+.externalToolBuilders/**
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# PDT-specific
+.buildpath
+
+######################
+# Intellij
+######################
+.idea/
+*.iml
+*.iws
+*.ipr
+*.ids
+*.orig
+
+######################
+# Visual Studio Code
+######################
+.vscode/
+
+######################
+# Maven
+######################
+/log/
+/target/
+
+######################
+# Gradle
+######################
+.gradle/
+/build/
+
+######################
+# Package Files
+######################
+*.jar
+*.war
+*.ear
+*.db
+
+######################
+# Windows
+######################
+# Windows image file caches
+Thumbs.db
+
+# Folder config file
+Desktop.ini
+
+######################
+# Mac OSX
+######################
+.DS_Store
+.svn
+
+# Thumbnails
+._*
+
+# Files that might appear on external disk
+.Spotlight-V100
+.Trashes
+
+######################
+# Directories
+######################
+/bin/
+/deploy/
+
+######################
+# Logs
+######################
+*.log
+
+######################
+# Others
+######################
+*.class
+*.*~
+*~
+.merge_file*
+
+######################
+# Gradle Wrapper
+######################
+!gradle/wrapper/gradle-wrapper.jar
+
+######################
+# Maven Wrapper
+######################
+!.mvn/wrapper/maven-wrapper.jar
+
+######################
+# ESLint
+######################
+.eslintcache
diff --git a/jhipster/jhipster-microservice/dealer-app/.jhipster/Dealer.json b/jhipster/jhipster-microservice/dealer-app/.jhipster/Dealer.json
new file mode 100644
index 0000000000..e9b4a8112e
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/.jhipster/Dealer.json
@@ -0,0 +1,21 @@
+{
+ "fluentMethods": true,
+ "relationships": [],
+ "fields": [
+ {
+ "fieldName": "name",
+ "fieldType": "String"
+ },
+ {
+ "fieldName": "address",
+ "fieldType": "String"
+ }
+ ],
+ "changelogDate": "20170503044952",
+ "dto": "no",
+ "service": "no",
+ "entityTableName": "dealer",
+ "pagination": "infinite-scroll",
+ "microserviceName": "dealerapp",
+ "searchEngine": false
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/.mvn/wrapper/maven-wrapper.jar b/jhipster/jhipster-microservice/dealer-app/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000000..5fd4d5023f
Binary files /dev/null and b/jhipster/jhipster-microservice/dealer-app/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/jhipster/jhipster-microservice/dealer-app/.mvn/wrapper/maven-wrapper.properties b/jhipster/jhipster-microservice/dealer-app/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000000..c954cec91c
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1 @@
+distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
diff --git a/jhipster/jhipster-microservice/dealer-app/.yo-rc.json b/jhipster/jhipster-microservice/dealer-app/.yo-rc.json
new file mode 100644
index 0000000000..aa9167a92e
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/.yo-rc.json
@@ -0,0 +1,29 @@
+{
+ "generator-jhipster": {
+ "jhipsterVersion": "4.0.8",
+ "baseName": "dealerapp",
+ "packageName": "com.dealer.app",
+ "packageFolder": "com/dealer/app",
+ "serverPort": "8082",
+ "authenticationType": "jwt",
+ "hibernateCache": "hazelcast",
+ "clusteredHttpSession": false,
+ "websocket": false,
+ "databaseType": "sql",
+ "devDatabaseType": "h2Disk",
+ "prodDatabaseType": "mysql",
+ "searchEngine": false,
+ "messageBroker": false,
+ "serviceDiscoveryType": "eureka",
+ "buildTool": "maven",
+ "enableSocialSignIn": false,
+ "jwtSecretKey": "d4c73e937677223a85c7fcebae7a6ce0c48c3b01",
+ "enableTranslation": false,
+ "applicationType": "microservice",
+ "testFrameworks": [],
+ "jhiPrefix": "jhi",
+ "skipClient": true,
+ "skipUserManagement": true,
+ "clientPackageManager": "yarn"
+ }
+}
\ No newline at end of file
diff --git a/jhipster/jhipster-microservice/dealer-app/README.md b/jhipster/jhipster-microservice/dealer-app/README.md
new file mode 100644
index 0000000000..f0fb5fb820
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/README.md
@@ -0,0 +1,75 @@
+# dealerapp
+This application was generated using JHipster 4.0.8, you can find documentation and help at [https://jhipster.github.io/documentation-archive/v4.0.8](https://jhipster.github.io/documentation-archive/v4.0.8).
+
+This is a "microservice" application intended to be part of a microservice architecture, please refer to the [Doing microservices with JHipster][] page of the documentation for more information.
+
+This application is configured for Service Discovery and Configuration with the JHipster-Registry. On launch, it will refuse to start if it is not able to connect to the JHipster-Registry at [http://localhost:8761](http://localhost:8761). For more information, read our documentation on [Service Discovery and Configuration with the JHipster-Registry][].
+
+## Development
+
+To start your application in the dev profile, simply run:
+
+ ./mvnw
+
+
+For further instructions on how to develop with JHipster, have a look at [Using JHipster in development][].
+
+
+## Building for production
+
+To optimize the dealerapp application for production, run:
+
+ ./mvnw -Pprod clean package
+
+To ensure everything worked, run:
+
+ java -jar target/*.war
+
+
+Refer to [Using JHipster in production][] for more details.
+
+## Testing
+
+To launch your application's tests, run:
+
+ ./mvnw clean test
+
+For more information, refer to the [Running tests page][].
+
+## Using Docker to simplify development (optional)
+
+You can use Docker to improve your JHipster development experience. A number of docker-compose configuration are available in the [src/main/docker](src/main/docker) folder to launch required third party services.
+For example, to start a mysql database in a docker container, run:
+
+ docker-compose -f src/main/docker/mysql.yml up -d
+
+To stop it and remove the container, run:
+
+ docker-compose -f src/main/docker/mysql.yml down
+
+You can also fully dockerize your application and all the services that it depends on.
+To achieve this, first build a docker image of your app by running:
+
+ ./mvnw package -Pprod docker:build
+
+Then run:
+
+ docker-compose -f src/main/docker/app.yml up -d
+
+For more information refer to [Using Docker and Docker-Compose][], this page also contains information on the docker-compose sub-generator (`yo jhipster:docker-compose`), which is able to generate docker configurations for one or several JHipster applications.
+
+## Continuous Integration (optional)
+
+To configure CI for your project, run the ci-cd sub-generator (`yo jhipster:ci-cd`), this will let you generate configuration files for a number of Continuous Integration systems. Consult the [Setting up Continuous Integration][] page for more information.
+
+[JHipster Homepage and latest documentation]: https://jhipster.github.io
+[JHipster 4.0.8 archive]: https://jhipster.github.io/documentation-archive/v4.0.8
+[Doing microservices with JHipster]: https://jhipster.github.io/documentation-archive/v4.0.8/microservices-architecture/
+[Using JHipster in development]: https://jhipster.github.io/documentation-archive/v4.0.8/development/
+[Service Discovery and Configuration with the JHipster-Registry]: https://jhipster.github.io/documentation-archive/v4.0.8/microservices-architecture/#jhipster-registry
+[Using Docker and Docker-Compose]: https://jhipster.github.io/documentation-archive/v4.0.8/docker-compose
+[Using JHipster in production]: https://jhipster.github.io/documentation-archive/v4.0.8/production/
+[Running tests page]: https://jhipster.github.io/documentation-archive/v4.0.8/running-tests/
+[Setting up Continuous Integration]: https://jhipster.github.io/documentation-archive/v4.0.8/setting-up-ci/
+
+
diff --git a/jhipster/jhipster-microservice/dealer-app/mvnw b/jhipster/jhipster-microservice/dealer-app/mvnw
new file mode 100755
index 0000000000..a1ba1bf554
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/mvnw
@@ -0,0 +1,233 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven2 Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ #
+ # Look for the Apple JDKs first to preserve the existing behaviour, and then look
+ # for the new JDKs provided by Oracle.
+ #
+ if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
+ #
+ # Oracle JDKs
+ #
+ export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=`/usr/libexec/java_home`
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Migwn, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+ # TODO classpath?
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`which java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+fi
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+ local basedir=$(pwd)
+ local wdir=$(pwd)
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ wdir=$(cd "$wdir/.."; pwd)
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} "$@"
diff --git a/jhipster/jhipster-microservice/dealer-app/mvnw.cmd b/jhipster/jhipster-microservice/dealer-app/mvnw.cmd
new file mode 100644
index 0000000000..2b934e89dd
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/mvnw.cmd
@@ -0,0 +1,145 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven2 Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+set MAVEN_CMD_LINE_ARGS=%*
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+
+set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
\ No newline at end of file
diff --git a/jhipster/jhipster-microservice/dealer-app/package.json b/jhipster/jhipster-microservice/dealer-app/package.json
new file mode 100644
index 0000000000..ac56dd89a7
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/package.json
@@ -0,0 +1,5 @@
+{
+ "devDependencies": {
+ "generator-jhipster": "4.0.8"
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/pom.xml b/jhipster/jhipster-microservice/dealer-app/pom.xml
new file mode 100644
index 0000000000..359783ef81
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/pom.xml
@@ -0,0 +1,926 @@
+
+
+ 4.0.0
+
+
+ parent-boot-5
+ com.baeldung
+ 0.0.1-SNAPSHOT
+ ../../../parent-boot-5
+
+
+ com.dealer.app
+ dealerapp
+ 0.0.1-SNAPSHOT
+ war
+ Dealerapp
+
+
+ ${maven.version}
+
+
+
+ -Djava.security.egd=file:/dev/./urandom -Xmx256m
+ 3.6.2
+ 2.0.0
+ 2.5
+ 3.5
+ 0.4.13
+ 1.2
+ 5.2.8.Final
+ 2.6.0
+ 0.7.9
+ 1.8
+ 3.21.0-GA
+ 1.0.0
+ 1.1.0
+ 0.7.0
+ 3.6
+ 2.0.0
+ 4.8
+ jdt_apt
+ 1.1.0.Final
+ 1.4.1
+ 3.0.1
+ yyyyMMddHHmmss
+ 3.0.0
+ 3.1.3
+ v6.10.0
+
+
+
+ 0.0.20
+
+ ${project.build.directory}/test-results
+ false
+ 3.2.2
+ 2.12.1
+ 3.2
+
+ src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.*
+
+ S3437,UndocumentedApi,BoldAndItalicTagsCheck
+
+
+ src/main/webapp/app/**/*.*
+ Web:BoldAndItalicTagsCheck
+
+ src/main/java/**/*
+ squid:S3437
+
+ src/main/java/**/*
+ squid:UndocumentedApi
+
+ ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec
+ ${project.testresult.directory}/coverage/jacoco/jacoco.exec
+ jacoco
+
+ ${project.testresult.directory}/karma
+
+ ${project.testresult.directory}/coverage/report-lcov/lcov.info
+
+ ${project.testresult.directory}/coverage/report-lcov/lcov.info
+
+ ${project.basedir}/src/main/
+ ${project.testresult.directory}/surefire-reports
+ ${project.basedir}/src/test/
+
+ 2.5.0
+
+ Camden.SR5
+ 2.6.1
+ 1.4.10.Final
+ 1.1.0.Final
+ v0.21.3
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+
+
+ io.github.jhipster
+ jhipster
+ ${jhipster.server.version}
+
+
+ io.dropwizard.metrics
+ metrics-core
+
+
+ io.dropwizard.metrics
+ metrics-annotation
+ ${dropwizard-metrics.version}
+
+
+ io.dropwizard.metrics
+ metrics-json
+ ${dropwizard-metrics.version}
+
+
+ io.dropwizard.metrics
+ metrics-jvm
+ ${dropwizard-metrics.version}
+
+
+ io.dropwizard.metrics
+ metrics-servlet
+ ${dropwizard-metrics.version}
+
+
+ io.dropwizard.metrics
+ metrics-servlets
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-hibernate5
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-hppc
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-json-org
+
+
+ com.h2database
+ h2
+
+
+ com.hazelcast
+ hazelcast
+
+
+ com.hazelcast
+ hazelcast-hibernate52
+ ${hazelcast-hibernate52.version}
+
+
+ com.hazelcast
+ hazelcast-spring
+
+
+ org.awaitility
+ awaitility
+ ${awaitility.version}
+ test
+
+
+ com.jayway.jsonpath
+ json-path
+ test
+
+
+
+ io.springfox
+ springfox-swagger2
+ ${springfox.version}
+
+
+ org.mapstruct
+ mapstruct
+
+
+
+
+ io.springfox
+ springfox-bean-validators
+ ${springfox.version}
+
+
+ com.mattbertolini
+ liquibase-slf4j
+ ${liquibase-slf4j.version}
+
+
+ com.ryantenney.metrics
+ metrics-spring
+ ${metrics-spring.version}
+
+
+ com.codahale.metrics
+ metrics-annotation
+
+
+ com.codahale.metrics
+ metrics-core
+
+
+ com.codahale.metrics
+ metrics-healthchecks
+
+
+
+
+ com.zaxxer
+ HikariCP
+
+
+ tools
+ com.sun
+
+
+
+
+
+ commons-io
+ commons-io
+ ${commons-io.version}
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang.version}
+
+
+ javax.cache
+ cache-api
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+ org.hibernate
+ hibernate-envers
+
+
+ org.hibernate
+ hibernate-validator
+
+
+ org.liquibase
+ liquibase-core
+
+
+ jetty-servlet
+ org.eclipse.jetty
+
+
+
+
+ org.mapstruct
+ mapstruct-jdk8
+ ${mapstruct.version}
+
+
+ org.springframework
+ spring-context-support
+
+
+ org.springframework.boot
+ spring-boot-actuator
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+ org.springframework.boot
+ spring-boot-loader-tools
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-logging
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+
+
+
+
+ io.jsonwebtoken
+ jjwt
+ ${jjwt.version}
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter
+
+
+ org.springframework.cloud
+ spring-cloud-starter-ribbon
+
+
+
+ io.netty
+ netty-transport-native-epoll
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-hystrix
+
+
+ org.springframework.cloud
+ spring-cloud-starter-spectator
+
+
+ org.springframework.retry
+ spring-retry
+
+
+ org.springframework.cloud
+ spring-cloud-starter-eureka
+
+
+ org.springframework.cloud
+ spring-cloud-starter-config
+
+
+ org.springframework.cloud
+ spring-cloud-starter-feign
+
+
+ net.logstash.logback
+ logstash-logback-encoder
+ ${logstash-logback-encoder.version}
+
+
+ ch.qos.logback
+ logback-core
+
+
+ ch.qos.logback
+ logback-classic
+
+
+ ch.qos.logback
+ logback-access
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-cloud-connectors
+
+
+
+ org.springframework.security
+ spring-security-data
+
+
+
+
+ spring-boot:run
+
+
+ com.github.ekryd.sortpom
+ sortpom-maven-plugin
+ ${sortpom-maven-plugin.version}
+
+
+ verify
+
+ sort
+
+
+
+
+ true
+ 4
+ groupId,artifactId
+ groupId,artifactId
+ true
+ false
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${mapstruct.version}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-eclipse-plugin
+
+ true
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ ${maven-enforcer-plugin.version}
+
+
+ enforce-versions
+
+ enforce
+
+
+
+
+
+
+ You are running an older version of Maven. JHipster requires at least Maven ${maven.version}
+ [${maven.version},)
+
+
+ You are running an older version of Java. JHipster requires at least JDK ${java.version}
+ [${java.version}.0,)
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ ${maven-resources-plugin.version}
+
+
+ default-resources
+ validate
+
+ copy-resources
+
+
+ target/classes
+ false
+
+ #
+
+
+
+ src/main/resources/
+ true
+
+ **/*.xml
+ **/*.yml
+
+
+
+ src/main/resources/
+ false
+
+ **/*.xml
+ **/*.yml
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ alphabetical
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco-maven-plugin.version}
+
+
+ pre-unit-tests
+
+ prepare-agent
+
+
+
+ ${project.testresult.directory}/coverage/jacoco/jacoco.exec
+
+
+
+
+ post-unit-test
+ test
+
+ report
+
+
+ ${project.testresult.directory}/coverage/jacoco/jacoco.exec
+ ${project.testresult.directory}/coverage/jacoco
+
+
+
+
+
+ org.sonarsource.scanner.maven
+ sonar-maven-plugin
+ ${sonar-maven-plugin.version}
+
+
+ org.liquibase
+ liquibase-maven-plugin
+ ${liquibase.version}
+
+ src/main/resources/config/liquibase/master.xml
+ src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml
+ org.h2.Driver
+ jdbc:h2:file:./target/h2db/db/dealerapp
+
+ dealerapp
+
+ hibernate:spring:com.dealer.app.domain?dialect=org.hibernate.dialect.H2Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
+ true
+ debug
+
+
+
+ org.javassist
+ javassist
+ ${javassist.version}
+
+
+ org.liquibase.ext
+ liquibase-hibernate5
+ ${liquibase-hibernate5.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+ ${project.parent.version}
+
+
+ javax.validation
+ validation-api
+ ${validation-api.version}
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+ true
+
+
+
+
+ com.spotify
+ docker-maven-plugin
+ ${docker-maven-plugin.version}
+
+ dealerapp
+ src/main/docker
+
+
+ /
+ ${project.build.directory}
+ ${project.build.finalName}.war
+
+
+
+
+
+
+
+
+
+
+ org.eclipse.m2e
+ lifecycle-mapping
+ 1.0.0
+
+
+
+
+
+ org.jacoco
+
+ jacoco-maven-plugin
+
+
+ ${jacoco-maven-plugin.version}
+
+
+ prepare-agent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ no-liquibase
+
+ ,no-liquibase
+
+
+
+ swagger
+
+ ,swagger
+
+
+
+ dev
+
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-undertow
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+
+
+
+
+
+
+ DEBUG
+
+ dev${profile.no-liquibase}
+
+
+
+ prod
+
+
+ org.springframework.boot
+ spring-boot-starter-undertow
+
+
+
+
+
+ maven-clean-plugin
+
+
+
+ target/www/
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+ build-info
+
+
+
+
+
+
+
+
+ INFO
+
+ prod${profile.swagger}${profile.no-liquibase}
+
+
+
+
+ cc
+
+
+ org.springframework.boot
+ spring-boot-starter-undertow
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ src/main/webapp/
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+ true
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ default-compile
+ none
+
+
+ default-testCompile
+ none
+
+
+
+
+ net.alchim31.maven
+ scala-maven-plugin
+ ${scala-maven-plugin.version}
+
+
+ compile
+ compile
+
+ add-source
+ compile
+
+
+
+ test-compile
+ test-compile
+
+ add-source
+ testCompile
+
+
+
+
+ incremental
+ true
+ ${scala.version}
+
+
+
+
+
+
+ DEBUG
+
+ dev,swagger
+
+
+
+
+ graphite
+
+
+ io.dropwizard.metrics
+ metrics-graphite
+
+
+
+
+
+ prometheus
+
+
+ io.prometheus
+ simpleclient
+ ${prometheus-simpleclient.version}
+
+
+ io.prometheus
+ simpleclient_servlet
+ ${prometheus-simpleclient.version}
+
+
+ io.prometheus
+ simpleclient_dropwizard
+ ${prometheus-simpleclient.version}
+
+
+
+
+
+ IDE
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${mapstruct.version}
+
+
+
+
+
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/docker/Dockerfile b/jhipster/jhipster-microservice/dealer-app/src/main/docker/Dockerfile
new file mode 100644
index 0000000000..cdef3a17e4
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/docker/Dockerfile
@@ -0,0 +1,13 @@
+FROM openjdk:8-jre-alpine
+
+ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
+ JHIPSTER_SLEEP=0
+
+# add directly the war
+ADD *.war /app.war
+
+VOLUME /tmp
+EXPOSE 8082 5701/udp
+CMD echo "The application will start in ${JHIPSTER_SLEEP}s..." && \
+ sleep ${JHIPSTER_SLEEP} && \
+ java -Djava.security.egd=file:/dev/./urandom -jar /app.war
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/docker/app.yml b/jhipster/jhipster-microservice/dealer-app/src/main/docker/app.yml
new file mode 100644
index 0000000000..85a816052e
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/docker/app.yml
@@ -0,0 +1,19 @@
+version: '2'
+services:
+ dealerapp-app:
+ image: dealerapp
+ environment:
+ - SPRING_PROFILES_ACTIVE=prod,swagger
+ - SPRING_CLOUD_CONFIG_URI=http://admin:$${jhipster.registry.password}@jhipster-registry:8761/config
+ - SPRING_DATASOURCE_URL=jdbc:mysql://dealerapp-mysql:3306/dealerapp?useUnicode=true&characterEncoding=utf8&useSSL=false
+ - JHIPSTER_SLEEP=10 # gives time for the database to boot before the application
+ dealerapp-mysql:
+ extends:
+ file: mysql.yml
+ service: dealerapp-mysql
+ jhipster-registry:
+ extends:
+ file: jhipster-registry.yml
+ service: jhipster-registry
+ environment:
+ - SPRING_CLOUD_CONFIG_SERVER_NATIVE_SEARCH_LOCATIONS=file:./central-config/docker-config/
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/docker/central-server-config/README.md b/jhipster/jhipster-microservice/dealer-app/src/main/docker/central-server-config/README.md
new file mode 100644
index 0000000000..022a152863
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/docker/central-server-config/README.md
@@ -0,0 +1,7 @@
+# Central configuration sources details
+
+The JHipster-Registry will use the following directories as its configuration source :
+- localhost-config : when running the registry in docker with the jhipster-registry.yml docker-compose file
+- docker-config : when running the registry and the app both in docker with the app.yml docker-compose file
+
+For more info, refer to http://jhipster.github.io/microservices-architecture/#registry_app_configuration
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/docker/central-server-config/docker-config/application.yml b/jhipster/jhipster-microservice/dealer-app/src/main/docker/central-server-config/docker-config/application.yml
new file mode 100644
index 0000000000..f11d367241
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/docker/central-server-config/docker-config/application.yml
@@ -0,0 +1,15 @@
+# Common configuration shared between all applications
+configserver:
+ name: Docker JHipster Registry
+ status: Connected to the JHipster Registry running in Docker
+
+jhipster:
+ security:
+ authentication:
+ jwt:
+ secret: my-secret-token-to-change-in-production
+
+eureka:
+ client:
+ serviceUrl:
+ defaultZone: http://admin:${jhipster.registry.password}@jhipster-registry:8761/eureka/
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/docker/central-server-config/localhost-config/application.yml b/jhipster/jhipster-microservice/dealer-app/src/main/docker/central-server-config/localhost-config/application.yml
new file mode 100644
index 0000000000..052a6d0535
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/docker/central-server-config/localhost-config/application.yml
@@ -0,0 +1,15 @@
+# Common configuration shared between all applications
+configserver:
+ name: Docker JHipster Registry
+ status: Connected to the JHipster Registry running in Docker
+
+jhipster:
+ security:
+ authentication:
+ jwt:
+ secret: my-secret-token-to-change-in-production
+
+eureka:
+ client:
+ serviceUrl:
+ defaultZone: http://admin:${jhipster.registry.password}@localhost:8761/eureka/
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/docker/jhipster-registry.yml b/jhipster/jhipster-microservice/dealer-app/src/main/docker/jhipster-registry.yml
new file mode 100644
index 0000000000..58feb685d4
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/docker/jhipster-registry.yml
@@ -0,0 +1,18 @@
+version: '2'
+services:
+ jhipster-registry:
+ image: jhipster/jhipster-registry:v2.5.8
+ volumes:
+ - ./central-server-config:/central-config
+ # When run with the "dev" Spring profile, the JHipster Registry will
+ # read the config from the local filesystem (central-server-config directory)
+ # When run with the "prod" Spring profile, it will read the config from a git repository
+ # See http://jhipster.github.io/microservices-architecture/#registry_app_configuration
+ environment:
+ - SPRING_PROFILES_ACTIVE=dev
+ - SECURITY_USER_PASSWORD=admin
+ - SPRING_CLOUD_CONFIG_SERVER_NATIVE_SEARCH_LOCATIONS=file:./central-config/localhost-config/
+ # - GIT_URI=https://github.com/jhipster/jhipster-registry/
+ # - GIT_SEARCH_PATHS=central-config
+ ports:
+ - 8761:8761
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/docker/mysql.yml b/jhipster/jhipster-microservice/dealer-app/src/main/docker/mysql.yml
new file mode 100644
index 0000000000..866f39f947
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/docker/mysql.yml
@@ -0,0 +1,13 @@
+version: '2'
+services:
+ dealerapp-mysql:
+ image: mysql:5.7.13
+ # volumes:
+ # - ~/volumes/jhipster/dealerapp/mysql/:/var/lib/mysql/
+ environment:
+ - MYSQL_USER=root
+ - MYSQL_ALLOW_EMPTY_PASSWORD=yes
+ - MYSQL_DATABASE=dealerapp
+ ports:
+ - 3306:3306
+ command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/docker/sonar.yml b/jhipster/jhipster-microservice/dealer-app/src/main/docker/sonar.yml
new file mode 100644
index 0000000000..0ed7462f28
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/docker/sonar.yml
@@ -0,0 +1,7 @@
+version: '2'
+services:
+ dealerapp-sonar:
+ image: sonarqube:6.2-alpine
+ ports:
+ - 9000:9000
+ - 9092:9092
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/ApplicationWebXml.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/ApplicationWebXml.java
new file mode 100644
index 0000000000..2321d72c70
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/ApplicationWebXml.java
@@ -0,0 +1,21 @@
+package com.dealer.app;
+
+import com.dealer.app.config.DefaultProfileUtil;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+
+/**
+ * This is a helper Java class that provides an alternative to creating a web.xml.
+ * This will be invoked only when the application is deployed to a servlet container like Tomcat, JBoss etc.
+ */
+public class ApplicationWebXml extends SpringBootServletInitializer {
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ /**
+ * set a default to use when no profile is configured.
+ */
+ DefaultProfileUtil.addDefaultProfile(application.application());
+ return application.sources(DealerappApp.class);
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/DealerappApp.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/DealerappApp.java
new file mode 100644
index 0000000000..72075d8bfe
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/DealerappApp.java
@@ -0,0 +1,91 @@
+package com.dealer.app;
+
+import com.dealer.app.config.ApplicationProperties;
+import com.dealer.app.config.DefaultProfileUtil;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.actuate.autoconfigure.*;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.core.env.Environment;
+
+import javax.annotation.PostConstruct;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.Collection;
+
+@ComponentScan
+@EnableAutoConfiguration(exclude = {MetricFilterAutoConfiguration.class, MetricRepositoryAutoConfiguration.class})
+@EnableConfigurationProperties({LiquibaseProperties.class, ApplicationProperties.class})
+@EnableDiscoveryClient
+public class DealerappApp {
+
+ private static final Logger log = LoggerFactory.getLogger(DealerappApp.class);
+
+ private final Environment env;
+
+ public DealerappApp(Environment env) {
+ this.env = env;
+ }
+
+ /**
+ * Initializes dealerapp.
+ *
+ * Spring profiles can be configured with a program arguments --spring.profiles.active=your-active-profile
+ *
+ * You can find more information on how profiles work with JHipster on http://jhipster.github.io/profiles/.
+ */
+ @PostConstruct
+ public void initApplication() {
+ Collection activeProfiles = Arrays.asList(env.getActiveProfiles());
+ if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
+ log.error("You have misconfigured your application! It should not run " +
+ "with both the 'dev' and 'prod' profiles at the same time.");
+ }
+ if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD)) {
+ log.error("You have misconfigured your application! It should not" +
+ "run with both the 'dev' and 'cloud' profiles at the same time.");
+ }
+ }
+
+ /**
+ * Main method, used to run the application.
+ *
+ * @param args the command line arguments
+ * @throws UnknownHostException if the local host name could not be resolved into an address
+ */
+ public static void main(String[] args) throws UnknownHostException {
+ SpringApplication app = new SpringApplication(DealerappApp.class);
+ DefaultProfileUtil.addDefaultProfile(app);
+ Environment env = app.run(args).getEnvironment();
+ String protocol = "http";
+ if (env.getProperty("server.ssl.key-store") != null) {
+ protocol = "https";
+ }
+ log.info("\n----------------------------------------------------------\n\t" +
+ "Application '{}' is running! Access URLs:\n\t" +
+ "Local: \t\t{}://localhost:{}\n\t" +
+ "External: \t{}://{}:{}\n\t" +
+ "Profile(s): \t{}\n----------------------------------------------------------",
+ env.getProperty("spring.application.name"),
+ protocol,
+ env.getProperty("server.port"),
+ protocol,
+ InetAddress.getLocalHost().getHostAddress(),
+ env.getProperty("server.port"),
+ env.getActiveProfiles());
+
+ String configServerStatus = env.getProperty("configserver.status");
+ log.info("\n----------------------------------------------------------\n\t" +
+ "Config Server: \t{}\n----------------------------------------------------------",
+ configServerStatus == null ? "Not found or not setup for this application" : configServerStatus);
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/aop/logging/LoggingAspect.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/aop/logging/LoggingAspect.java
new file mode 100644
index 0000000000..a7364157c9
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/aop/logging/LoggingAspect.java
@@ -0,0 +1,79 @@
+package com.dealer.app.aop.logging;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.env.Environment;
+
+import java.util.Arrays;
+
+/**
+ * Aspect for logging execution of service and repository Spring components.
+ *
+ * By default, it only runs with the "dev" profile.
+ */
+@Aspect
+public class LoggingAspect {
+
+ private final Logger log = LoggerFactory.getLogger(this.getClass());
+
+ private final Environment env;
+
+ public LoggingAspect(Environment env) {
+ this.env = env;
+ }
+
+ /**
+ * Pointcut that matches all repositories, services and Web REST endpoints.
+ */
+ @Pointcut("within(com.dealer.app.repository..*) || within(com.dealer.app.service..*) || within(com.dealer.app.web.rest..*)")
+ public void loggingPointcut() {
+ // Method is empty as this is just a Pointcut, the implementations are in the advices.
+ }
+
+ /**
+ * Advice that logs methods throwing exceptions.
+ */
+ @AfterThrowing(pointcut = "loggingPointcut()", throwing = "e")
+ public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
+ log.error("Exception in {}.{}() with cause = \'{}\' and exception = \'{}\'", joinPoint.getSignature().getDeclaringTypeName(),
+ joinPoint.getSignature().getName(), e.getCause() != null? e.getCause() : "NULL", e.getMessage(), e);
+
+ } else {
+ log.error("Exception in {}.{}() with cause = {}", joinPoint.getSignature().getDeclaringTypeName(),
+ joinPoint.getSignature().getName(), e.getCause() != null? e.getCause() : "NULL");
+ }
+ }
+
+ /**
+ * Advice that logs when a method is entered and exited.
+ */
+ @Around("loggingPointcut()")
+ public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
+ if (log.isDebugEnabled()) {
+ log.debug("Enter: {}.{}() with argument[s] = {}", joinPoint.getSignature().getDeclaringTypeName(),
+ joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs()));
+ }
+ try {
+ Object result = joinPoint.proceed();
+ if (log.isDebugEnabled()) {
+ log.debug("Exit: {}.{}() with result = {}", joinPoint.getSignature().getDeclaringTypeName(),
+ joinPoint.getSignature().getName(), result);
+ }
+ return result;
+ } catch (IllegalArgumentException e) {
+ log.error("Illegal argument: {} in {}.{}()", Arrays.toString(joinPoint.getArgs()),
+ joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
+
+ throw e;
+ }
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/ApplicationProperties.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/ApplicationProperties.java
new file mode 100644
index 0000000000..dc11fa63fe
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/ApplicationProperties.java
@@ -0,0 +1,15 @@
+package com.dealer.app.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Properties specific to JHipster.
+ *
+ *
+ * Properties are configured in the application.yml file.
+ *
+ */
+@ConfigurationProperties(prefix = "application", ignoreUnknownFields = false)
+public class ApplicationProperties {
+
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/AsyncConfiguration.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/AsyncConfiguration.java
new file mode 100644
index 0000000000..3b6de121fd
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/AsyncConfiguration.java
@@ -0,0 +1,46 @@
+package com.dealer.app.config;
+
+import io.github.jhipster.async.ExceptionHandlingAsyncTaskExecutor;
+import io.github.jhipster.config.JHipsterProperties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
+import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.*;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+
+@Configuration
+@EnableAsync
+@EnableScheduling
+public class AsyncConfiguration implements AsyncConfigurer {
+
+ private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class);
+
+ private final JHipsterProperties jHipsterProperties;
+
+ public AsyncConfiguration(JHipsterProperties jHipsterProperties) {
+ this.jHipsterProperties = jHipsterProperties;
+ }
+
+ @Override
+ @Bean(name = "taskExecutor")
+ public Executor getAsyncExecutor() {
+ log.debug("Creating Async Task Executor");
+ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+ executor.setCorePoolSize(jHipsterProperties.getAsync().getCorePoolSize());
+ executor.setMaxPoolSize(jHipsterProperties.getAsync().getMaxPoolSize());
+ executor.setQueueCapacity(jHipsterProperties.getAsync().getQueueCapacity());
+ executor.setThreadNamePrefix("dealerapp-Executor-");
+ return new ExceptionHandlingAsyncTaskExecutor(executor);
+ }
+
+ @Override
+ public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+ return new SimpleAsyncUncaughtExceptionHandler();
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/CacheConfiguration.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/CacheConfiguration.java
new file mode 100644
index 0000000000..6626dea1a2
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/CacheConfiguration.java
@@ -0,0 +1,134 @@
+package com.dealer.app.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+import io.github.jhipster.config.JHipsterProperties;
+
+import com.hazelcast.config.Config;
+import com.hazelcast.core.HazelcastInstance;
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.config.MapConfig;
+import com.hazelcast.config.EvictionPolicy;
+import com.hazelcast.config.MaxSizeConfig;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.context.annotation.*;
+import org.springframework.core.env.Environment;
+
+import javax.annotation.PreDestroy;
+
+@Configuration
+@EnableCaching
+@AutoConfigureAfter(value = { MetricsConfiguration.class })
+@AutoConfigureBefore(value = { WebConfigurer.class, DatabaseConfiguration.class })
+public class CacheConfiguration {
+
+ private final Logger log = LoggerFactory.getLogger(CacheConfiguration.class);
+
+ private final Environment env;
+
+ private final DiscoveryClient discoveryClient;
+
+ private final ServerProperties serverProperties;
+
+ public CacheConfiguration(Environment env, DiscoveryClient discoveryClient, ServerProperties serverProperties) {
+ this.env = env;
+ this.discoveryClient = discoveryClient;
+ this.serverProperties = serverProperties;
+ }
+
+ @PreDestroy
+ public void destroy() {
+ log.info("Closing Cache Manager");
+ Hazelcast.shutdownAll();
+ }
+
+ @Bean
+ public CacheManager cacheManager(HazelcastInstance hazelcastInstance) {
+ log.debug("Starting HazelcastCacheManager");
+ CacheManager cacheManager = new com.hazelcast.spring.cache.HazelcastCacheManager(hazelcastInstance);
+ return cacheManager;
+ }
+
+ @Bean
+ public HazelcastInstance hazelcastInstance(JHipsterProperties jHipsterProperties) {
+ log.debug("Configuring Hazelcast");
+ Config config = new Config();
+ config.setInstanceName("dealerapp");
+ // The serviceId is by default the application's name, see Spring Boot's eureka.instance.appname property
+ String serviceId = discoveryClient.getLocalServiceInstance().getServiceId();
+ log.debug("Configuring Hazelcast clustering for instanceId: {}", serviceId);
+
+ // In development, everything goes through 127.0.0.1, with a different port
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
+ log.debug("Application is running with the \"dev\" profile, Hazelcast " +
+ "cluster will only work with localhost instances");
+
+ System.setProperty("hazelcast.local.localAddress", "127.0.0.1");
+ config.getNetworkConfig().setPort(serverProperties.getPort() + 5701);
+ config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(true);
+ for (ServiceInstance instance : discoveryClient.getInstances(serviceId)) {
+ String clusterMember = "127.0.0.1:" + (instance.getPort() + 5701);
+ log.debug("Adding Hazelcast (dev) cluster member " + clusterMember);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().addMember(clusterMember);
+ }
+ } else { // Production configuration, one host per instance all using port 5701
+ config.getNetworkConfig().setPort(5701);
+ config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(true);
+ for (ServiceInstance instance : discoveryClient.getInstances(serviceId)) {
+ String clusterMember = instance.getHost() + ":5701";
+ log.debug("Adding Hazelcast (prod) cluster member " + clusterMember);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().addMember(clusterMember);
+ }
+ }
+ config.getMapConfigs().put("default", initializeDefaultMapConfig());
+ config.getMapConfigs().put("com.dealer.app.domain.*", initializeDomainMapConfig(jHipsterProperties));
+ return Hazelcast.newHazelcastInstance(config);
+ }
+
+ private MapConfig initializeDefaultMapConfig() {
+ MapConfig mapConfig = new MapConfig();
+
+ /*
+ Number of backups. If 1 is set as the backup-count for example,
+ then all entries of the map will be copied to another JVM for
+ fail-safety. Valid numbers are 0 (no backup), 1, 2, 3.
+ */
+ mapConfig.setBackupCount(0);
+
+ /*
+ Valid values are:
+ NONE (no eviction),
+ LRU (Least Recently Used),
+ LFU (Least Frequently Used).
+ NONE is the default.
+ */
+ mapConfig.setEvictionPolicy(EvictionPolicy.LRU);
+
+ /*
+ Maximum size of the map. When max size is reached,
+ map is evicted based on the policy defined.
+ Any integer between 0 and Integer.MAX_VALUE. 0 means
+ Integer.MAX_VALUE. Default is 0.
+ */
+ mapConfig.setMaxSizeConfig(new MaxSizeConfig(0, MaxSizeConfig.MaxSizePolicy.USED_HEAP_SIZE));
+
+ return mapConfig;
+ }
+
+ private MapConfig initializeDomainMapConfig(JHipsterProperties jHipsterProperties) {
+ MapConfig mapConfig = new MapConfig();
+ mapConfig.setTimeToLiveSeconds(jHipsterProperties.getCache().getHazelcast().getTimeToLiveSeconds());
+ return mapConfig;
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/CloudDatabaseConfiguration.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/CloudDatabaseConfiguration.java
new file mode 100644
index 0000000000..2a64314685
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/CloudDatabaseConfiguration.java
@@ -0,0 +1,24 @@
+package com.dealer.app.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cache.CacheManager;
+import org.springframework.cloud.config.java.AbstractCloudConfig;
+import org.springframework.context.annotation.*;
+
+import javax.sql.DataSource;
+
+@Configuration
+@Profile(JHipsterConstants.SPRING_PROFILE_CLOUD)
+public class CloudDatabaseConfiguration extends AbstractCloudConfig {
+
+ private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class);
+
+ @Bean
+ public DataSource dataSource(CacheManager cacheManager) {
+ log.info("Configuring JDBC datasource from a cloud provider");
+ return connectionFactory().dataSource();
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/Constants.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/Constants.java
new file mode 100644
index 0000000000..0d2098b836
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/Constants.java
@@ -0,0 +1,16 @@
+package com.dealer.app.config;
+
+/**
+ * Application constants.
+ */
+public final class Constants {
+
+ //Regex for acceptable logins
+ public static final String LOGIN_REGEX = "^[_'.@A-Za-z0-9-]*$";
+
+ public static final String SYSTEM_ACCOUNT = "system";
+ public static final String ANONYMOUS_USER = "anonymoususer";
+
+ private Constants() {
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/DatabaseConfiguration.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/DatabaseConfiguration.java
new file mode 100644
index 0000000000..04fced065b
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/DatabaseConfiguration.java
@@ -0,0 +1,75 @@
+package com.dealer.app.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+import io.github.jhipster.config.liquibase.AsyncSpringLiquibase;
+
+import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
+import liquibase.integration.spring.SpringLiquibase;
+import org.h2.tools.Server;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.env.Environment;
+import org.springframework.core.task.TaskExecutor;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+
+@Configuration
+@EnableJpaRepositories("com.dealer.app.repository")
+@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
+@EnableTransactionManagement
+public class DatabaseConfiguration {
+
+ private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);
+
+ private final Environment env;
+
+ public DatabaseConfiguration(Environment env) {
+ this.env = env;
+ }
+
+ /**
+ * Open the TCP port for the H2 database, so it is available remotely.
+ *
+ * @return the H2 database TCP server
+ * @throws SQLException if the server failed to start
+ */
+ @Bean(initMethod = "start", destroyMethod = "stop")
+ @Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
+ public Server h2TCPServer() throws SQLException {
+ return Server.createTcpServer("-tcp","-tcpAllowOthers");
+ }
+
+ @Bean
+ public SpringLiquibase liquibase(@Qualifier("taskExecutor") TaskExecutor taskExecutor,
+ DataSource dataSource, LiquibaseProperties liquibaseProperties) {
+
+ // Use liquibase.integration.spring.SpringLiquibase if you don't want Liquibase to start asynchronously
+ SpringLiquibase liquibase = new AsyncSpringLiquibase(taskExecutor, env);
+ liquibase.setDataSource(dataSource);
+ liquibase.setChangeLog("classpath:config/liquibase/master.xml");
+ liquibase.setContexts(liquibaseProperties.getContexts());
+ liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema());
+ liquibase.setDropFirst(liquibaseProperties.isDropFirst());
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_NO_LIQUIBASE)) {
+ liquibase.setShouldRun(false);
+ } else {
+ liquibase.setShouldRun(liquibaseProperties.isEnabled());
+ log.debug("Configuring Liquibase");
+ }
+ return liquibase;
+ }
+
+ @Bean
+ public Hibernate5Module hibernate5Module() {
+ return new Hibernate5Module();
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/DateTimeFormatConfiguration.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/DateTimeFormatConfiguration.java
new file mode 100644
index 0000000000..cca6e4ca04
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/DateTimeFormatConfiguration.java
@@ -0,0 +1,17 @@
+package com.dealer.app.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@Configuration
+public class DateTimeFormatConfiguration extends WebMvcConfigurerAdapter {
+
+ @Override
+ public void addFormatters(FormatterRegistry registry) {
+ DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
+ registrar.setUseIsoFormat(true);
+ registrar.registerFormatters(registry);
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/DefaultProfileUtil.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/DefaultProfileUtil.java
new file mode 100644
index 0000000000..c914c96954
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/DefaultProfileUtil.java
@@ -0,0 +1,48 @@
+package com.dealer.app.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.core.env.Environment;
+
+import java.util.*;
+
+/**
+ * Utility class to load a Spring profile to be used as default
+ * when there is no spring.profiles.active set in the environment or as command line argument.
+ * If the value is not available in application.yml then dev profile will be used as default.
+ */
+public final class DefaultProfileUtil {
+
+ private static final String SPRING_PROFILE_DEFAULT = "spring.profiles.default";
+
+ private DefaultProfileUtil() {
+ }
+
+ /**
+ * Set a default to use when no profile is configured.
+ *
+ * @param app the Spring application
+ */
+ public static void addDefaultProfile(SpringApplication app) {
+ Map defProperties = new HashMap<>();
+ /*
+ * The default profile to use when no other profiles are defined
+ * This cannot be set in the application.yml file.
+ * See https://github.com/spring-projects/spring-boot/issues/1219
+ */
+ defProperties.put(SPRING_PROFILE_DEFAULT, JHipsterConstants.SPRING_PROFILE_DEVELOPMENT);
+ app.setDefaultProperties(defProperties);
+ }
+
+ /**
+ * Get the profiles that are applied else get default profiles.
+ */
+ public static String[] getActiveProfiles(Environment env) {
+ String[] profiles = env.getActiveProfiles();
+ if (profiles.length == 0) {
+ return env.getDefaultProfiles();
+ }
+ return profiles;
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/LocaleConfiguration.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/LocaleConfiguration.java
new file mode 100644
index 0000000000..6416813b26
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/LocaleConfiguration.java
@@ -0,0 +1,35 @@
+package com.dealer.app.config;
+
+import io.github.jhipster.config.locale.AngularCookieLocaleResolver;
+
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
+
+@Configuration
+public class LocaleConfiguration extends WebMvcConfigurerAdapter implements EnvironmentAware {
+
+ @Override
+ public void setEnvironment(Environment environment) {
+ // unused
+ }
+
+ @Bean(name = "localeResolver")
+ public LocaleResolver localeResolver() {
+ AngularCookieLocaleResolver cookieLocaleResolver = new AngularCookieLocaleResolver();
+ cookieLocaleResolver.setCookieName("NG_TRANSLATE_LANG_KEY");
+ return cookieLocaleResolver;
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
+ localeChangeInterceptor.setParamName("language");
+ registry.addInterceptor(localeChangeInterceptor);
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/LoggingAspectConfiguration.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/LoggingAspectConfiguration.java
new file mode 100644
index 0000000000..b530771a85
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/LoggingAspectConfiguration.java
@@ -0,0 +1,19 @@
+package com.dealer.app.config;
+
+import com.dealer.app.aop.logging.LoggingAspect;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.springframework.context.annotation.*;
+import org.springframework.core.env.Environment;
+
+@Configuration
+@EnableAspectJAutoProxy
+public class LoggingAspectConfiguration {
+
+ @Bean
+ @Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
+ public LoggingAspect loggingAspect(Environment env) {
+ return new LoggingAspect(env);
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/LoggingConfiguration.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/LoggingConfiguration.java
new file mode 100644
index 0000000000..d7ad0602c4
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/LoggingConfiguration.java
@@ -0,0 +1,113 @@
+package com.dealer.app.config;
+
+import io.github.jhipster.config.JHipsterProperties;
+
+import ch.qos.logback.classic.AsyncAppender;
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.LoggerContextListener;
+import ch.qos.logback.core.spi.ContextAwareBase;
+import net.logstash.logback.appender.LogstashSocketAppender;
+import net.logstash.logback.stacktrace.ShortenedThrowableConverter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class LoggingConfiguration {
+
+ private final Logger log = LoggerFactory.getLogger(LoggingConfiguration.class);
+
+ private LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+
+ @Value("${spring.application.name}")
+ private String appName;
+
+ @Value("${server.port}")
+ private String serverPort;
+
+ @Value("${eureka.instance.instanceId}")
+ private String instanceId;
+
+ private final JHipsterProperties jHipsterProperties;
+
+ public LoggingConfiguration(JHipsterProperties jHipsterProperties) {
+ this.jHipsterProperties = jHipsterProperties;
+ if (jHipsterProperties.getLogging().getLogstash().isEnabled()) {
+ addLogstashAppender(context);
+
+ // Add context listener
+ LogbackLoggerContextListener loggerContextListener = new LogbackLoggerContextListener();
+ loggerContextListener.setContext(context);
+ context.addListener(loggerContextListener);
+ }
+ }
+
+ public void addLogstashAppender(LoggerContext context) {
+ log.info("Initializing Logstash logging");
+
+ LogstashSocketAppender logstashAppender = new LogstashSocketAppender();
+ logstashAppender.setName("LOGSTASH");
+ logstashAppender.setContext(context);
+ String customFields = "{\"app_name\":\"" + appName + "\",\"app_port\":\"" + serverPort + "\"," +
+ "\"instance_id\":\"" + instanceId + "\"}";
+
+ // Set the Logstash appender config from JHipster properties
+ logstashAppender.setSyslogHost(jHipsterProperties.getLogging().getLogstash().getHost());
+ logstashAppender.setPort(jHipsterProperties.getLogging().getLogstash().getPort());
+ logstashAppender.setCustomFields(customFields);
+
+ // Limit the maximum length of the forwarded stacktrace so that it won't exceed the 8KB UDP limit of logstash
+ ShortenedThrowableConverter throwableConverter = new ShortenedThrowableConverter();
+ throwableConverter.setMaxLength(7500);
+ throwableConverter.setRootCauseFirst(true);
+ logstashAppender.setThrowableConverter(throwableConverter);
+
+ logstashAppender.start();
+
+ // Wrap the appender in an Async appender for performance
+ AsyncAppender asyncLogstashAppender = new AsyncAppender();
+ asyncLogstashAppender.setContext(context);
+ asyncLogstashAppender.setName("ASYNC_LOGSTASH");
+ asyncLogstashAppender.setQueueSize(jHipsterProperties.getLogging().getLogstash().getQueueSize());
+ asyncLogstashAppender.addAppender(logstashAppender);
+ asyncLogstashAppender.start();
+
+ context.getLogger("ROOT").addAppender(asyncLogstashAppender);
+ }
+
+ /**
+ * Logback configuration is achieved by configuration file and API.
+ * When configuration file change is detected, the configuration is reset.
+ * This listener ensures that the programmatic configuration is also re-applied after reset.
+ */
+ class LogbackLoggerContextListener extends ContextAwareBase implements LoggerContextListener {
+
+ @Override
+ public boolean isResetResistant() {
+ return true;
+ }
+
+ @Override
+ public void onStart(LoggerContext context) {
+ addLogstashAppender(context);
+ }
+
+ @Override
+ public void onReset(LoggerContext context) {
+ addLogstashAppender(context);
+ }
+
+ @Override
+ public void onStop(LoggerContext context) {
+ // Nothing to do.
+ }
+
+ @Override
+ public void onLevelChange(ch.qos.logback.classic.Logger logger, Level level) {
+ // Nothing to do.
+ }
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/MetricsConfiguration.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/MetricsConfiguration.java
new file mode 100644
index 0000000000..54b8f2af32
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/MetricsConfiguration.java
@@ -0,0 +1,113 @@
+package com.dealer.app.config;
+
+import io.github.jhipster.config.JHipsterProperties;
+import io.github.jhipster.config.metrics.SpectatorLogMetricWriter;
+
+import com.netflix.spectator.api.Registry;
+import org.springframework.boot.actuate.autoconfigure.ExportMetricReader;
+import org.springframework.boot.actuate.autoconfigure.ExportMetricWriter;
+import org.springframework.boot.actuate.metrics.writer.MetricWriter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.netflix.metrics.spectator.SpectatorMetricReader;
+
+import com.codahale.metrics.JmxReporter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Slf4jReporter;
+import com.codahale.metrics.health.HealthCheckRegistry;
+import com.codahale.metrics.jvm.*;
+import com.ryantenney.metrics.spring.config.annotation.EnableMetrics;
+import com.ryantenney.metrics.spring.config.annotation.MetricsConfigurerAdapter;
+import com.zaxxer.hikari.HikariDataSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.*;
+
+import javax.annotation.PostConstruct;
+import java.lang.management.ManagementFactory;
+import java.util.concurrent.TimeUnit;
+
+@Configuration
+@EnableMetrics(proxyTargetClass = true)
+public class MetricsConfiguration extends MetricsConfigurerAdapter {
+
+ private static final String PROP_METRIC_REG_JVM_MEMORY = "jvm.memory";
+ private static final String PROP_METRIC_REG_JVM_GARBAGE = "jvm.garbage";
+ private static final String PROP_METRIC_REG_JVM_THREADS = "jvm.threads";
+ private static final String PROP_METRIC_REG_JVM_FILES = "jvm.files";
+ private static final String PROP_METRIC_REG_JVM_BUFFERS = "jvm.buffers";
+ private final Logger log = LoggerFactory.getLogger(MetricsConfiguration.class);
+
+ private MetricRegistry metricRegistry = new MetricRegistry();
+
+ private HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry();
+
+ private final JHipsterProperties jHipsterProperties;
+
+ private HikariDataSource hikariDataSource;
+
+ public MetricsConfiguration(JHipsterProperties jHipsterProperties) {
+ this.jHipsterProperties = jHipsterProperties;
+ }
+
+ @Autowired(required = false)
+ public void setHikariDataSource(HikariDataSource hikariDataSource) {
+ this.hikariDataSource = hikariDataSource;
+ }
+
+ @Override
+ @Bean
+ public MetricRegistry getMetricRegistry() {
+ return metricRegistry;
+ }
+
+ @Override
+ @Bean
+ public HealthCheckRegistry getHealthCheckRegistry() {
+ return healthCheckRegistry;
+ }
+
+ @PostConstruct
+ public void init() {
+ log.debug("Registering JVM gauges");
+ metricRegistry.register(PROP_METRIC_REG_JVM_MEMORY, new MemoryUsageGaugeSet());
+ metricRegistry.register(PROP_METRIC_REG_JVM_GARBAGE, new GarbageCollectorMetricSet());
+ metricRegistry.register(PROP_METRIC_REG_JVM_THREADS, new ThreadStatesGaugeSet());
+ metricRegistry.register(PROP_METRIC_REG_JVM_FILES, new FileDescriptorRatioGauge());
+ metricRegistry.register(PROP_METRIC_REG_JVM_BUFFERS, new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()));
+ if (hikariDataSource != null) {
+ log.debug("Monitoring the datasource");
+ hikariDataSource.setMetricRegistry(metricRegistry);
+ }
+ if (jHipsterProperties.getMetrics().getJmx().isEnabled()) {
+ log.debug("Initializing Metrics JMX reporting");
+ JmxReporter jmxReporter = JmxReporter.forRegistry(metricRegistry).build();
+ jmxReporter.start();
+ }
+ if (jHipsterProperties.getMetrics().getLogs().isEnabled()) {
+ log.info("Initializing Metrics Log reporting");
+ final Slf4jReporter reporter = Slf4jReporter.forRegistry(metricRegistry)
+ .outputTo(LoggerFactory.getLogger("metrics"))
+ .convertRatesTo(TimeUnit.SECONDS)
+ .convertDurationsTo(TimeUnit.MILLISECONDS)
+ .build();
+ reporter.start(jHipsterProperties.getMetrics().getLogs().getReportFrequency(), TimeUnit.SECONDS);
+ }
+ }
+
+ /* Spectator metrics log reporting */
+ @Bean
+ @ConditionalOnProperty("jhipster.logging.spectator-metrics.enabled")
+ @ExportMetricReader
+ public SpectatorMetricReader SpectatorMetricReader(Registry registry) {
+ log.info("Initializing Spectator Metrics Log reporting");
+ return new SpectatorMetricReader(registry);
+ }
+
+ @Bean
+ @ConditionalOnProperty("jhipster.logging.spectator-metrics.enabled")
+ @ExportMetricWriter
+ MetricWriter metricWriter() {
+ return new SpectatorLogMetricWriter();
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/MicroserviceSecurityConfiguration.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/MicroserviceSecurityConfiguration.java
new file mode 100644
index 0000000000..86a109e91f
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/MicroserviceSecurityConfiguration.java
@@ -0,0 +1,71 @@
+package com.dealer.app.config;
+
+import com.dealer.app.security.AuthoritiesConstants;
+import com.dealer.app.security.jwt.JWTConfigurer;
+import com.dealer.app.security.jwt.TokenProvider;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
+
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
+public class MicroserviceSecurityConfiguration extends WebSecurityConfigurerAdapter {
+
+ private final TokenProvider tokenProvider;
+
+ public MicroserviceSecurityConfiguration(TokenProvider tokenProvider) {
+ this.tokenProvider = tokenProvider;
+ }
+
+ @Override
+ public void configure(WebSecurity web) throws Exception {
+ web.ignoring()
+ .antMatchers(HttpMethod.OPTIONS, "/**")
+ .antMatchers("/app/**/*.{js,html}")
+ .antMatchers("/bower_components/**")
+ .antMatchers("/i18n/**")
+ .antMatchers("/content/**")
+ .antMatchers("/swagger-ui/index.html")
+ .antMatchers("/test/**")
+ .antMatchers("/h2-console/**");
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .csrf()
+ .disable()
+ .headers()
+ .frameOptions()
+ .disable()
+ .and()
+ .sessionManagement()
+ .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+ .and()
+ .authorizeRequests()
+ .antMatchers("/api/**").authenticated()
+ .antMatchers("/management/health").permitAll()
+ .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
+ .antMatchers("/swagger-resources/configuration/ui").permitAll()
+ .and()
+ .apply(securityConfigurerAdapter());
+ }
+
+ private JWTConfigurer securityConfigurerAdapter() {
+ return new JWTConfigurer(tokenProvider);
+ }
+
+ @Bean
+ public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
+ return new SecurityEvaluationContextExtension();
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/ThymeleafConfiguration.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/ThymeleafConfiguration.java
new file mode 100644
index 0000000000..5bc92dd86d
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/ThymeleafConfiguration.java
@@ -0,0 +1,26 @@
+package com.dealer.app.config;
+
+import org.apache.commons.lang3.CharEncoding;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.*;
+import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
+
+@Configuration
+public class ThymeleafConfiguration {
+
+ @SuppressWarnings("unused")
+ private final Logger log = LoggerFactory.getLogger(ThymeleafConfiguration.class);
+
+ @Bean
+ @Description("Thymeleaf template resolver serving HTML 5 emails")
+ public ClassLoaderTemplateResolver emailTemplateResolver() {
+ ClassLoaderTemplateResolver emailTemplateResolver = new ClassLoaderTemplateResolver();
+ emailTemplateResolver.setPrefix("mails/");
+ emailTemplateResolver.setSuffix(".html");
+ emailTemplateResolver.setTemplateMode("HTML5");
+ emailTemplateResolver.setCharacterEncoding(CharEncoding.UTF_8);
+ emailTemplateResolver.setOrder(1);
+ return emailTemplateResolver;
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/WebConfigurer.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/WebConfigurer.java
new file mode 100644
index 0000000000..f34caa57d7
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/WebConfigurer.java
@@ -0,0 +1,144 @@
+package com.dealer.app.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+import io.github.jhipster.config.JHipsterProperties;
+
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.servlet.InstrumentedFilter;
+import com.codahale.metrics.servlets.MetricsServlet;
+import com.hazelcast.core.HazelcastInstance;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.embedded.*;
+import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
+import io.undertow.UndertowOptions;
+import org.springframework.boot.web.servlet.ServletContextInitializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+import java.util.*;
+import javax.servlet.*;
+
+/**
+ * Configuration of web application with Servlet 3.0 APIs.
+ */
+@Configuration
+public class WebConfigurer implements ServletContextInitializer, EmbeddedServletContainerCustomizer {
+
+ private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);
+
+ private final Environment env;
+
+ private final JHipsterProperties jHipsterProperties;
+
+ private final HazelcastInstance hazelcastInstance;
+
+ private MetricRegistry metricRegistry;
+
+ public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties, HazelcastInstance hazelcastInstance) {
+
+ this.env = env;
+ this.jHipsterProperties = jHipsterProperties;
+ this.hazelcastInstance = hazelcastInstance;
+ }
+
+ @Override
+ public void onStartup(ServletContext servletContext) throws ServletException {
+ if (env.getActiveProfiles().length != 0) {
+ log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles());
+ }
+ EnumSet disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
+ initMetrics(servletContext, disps);
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
+ initH2Console(servletContext);
+ }
+ log.info("Web application fully configured");
+ }
+
+ /**
+ * Customize the Servlet engine: Mime types, the document root, the cache.
+ */
+ @Override
+ public void customize(ConfigurableEmbeddedServletContainer container) {
+ MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
+ // IE issue, see https://github.com/jhipster/generator-jhipster/pull/711
+ mappings.add("html", "text/html;charset=utf-8");
+ // CloudFoundry issue, see https://github.com/cloudfoundry/gorouter/issues/64
+ mappings.add("json", "text/html;charset=utf-8");
+ container.setMimeMappings(mappings);
+
+ /*
+ * Enable HTTP/2 for Undertow - https://twitter.com/ankinson/status/829256167700492288
+ * HTTP/2 requires HTTPS, so HTTP requests will fallback to HTTP/1.1.
+ * See the JHipsterProperties class and your application-*.yml configuration files
+ * for more information.
+ */
+ if (jHipsterProperties.getHttp().getVersion().equals(JHipsterProperties.Http.Version.V_2_0) &&
+ container instanceof UndertowEmbeddedServletContainerFactory) {
+
+ ((UndertowEmbeddedServletContainerFactory) container)
+ .addBuilderCustomizers(builder ->
+ builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true));
+ }
+ }
+
+ /**
+ * Initializes Metrics.
+ */
+ private void initMetrics(ServletContext servletContext, EnumSet disps) {
+ log.debug("Initializing Metrics registries");
+ servletContext.setAttribute(InstrumentedFilter.REGISTRY_ATTRIBUTE,
+ metricRegistry);
+ servletContext.setAttribute(MetricsServlet.METRICS_REGISTRY,
+ metricRegistry);
+
+ log.debug("Registering Metrics Filter");
+ FilterRegistration.Dynamic metricsFilter = servletContext.addFilter("webappMetricsFilter",
+ new InstrumentedFilter());
+
+ metricsFilter.addMappingForUrlPatterns(disps, true, "/*");
+ metricsFilter.setAsyncSupported(true);
+
+ log.debug("Registering Metrics Servlet");
+ ServletRegistration.Dynamic metricsAdminServlet =
+ servletContext.addServlet("metricsServlet", new MetricsServlet());
+
+ metricsAdminServlet.addMapping("/management/metrics/*");
+ metricsAdminServlet.setAsyncSupported(true);
+ metricsAdminServlet.setLoadOnStartup(2);
+ }
+
+ @Bean
+ public CorsFilter corsFilter() {
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ CorsConfiguration config = jHipsterProperties.getCors();
+ if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
+ log.debug("Registering CORS filter");
+ source.registerCorsConfiguration("/api/**", config);
+ source.registerCorsConfiguration("/v2/api-docs", config);
+ }
+ return new CorsFilter(source);
+ }
+
+ /**
+ * Initializes H2 console.
+ */
+ private void initH2Console(ServletContext servletContext) {
+ log.debug("Initialize H2 console");
+ ServletRegistration.Dynamic h2ConsoleServlet = servletContext.addServlet("H2Console", new org.h2.server.web.WebServlet());
+ h2ConsoleServlet.addMapping("/h2-console/*");
+ h2ConsoleServlet.setInitParameter("-properties", "src/main/resources/");
+ h2ConsoleServlet.setLoadOnStartup(1);
+ }
+
+ @Autowired(required = false)
+ public void setMetricRegistry(MetricRegistry metricRegistry) {
+ this.metricRegistry = metricRegistry;
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/audit/AuditEventConverter.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/audit/AuditEventConverter.java
new file mode 100644
index 0000000000..6e04a2556f
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/audit/AuditEventConverter.java
@@ -0,0 +1,91 @@
+package com.dealer.app.config.audit;
+
+import com.dealer.app.domain.PersistentAuditEvent;
+
+import org.springframework.boot.actuate.audit.AuditEvent;
+import org.springframework.security.web.authentication.WebAuthenticationDetails;
+import org.springframework.stereotype.Component;
+
+import java.time.Instant;
+import java.time.ZoneId;
+import java.util.*;
+
+@Component
+public class AuditEventConverter {
+
+ /**
+ * Convert a list of PersistentAuditEvent to a list of AuditEvent
+ *
+ * @param persistentAuditEvents the list to convert
+ * @return the converted list.
+ */
+ public List convertToAuditEvent(Iterable persistentAuditEvents) {
+ if (persistentAuditEvents == null) {
+ return Collections.emptyList();
+ }
+ List auditEvents = new ArrayList<>();
+ for (PersistentAuditEvent persistentAuditEvent : persistentAuditEvents) {
+ auditEvents.add(convertToAuditEvent(persistentAuditEvent));
+ }
+ return auditEvents;
+ }
+
+ /**
+ * Convert a PersistentAuditEvent to an AuditEvent
+ *
+ * @param persistentAuditEvent the event to convert
+ * @return the converted list.
+ */
+ public AuditEvent convertToAuditEvent(PersistentAuditEvent persistentAuditEvent) {
+ Instant instant = persistentAuditEvent.getAuditEventDate().atZone(ZoneId.systemDefault()).toInstant();
+ return new AuditEvent(Date.from(instant), persistentAuditEvent.getPrincipal(),
+ persistentAuditEvent.getAuditEventType(), convertDataToObjects(persistentAuditEvent.getData()));
+ }
+
+ /**
+ * Internal conversion. This is needed to support the current SpringBoot actuator AuditEventRepository interface
+ *
+ * @param data the data to convert
+ * @return a map of String, Object
+ */
+ public Map convertDataToObjects(Map data) {
+ Map results = new HashMap<>();
+
+ if (data != null) {
+ for (Map.Entry entry : data.entrySet()) {
+ results.put(entry.getKey(), entry.getValue());
+ }
+ }
+ return results;
+ }
+
+ /**
+ * Internal conversion. This method will allow to save additional data.
+ * By default, it will save the object as string
+ *
+ * @param data the data to convert
+ * @return a map of String, String
+ */
+ public Map convertDataToStrings(Map data) {
+ Map results = new HashMap<>();
+
+ if (data != null) {
+ for (Map.Entry entry : data.entrySet()) {
+ Object object = entry.getValue();
+
+ // Extract the data that will be saved.
+ if (object instanceof WebAuthenticationDetails) {
+ WebAuthenticationDetails authenticationDetails = (WebAuthenticationDetails) object;
+ results.put("remoteAddress", authenticationDetails.getRemoteAddress());
+ results.put("sessionId", authenticationDetails.getSessionId());
+ } else if (object != null) {
+ results.put(entry.getKey(), object.toString());
+ } else {
+ results.put(entry.getKey(), "null");
+ }
+ }
+ }
+
+ return results;
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/audit/package-info.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/audit/package-info.java
new file mode 100644
index 0000000000..fb44326371
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/audit/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Audit specific code.
+ */
+package com.dealer.app.config.audit;
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/package-info.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/package-info.java
new file mode 100644
index 0000000000..bb4cb44cbf
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/config/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Spring Framework configuration files.
+ */
+package com.dealer.app.config;
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/domain/AbstractAuditingEntity.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/domain/AbstractAuditingEntity.java
new file mode 100644
index 0000000000..1bfb1025cc
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/domain/AbstractAuditingEntity.java
@@ -0,0 +1,80 @@
+package com.dealer.app.domain;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.hibernate.envers.Audited;
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedBy;
+import org.springframework.data.annotation.LastModifiedDate;
+
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+import java.time.ZonedDateTime;
+import javax.persistence.Column;
+import javax.persistence.EntityListeners;
+import javax.persistence.MappedSuperclass;
+
+/**
+ * Base abstract class for entities which will hold definitions for created, last modified by and created,
+ * last modified by date.
+ */
+@MappedSuperclass
+@Audited
+@EntityListeners(AuditingEntityListener.class)
+public abstract class AbstractAuditingEntity implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @CreatedBy
+ @Column(name = "created_by", nullable = false, length = 50, updatable = false)
+ @JsonIgnore
+ private String createdBy;
+
+ @CreatedDate
+ @Column(name = "created_date", nullable = false)
+ @JsonIgnore
+ private ZonedDateTime createdDate = ZonedDateTime.now();
+
+ @LastModifiedBy
+ @Column(name = "last_modified_by", length = 50)
+ @JsonIgnore
+ private String lastModifiedBy;
+
+ @LastModifiedDate
+ @Column(name = "last_modified_date")
+ @JsonIgnore
+ private ZonedDateTime lastModifiedDate = ZonedDateTime.now();
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public ZonedDateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ public void setCreatedDate(ZonedDateTime createdDate) {
+ this.createdDate = createdDate;
+ }
+
+ public String getLastModifiedBy() {
+ return lastModifiedBy;
+ }
+
+ public void setLastModifiedBy(String lastModifiedBy) {
+ this.lastModifiedBy = lastModifiedBy;
+ }
+
+ public ZonedDateTime getLastModifiedDate() {
+ return lastModifiedDate;
+ }
+
+ public void setLastModifiedDate(ZonedDateTime lastModifiedDate) {
+ this.lastModifiedDate = lastModifiedDate;
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/domain/Dealer.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/domain/Dealer.java
new file mode 100644
index 0000000000..10c967a093
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/domain/Dealer.java
@@ -0,0 +1,92 @@
+package com.dealer.app.domain;
+
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * A Dealer.
+ */
+@Entity
+@Table(name = "dealer")
+@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
+public class Dealer implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(name = "name")
+ private String name;
+
+ @Column(name = "address")
+ private String address;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Dealer name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public Dealer address(String address) {
+ this.address = address;
+ return this;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Dealer dealer = (Dealer) o;
+ if (dealer.id == null || id == null) {
+ return false;
+ }
+ return Objects.equals(id, dealer.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(id);
+ }
+
+ @Override
+ public String toString() {
+ return "Dealer{" +
+ "id=" + id +
+ ", name='" + name + "'" +
+ ", address='" + address + "'" +
+ '}';
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/domain/PersistentAuditEvent.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/domain/PersistentAuditEvent.java
new file mode 100644
index 0000000000..a5c02428a5
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/domain/PersistentAuditEvent.java
@@ -0,0 +1,78 @@
+package com.dealer.app.domain;
+
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import javax.persistence.*;
+import javax.validation.constraints.NotNull;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Persist AuditEvent managed by the Spring Boot actuator
+ * @see org.springframework.boot.actuate.audit.AuditEvent
+ */
+@Entity
+@Table(name = "jhi_persistent_audit_event")
+public class PersistentAuditEvent implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "event_id")
+ private Long id;
+
+ @NotNull
+ @Column(nullable = false)
+ private String principal;
+
+ @Column(name = "event_date")
+ private LocalDateTime auditEventDate;
+ @Column(name = "event_type")
+ private String auditEventType;
+
+ @ElementCollection
+ @MapKeyColumn(name = "name")
+ @Column(name = "value")
+ @CollectionTable(name = "jhi_persistent_audit_evt_data", joinColumns=@JoinColumn(name="event_id"))
+ private Map data = new HashMap<>();
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getPrincipal() {
+ return principal;
+ }
+
+ public void setPrincipal(String principal) {
+ this.principal = principal;
+ }
+
+ public LocalDateTime getAuditEventDate() {
+ return auditEventDate;
+ }
+
+ public void setAuditEventDate(LocalDateTime auditEventDate) {
+ this.auditEventDate = auditEventDate;
+ }
+
+ public String getAuditEventType() {
+ return auditEventType;
+ }
+
+ public void setAuditEventType(String auditEventType) {
+ this.auditEventType = auditEventType;
+ }
+
+ public Map getData() {
+ return data;
+ }
+
+ public void setData(Map data) {
+ this.data = data;
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/domain/package-info.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/domain/package-info.java
new file mode 100644
index 0000000000..0651edd7cc
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/domain/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * JPA domain objects.
+ */
+package com.dealer.app.domain;
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/repository/DealerRepository.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/repository/DealerRepository.java
new file mode 100644
index 0000000000..ff77d228a9
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/repository/DealerRepository.java
@@ -0,0 +1,15 @@
+package com.dealer.app.repository;
+
+import com.dealer.app.domain.Dealer;
+
+import org.springframework.data.jpa.repository.*;
+
+import java.util.List;
+
+/**
+ * Spring Data JPA repository for the Dealer entity.
+ */
+@SuppressWarnings("unused")
+public interface DealerRepository extends JpaRepository {
+
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/repository/package-info.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/repository/package-info.java
new file mode 100644
index 0000000000..93be9f265d
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/repository/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Spring Data JPA repositories.
+ */
+package com.dealer.app.repository;
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/AuthoritiesConstants.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/AuthoritiesConstants.java
new file mode 100644
index 0000000000..c4ade99d0e
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/AuthoritiesConstants.java
@@ -0,0 +1,16 @@
+package com.dealer.app.security;
+
+/**
+ * Constants for Spring Security authorities.
+ */
+public final class AuthoritiesConstants {
+
+ public static final String ADMIN = "ROLE_ADMIN";
+
+ public static final String USER = "ROLE_USER";
+
+ public static final String ANONYMOUS = "ROLE_ANONYMOUS";
+
+ private AuthoritiesConstants() {
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/SecurityUtils.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/SecurityUtils.java
new file mode 100644
index 0000000000..1b3c1e5c90
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/SecurityUtils.java
@@ -0,0 +1,68 @@
+package com.dealer.app.security;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+
+/**
+ * Utility class for Spring Security.
+ */
+public final class SecurityUtils {
+
+ private SecurityUtils() {
+ }
+
+ /**
+ * Get the login of the current user.
+ *
+ * @return the login of the current user
+ */
+ public static String getCurrentUserLogin() {
+ SecurityContext securityContext = SecurityContextHolder.getContext();
+ Authentication authentication = securityContext.getAuthentication();
+ String userName = null;
+ if (authentication != null) {
+ if (authentication.getPrincipal() instanceof UserDetails) {
+ UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
+ userName = springSecurityUser.getUsername();
+ } else if (authentication.getPrincipal() instanceof String) {
+ userName = (String) authentication.getPrincipal();
+ }
+ }
+ return userName;
+ }
+
+ /**
+ * Check if a user is authenticated.
+ *
+ * @return true if the user is authenticated, false otherwise
+ */
+ public static boolean isAuthenticated() {
+ SecurityContext securityContext = SecurityContextHolder.getContext();
+ Authentication authentication = securityContext.getAuthentication();
+ if (authentication != null) {
+ return authentication.getAuthorities().stream()
+ .noneMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(AuthoritiesConstants.ANONYMOUS));
+ }
+ return false;
+ }
+
+ /**
+ * If the current user has a specific authority (security role).
+ *
+ * The name of this method comes from the isUserInRole() method in the Servlet API
+ *
+ * @param authority the authority to check
+ * @return true if the current user has the authority, false otherwise
+ */
+ public static boolean isCurrentUserInRole(String authority) {
+ SecurityContext securityContext = SecurityContextHolder.getContext();
+ Authentication authentication = securityContext.getAuthentication();
+ if (authentication != null) {
+ return authentication.getAuthorities().stream()
+ .anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(authority));
+ }
+ return false;
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/SpringSecurityAuditorAware.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/SpringSecurityAuditorAware.java
new file mode 100644
index 0000000000..72e518b1bc
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/SpringSecurityAuditorAware.java
@@ -0,0 +1,19 @@
+package com.dealer.app.security;
+
+import com.dealer.app.config.Constants;
+
+import org.springframework.data.domain.AuditorAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * Implementation of AuditorAware based on Spring Security.
+ */
+@Component
+public class SpringSecurityAuditorAware implements AuditorAware {
+
+ @Override
+ public String getCurrentAuditor() {
+ String userName = SecurityUtils.getCurrentUserLogin();
+ return userName != null ? userName : Constants.SYSTEM_ACCOUNT;
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/jwt/JWTConfigurer.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/jwt/JWTConfigurer.java
new file mode 100644
index 0000000000..0f7b3cf164
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/jwt/JWTConfigurer.java
@@ -0,0 +1,23 @@
+package com.dealer.app.security.jwt;
+
+import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.web.DefaultSecurityFilterChain;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+public class JWTConfigurer extends SecurityConfigurerAdapter {
+
+ public static final String AUTHORIZATION_HEADER = "Authorization";
+
+ private TokenProvider tokenProvider;
+
+ public JWTConfigurer(TokenProvider tokenProvider) {
+ this.tokenProvider = tokenProvider;
+ }
+
+ @Override
+ public void configure(HttpSecurity http) throws Exception {
+ JWTFilter customFilter = new JWTFilter(tokenProvider);
+ http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/jwt/JWTFilter.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/jwt/JWTFilter.java
new file mode 100644
index 0000000000..55e22bd10a
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/jwt/JWTFilter.java
@@ -0,0 +1,58 @@
+package com.dealer.app.security.jwt;
+
+import java.io.IOException;
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.util.StringUtils;
+import org.springframework.web.filter.GenericFilterBean;
+
+import io.jsonwebtoken.ExpiredJwtException;
+
+/**
+ * Filters incoming requests and installs a Spring Security principal if a header corresponding to a valid user is
+ * found.
+ */
+public class JWTFilter extends GenericFilterBean {
+
+ private final Logger log = LoggerFactory.getLogger(JWTFilter.class);
+
+ private TokenProvider tokenProvider;
+
+ public JWTFilter(TokenProvider tokenProvider) {
+ this.tokenProvider = tokenProvider;
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+ throws IOException, ServletException {
+ try {
+ HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
+ String jwt = resolveToken(httpServletRequest);
+ if (StringUtils.hasText(jwt) && this.tokenProvider.validateToken(jwt)) {
+ Authentication authentication = this.tokenProvider.getAuthentication(jwt);
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ }
+ filterChain.doFilter(servletRequest, servletResponse);
+ } catch (ExpiredJwtException eje) {
+ log.info("Security exception for user {} - {}",
+ eje.getClaims().getSubject(), eje.getMessage());
+
+ log.trace("Security exception trace: {}", eje);
+ ((HttpServletResponse) servletResponse).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ }
+ }
+
+ private String resolveToken(HttpServletRequest request){
+ String bearerToken = request.getHeader(JWTConfigurer.AUTHORIZATION_HEADER);
+ if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
+ return bearerToken.substring(7, bearerToken.length());
+ }
+ return null;
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/jwt/TokenProvider.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/jwt/TokenProvider.java
new file mode 100644
index 0000000000..47a5bf75af
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/jwt/TokenProvider.java
@@ -0,0 +1,109 @@
+package com.dealer.app.security.jwt;
+
+import io.github.jhipster.config.JHipsterProperties;
+
+import java.util.*;
+import java.util.stream.Collectors;
+import javax.annotation.PostConstruct;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.stereotype.Component;
+
+import io.jsonwebtoken.*;
+
+@Component
+public class TokenProvider {
+
+ private final Logger log = LoggerFactory.getLogger(TokenProvider.class);
+
+ private static final String AUTHORITIES_KEY = "auth";
+
+ private String secretKey;
+
+ private long tokenValidityInMilliseconds;
+
+ private long tokenValidityInMillisecondsForRememberMe;
+
+ private final JHipsterProperties jHipsterProperties;
+
+ public TokenProvider(JHipsterProperties jHipsterProperties) {
+ this.jHipsterProperties = jHipsterProperties;
+ }
+
+ @PostConstruct
+ public void init() {
+ this.secretKey =
+ jHipsterProperties.getSecurity().getAuthentication().getJwt().getSecret();
+
+ this.tokenValidityInMilliseconds =
+ 1000 * jHipsterProperties.getSecurity().getAuthentication().getJwt().getTokenValidityInSeconds();
+ this.tokenValidityInMillisecondsForRememberMe =
+ 1000 * jHipsterProperties.getSecurity().getAuthentication().getJwt().getTokenValidityInSecondsForRememberMe();
+ }
+
+ public String createToken(Authentication authentication, Boolean rememberMe) {
+ String authorities = authentication.getAuthorities().stream()
+ .map(GrantedAuthority::getAuthority)
+ .collect(Collectors.joining(","));
+
+ long now = (new Date()).getTime();
+ Date validity;
+ if (rememberMe) {
+ validity = new Date(now + this.tokenValidityInMillisecondsForRememberMe);
+ } else {
+ validity = new Date(now + this.tokenValidityInMilliseconds);
+ }
+
+ return Jwts.builder()
+ .setSubject(authentication.getName())
+ .claim(AUTHORITIES_KEY, authorities)
+ .signWith(SignatureAlgorithm.HS512, secretKey)
+ .setExpiration(validity)
+ .compact();
+ }
+
+ public Authentication getAuthentication(String token) {
+ Claims claims = Jwts.parser()
+ .setSigningKey(secretKey)
+ .parseClaimsJws(token)
+ .getBody();
+
+ Collection extends GrantedAuthority> authorities =
+ Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(","))
+ .map(SimpleGrantedAuthority::new)
+ .collect(Collectors.toList());
+
+ User principal = new User(claims.getSubject(), "", authorities);
+
+ return new UsernamePasswordAuthenticationToken(principal, "", authorities);
+ }
+
+ public boolean validateToken(String authToken) {
+ try {
+ Jwts.parser().setSigningKey(secretKey).parseClaimsJws(authToken);
+ return true;
+ } catch (SignatureException e) {
+ log.info("Invalid JWT signature.");
+ log.trace("Invalid JWT signature trace: {}", e);
+ } catch (MalformedJwtException e) {
+ log.info("Invalid JWT token.");
+ log.trace("Invalid JWT token trace: {}", e);
+ } catch (ExpiredJwtException e) {
+ log.info("Expired JWT token.");
+ log.trace("Expired JWT token trace: {}", e);
+ } catch (UnsupportedJwtException e) {
+ log.info("Unsupported JWT token.");
+ log.trace("Unsupported JWT token trace: {}", e);
+ } catch (IllegalArgumentException e) {
+ log.info("JWT token compact of handler are invalid.");
+ log.trace("JWT token compact of handler are invalid trace: {}", e);
+ }
+ return false;
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/service/package-info.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/service/package-info.java
new file mode 100644
index 0000000000..b6795f34a3
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/service/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Service layer beans.
+ */
+package com.dealer.app.service;
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/DealerResource.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/DealerResource.java
new file mode 100644
index 0000000000..bd49b3d179
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/DealerResource.java
@@ -0,0 +1,128 @@
+package com.dealer.app.web.rest;
+
+import com.codahale.metrics.annotation.Timed;
+import com.dealer.app.domain.Dealer;
+
+import com.dealer.app.repository.DealerRepository;
+import com.dealer.app.web.rest.util.HeaderUtil;
+import com.dealer.app.web.rest.util.PaginationUtil;
+import io.swagger.annotations.ApiParam;
+import io.github.jhipster.web.util.ResponseUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * REST controller for managing Dealer.
+ */
+@RestController
+@RequestMapping("/api")
+public class DealerResource {
+
+ private final Logger log = LoggerFactory.getLogger(DealerResource.class);
+
+ private static final String ENTITY_NAME = "dealer";
+
+ private final DealerRepository dealerRepository;
+
+ public DealerResource(DealerRepository dealerRepository) {
+ this.dealerRepository = dealerRepository;
+ }
+
+ /**
+ * POST /dealers : Create a new dealer.
+ *
+ * @param dealer the dealer to create
+ * @return the ResponseEntity with status 201 (Created) and with body the new dealer, or with status 400 (Bad Request) if the dealer has already an ID
+ * @throws URISyntaxException if the Location URI syntax is incorrect
+ */
+ @PostMapping("/dealers")
+ @Timed
+ public ResponseEntity createDealer(@RequestBody Dealer dealer) throws URISyntaxException {
+ log.debug("REST request to save Dealer : {}", dealer);
+ if (dealer.getId() != null) {
+ return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(ENTITY_NAME, "idexists", "A new dealer cannot already have an ID")).body(null);
+ }
+ Dealer result = dealerRepository.save(dealer);
+ return ResponseEntity.created(new URI("/api/dealers/" + result.getId()))
+ .headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString()))
+ .body(result);
+ }
+
+ /**
+ * PUT /dealers : Updates an existing dealer.
+ *
+ * @param dealer the dealer to update
+ * @return the ResponseEntity with status 200 (OK) and with body the updated dealer,
+ * or with status 400 (Bad Request) if the dealer is not valid,
+ * or with status 500 (Internal Server Error) if the dealer couldnt be updated
+ * @throws URISyntaxException if the Location URI syntax is incorrect
+ */
+ @PutMapping("/dealers")
+ @Timed
+ public ResponseEntity updateDealer(@RequestBody Dealer dealer) throws URISyntaxException {
+ log.debug("REST request to update Dealer : {}", dealer);
+ if (dealer.getId() == null) {
+ return createDealer(dealer);
+ }
+ Dealer result = dealerRepository.save(dealer);
+ return ResponseEntity.ok()
+ .headers(HeaderUtil.createEntityUpdateAlert(ENTITY_NAME, dealer.getId().toString()))
+ .body(result);
+ }
+
+ /**
+ * GET /dealers : get all the dealers.
+ *
+ * @param pageable the pagination information
+ * @return the ResponseEntity with status 200 (OK) and the list of dealers in body
+ * @throws URISyntaxException if there is an error to generate the pagination HTTP headers
+ */
+ @GetMapping("/dealers")
+ @Timed
+ public ResponseEntity> getAllDealers(@ApiParam Pageable pageable) {
+ log.debug("REST request to get a page of Dealers");
+ Page page = dealerRepository.findAll(pageable);
+ HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/dealers");
+ return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
+ }
+
+ /**
+ * GET /dealers/:id : get the "id" dealer.
+ *
+ * @param id the id of the dealer to retrieve
+ * @return the ResponseEntity with status 200 (OK) and with body the dealer, or with status 404 (Not Found)
+ */
+ @GetMapping("/dealers/{id}")
+ @Timed
+ public ResponseEntity getDealer(@PathVariable Long id) {
+ log.debug("REST request to get Dealer : {}", id);
+ Dealer dealer = dealerRepository.findOne(id);
+ return ResponseUtil.wrapOrNotFound(Optional.ofNullable(dealer));
+ }
+
+ /**
+ * DELETE /dealers/:id : delete the "id" dealer.
+ *
+ * @param id the id of the dealer to delete
+ * @return the ResponseEntity with status 200 (OK)
+ */
+ @DeleteMapping("/dealers/{id}")
+ @Timed
+ public ResponseEntity deleteDealer(@PathVariable Long id) {
+ log.debug("REST request to delete Dealer : {}", id);
+ dealerRepository.delete(id);
+ return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert(ENTITY_NAME, id.toString())).build();
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/LogsResource.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/LogsResource.java
new file mode 100644
index 0000000000..844fdfe7bb
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/LogsResource.java
@@ -0,0 +1,39 @@
+package com.dealer.app.web.rest;
+
+import com.dealer.app.web.rest.vm.LoggerVM;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.LoggerContext;
+import com.codahale.metrics.annotation.Timed;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Controller for view and managing Log Level at runtime.
+ */
+@RestController
+@RequestMapping("/management")
+public class LogsResource {
+
+ @GetMapping("/logs")
+ @Timed
+ public List getList() {
+ LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+ return context.getLoggerList()
+ .stream()
+ .map(LoggerVM::new)
+ .collect(Collectors.toList());
+ }
+
+ @PutMapping("/logs")
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ @Timed
+ public void changeLevel(@RequestBody LoggerVM jsonLogger) {
+ LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+ context.getLogger(jsonLogger.getName()).setLevel(Level.valueOf(jsonLogger.getLevel()));
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/ProfileInfoResource.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/ProfileInfoResource.java
new file mode 100644
index 0000000000..4c2d37b3ff
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/ProfileInfoResource.java
@@ -0,0 +1,69 @@
+package com.dealer.app.web.rest;
+
+import com.dealer.app.config.DefaultProfileUtil;
+
+import io.github.jhipster.config.JHipsterProperties;
+
+import org.springframework.core.env.Environment;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Resource to return information about the currently running Spring profiles.
+ */
+@RestController
+@RequestMapping("/api")
+public class ProfileInfoResource {
+
+ private final Environment env;
+
+ private final JHipsterProperties jHipsterProperties;
+
+ public ProfileInfoResource(Environment env, JHipsterProperties jHipsterProperties) {
+ this.env = env;
+ this.jHipsterProperties = jHipsterProperties;
+ }
+
+ @GetMapping("/profile-info")
+ public ProfileInfoVM getActiveProfiles() {
+ String[] activeProfiles = DefaultProfileUtil.getActiveProfiles(env);
+ return new ProfileInfoVM(activeProfiles, getRibbonEnv(activeProfiles));
+ }
+
+ private String getRibbonEnv(String[] activeProfiles) {
+ String[] displayOnActiveProfiles = jHipsterProperties.getRibbon().getDisplayOnActiveProfiles();
+ if (displayOnActiveProfiles == null) {
+ return null;
+ }
+ List ribbonProfiles = new ArrayList<>(Arrays.asList(displayOnActiveProfiles));
+ List springBootProfiles = Arrays.asList(activeProfiles);
+ ribbonProfiles.retainAll(springBootProfiles);
+ if (!ribbonProfiles.isEmpty()) {
+ return ribbonProfiles.get(0);
+ }
+ return null;
+ }
+
+ class ProfileInfoVM {
+
+ private String[] activeProfiles;
+
+ private String ribbonEnv;
+
+ ProfileInfoVM(String[] activeProfiles, String ribbonEnv) {
+ this.activeProfiles = activeProfiles;
+ this.ribbonEnv = ribbonEnv;
+ }
+
+ public String[] getActiveProfiles() {
+ return activeProfiles;
+ }
+
+ public String getRibbonEnv() {
+ return ribbonEnv;
+ }
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/CustomParameterizedException.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/CustomParameterizedException.java
new file mode 100644
index 0000000000..3897d94eba
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/CustomParameterizedException.java
@@ -0,0 +1,34 @@
+package com.dealer.app.web.rest.errors;
+
+/**
+ * Custom, parameterized exception, which can be translated on the client side.
+ * For example:
+ *
+ *
+ * throw new CustomParameterizedException("myCustomError", "hello", "world");
+ *
+ *
+ * Can be translated with:
+ *
+ *
+ * "error.myCustomError" : "The server says {{params[0]}} to {{params[1]}}"
+ *
+ */
+public class CustomParameterizedException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String message;
+ private final String[] params;
+
+ public CustomParameterizedException(String message, String... params) {
+ super(message);
+ this.message = message;
+ this.params = params;
+ }
+
+ public ParameterizedErrorVM getErrorVM() {
+ return new ParameterizedErrorVM(message, params);
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/ErrorConstants.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/ErrorConstants.java
new file mode 100644
index 0000000000..4ace18012e
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/ErrorConstants.java
@@ -0,0 +1,14 @@
+package com.dealer.app.web.rest.errors;
+
+public final class ErrorConstants {
+
+ public static final String ERR_CONCURRENCY_FAILURE = "error.concurrencyFailure";
+ public static final String ERR_ACCESS_DENIED = "error.accessDenied";
+ public static final String ERR_VALIDATION = "error.validation";
+ public static final String ERR_METHOD_NOT_SUPPORTED = "error.methodNotSupported";
+ public static final String ERR_INTERNAL_SERVER_ERROR = "error.internalServerError";
+
+ private ErrorConstants() {
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/ErrorVM.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/ErrorVM.java
new file mode 100644
index 0000000000..4f242f21e8
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/ErrorVM.java
@@ -0,0 +1,52 @@
+package com.dealer.app.web.rest.errors;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * View Model for transferring error message with a list of field errors.
+ */
+public class ErrorVM implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String message;
+ private final String description;
+
+ private List fieldErrors;
+
+ public ErrorVM(String message) {
+ this(message, null);
+ }
+
+ public ErrorVM(String message, String description) {
+ this.message = message;
+ this.description = description;
+ }
+
+ public ErrorVM(String message, String description, List fieldErrors) {
+ this.message = message;
+ this.description = description;
+ this.fieldErrors = fieldErrors;
+ }
+
+ public void add(String objectName, String field, String message) {
+ if (fieldErrors == null) {
+ fieldErrors = new ArrayList<>();
+ }
+ fieldErrors.add(new FieldErrorVM(objectName, field, message));
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public List getFieldErrors() {
+ return fieldErrors;
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/ExceptionTranslator.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/ExceptionTranslator.java
new file mode 100644
index 0000000000..17b1dc6c62
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/ExceptionTranslator.java
@@ -0,0 +1,85 @@
+package com.dealer.app.web.rest.errors;
+
+import java.util.List;
+
+import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.dao.ConcurrencyFailureException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.ResponseEntity.BodyBuilder;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.FieldError;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * Controller advice to translate the server side exceptions to client-friendly json structures.
+ */
+@ControllerAdvice
+public class ExceptionTranslator {
+
+ @ExceptionHandler(ConcurrencyFailureException.class)
+ @ResponseStatus(HttpStatus.CONFLICT)
+ @ResponseBody
+ public ErrorVM processConcurrencyError(ConcurrencyFailureException ex) {
+ return new ErrorVM(ErrorConstants.ERR_CONCURRENCY_FAILURE);
+ }
+
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ @ResponseBody
+ public ErrorVM processValidationError(MethodArgumentNotValidException ex) {
+ BindingResult result = ex.getBindingResult();
+ List fieldErrors = result.getFieldErrors();
+
+ return processFieldErrors(fieldErrors);
+ }
+
+ @ExceptionHandler(CustomParameterizedException.class)
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ @ResponseBody
+ public ParameterizedErrorVM processParameterizedValidationError(CustomParameterizedException ex) {
+ return ex.getErrorVM();
+ }
+
+ @ExceptionHandler(AccessDeniedException.class)
+ @ResponseStatus(HttpStatus.FORBIDDEN)
+ @ResponseBody
+ public ErrorVM processAccessDeniedException(AccessDeniedException e) {
+ return new ErrorVM(ErrorConstants.ERR_ACCESS_DENIED, e.getMessage());
+ }
+
+ private ErrorVM processFieldErrors(List fieldErrors) {
+ ErrorVM dto = new ErrorVM(ErrorConstants.ERR_VALIDATION);
+
+ for (FieldError fieldError : fieldErrors) {
+ dto.add(fieldError.getObjectName(), fieldError.getField(), fieldError.getCode());
+ }
+
+ return dto;
+ }
+
+ @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
+ @ResponseBody
+ @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
+ public ErrorVM processMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) {
+ return new ErrorVM(ErrorConstants.ERR_METHOD_NOT_SUPPORTED, exception.getMessage());
+ }
+
+ @ExceptionHandler(Exception.class)
+ public ResponseEntity processRuntimeException(Exception ex) {
+ BodyBuilder builder;
+ ErrorVM errorVM;
+ ResponseStatus responseStatus = AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class);
+ if (responseStatus != null) {
+ builder = ResponseEntity.status(responseStatus.value());
+ errorVM = new ErrorVM("error." + responseStatus.value().value(), responseStatus.reason());
+ } else {
+ builder = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
+ errorVM = new ErrorVM(ErrorConstants.ERR_INTERNAL_SERVER_ERROR, "Internal server error");
+ }
+ return builder.body(errorVM);
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/FieldErrorVM.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/FieldErrorVM.java
new file mode 100644
index 0000000000..036e358f41
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/FieldErrorVM.java
@@ -0,0 +1,33 @@
+package com.dealer.app.web.rest.errors;
+
+import java.io.Serializable;
+
+public class FieldErrorVM implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String objectName;
+
+ private final String field;
+
+ private final String message;
+
+ public FieldErrorVM(String dto, String field, String message) {
+ this.objectName = dto;
+ this.field = field;
+ this.message = message;
+ }
+
+ public String getObjectName() {
+ return objectName;
+ }
+
+ public String getField() {
+ return field;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/ParameterizedErrorVM.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/ParameterizedErrorVM.java
new file mode 100644
index 0000000000..7b0d4f23fa
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/errors/ParameterizedErrorVM.java
@@ -0,0 +1,27 @@
+package com.dealer.app.web.rest.errors;
+
+import java.io.Serializable;
+
+/**
+ * View Model for sending a parameterized error message.
+ */
+public class ParameterizedErrorVM implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private final String message;
+ private final String[] params;
+
+ public ParameterizedErrorVM(String message, String... params) {
+ this.message = message;
+ this.params = params;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String[] getParams() {
+ return params;
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/package-info.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/package-info.java
new file mode 100644
index 0000000000..20c6b71ccc
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Spring MVC REST controllers.
+ */
+package com.dealer.app.web.rest;
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/util/HeaderUtil.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/util/HeaderUtil.java
new file mode 100644
index 0000000000..63efc36663
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/util/HeaderUtil.java
@@ -0,0 +1,43 @@
+package com.dealer.app.web.rest.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpHeaders;
+
+/**
+ * Utility class for HTTP headers creation.
+ */
+public final class HeaderUtil {
+
+ private static final Logger log = LoggerFactory.getLogger(HeaderUtil.class);
+
+ private HeaderUtil() {
+ }
+
+ public static HttpHeaders createAlert(String message, String param) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("X-dealerappApp-alert", message);
+ headers.add("X-dealerappApp-params", param);
+ return headers;
+ }
+
+ public static HttpHeaders createEntityCreationAlert(String entityName, String param) {
+ return createAlert("A new " + entityName + " is created with identifier " + param, param);
+ }
+
+ public static HttpHeaders createEntityUpdateAlert(String entityName, String param) {
+ return createAlert("A " + entityName + " is updated with identifier " + param, param);
+ }
+
+ public static HttpHeaders createEntityDeletionAlert(String entityName, String param) {
+ return createAlert("A " + entityName + " is deleted with identifier " + param, param);
+ }
+
+ public static HttpHeaders createFailureAlert(String entityName, String errorKey, String defaultMessage) {
+ log.error("Entity creation failed, {}", defaultMessage);
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("X-dealerappApp-error", defaultMessage);
+ headers.add("X-dealerappApp-params", entityName);
+ return headers;
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/util/PaginationUtil.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/util/PaginationUtil.java
new file mode 100644
index 0000000000..39b7eae434
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/util/PaginationUtil.java
@@ -0,0 +1,47 @@
+package com.dealer.app.web.rest.util;
+
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpHeaders;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.net.URISyntaxException;
+
+/**
+ * Utility class for handling pagination.
+ *
+ *
+ * Pagination uses the same principles as the Github API,
+ * and follow RFC 5988 (Link header).
+ */
+public final class PaginationUtil {
+
+ private PaginationUtil() {
+ }
+
+ public static HttpHeaders generatePaginationHttpHeaders(Page page, String baseUrl) {
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("X-Total-Count", "" + Long.toString(page.getTotalElements()));
+ String link = "";
+ if ((page.getNumber() + 1) < page.getTotalPages()) {
+ link = "<" + generateUri(baseUrl, page.getNumber() + 1, page.getSize()) + ">; rel=\"next\",";
+ }
+ // prev link
+ if ((page.getNumber()) > 0) {
+ link += "<" + generateUri(baseUrl, page.getNumber() - 1, page.getSize()) + ">; rel=\"prev\",";
+ }
+ // last and first link
+ int lastPage = 0;
+ if (page.getTotalPages() > 0) {
+ lastPage = page.getTotalPages() - 1;
+ }
+ link += "<" + generateUri(baseUrl, lastPage, page.getSize()) + ">; rel=\"last\",";
+ link += "<" + generateUri(baseUrl, 0, page.getSize()) + ">; rel=\"first\"";
+ headers.add(HttpHeaders.LINK, link);
+ return headers;
+ }
+
+ private static String generateUri(String baseUrl, int page, int size) {
+ return UriComponentsBuilder.fromUriString(baseUrl).queryParam("page", page).queryParam("size", size).toUriString();
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/vm/LoggerVM.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/vm/LoggerVM.java
new file mode 100644
index 0000000000..82afc8c883
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/vm/LoggerVM.java
@@ -0,0 +1,48 @@
+package com.dealer.app.web.rest.vm;
+
+import ch.qos.logback.classic.Logger;
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+/**
+ * View Model object for storing a Logback logger.
+ */
+public class LoggerVM {
+
+ private String name;
+
+ private String level;
+
+ public LoggerVM(Logger logger) {
+ this.name = logger.getName();
+ this.level = logger.getEffectiveLevel().toString();
+ }
+
+ @JsonCreator
+ public LoggerVM() {
+ // Empty public constructor used by Jackson.
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLevel() {
+ return level;
+ }
+
+ public void setLevel(String level) {
+ this.level = level;
+ }
+
+ @Override
+ public String toString() {
+ return "LoggerVM{" +
+ "name='" + name + '\'' +
+ ", level='" + level + '\'' +
+ '}';
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/vm/package-info.java b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/vm/package-info.java
new file mode 100644
index 0000000000..563901498e
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/web/rest/vm/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * View Models used by Spring MVC REST controllers.
+ */
+package com.dealer.app.web.rest.vm;
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/resources/.h2.server.properties b/jhipster/jhipster-microservice/dealer-app/src/main/resources/.h2.server.properties
new file mode 100644
index 0000000000..8d8f192ac0
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/resources/.h2.server.properties
@@ -0,0 +1,5 @@
+#H2 Server Properties
+0=JHipster H2 (Disk)|org.h2.Driver|jdbc\:h2\:file\:./target/h2db/db/dealerapp|dealerapp
+webAllowOthers=true
+webPort=8082
+webSSL=false
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/resources/banner.txt b/jhipster/jhipster-microservice/dealer-app/src/main/resources/banner.txt
new file mode 100644
index 0000000000..c3d8cf725d
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/resources/banner.txt
@@ -0,0 +1,10 @@
+
+ ${AnsiColor.GREEN} ██╗${AnsiColor.RED} ██╗ ██╗ ████████╗ ███████╗ ██████╗ ████████╗ ████████╗ ███████╗
+ ${AnsiColor.GREEN} ██║${AnsiColor.RED} ██║ ██║ ╚â•â•██╔â•â•╠██╔â•â•â•██╗ ██╔â•â•â•â•╠╚â•â•██╔â•â•╠██╔â•â•â•â•â•╠██╔â•â•â•██╗
+ ${AnsiColor.GREEN} ██║${AnsiColor.RED} ████████║ ██║ ███████╔╠╚█████╗ ██║ ██████╗ ███████╔â•
+ ${AnsiColor.GREEN}██╗ ██║${AnsiColor.RED} ██╔â•â•â•██║ ██║ ██╔â•â•â•â•╠╚â•â•â•██╗ ██║ ██╔â•â•â•╠██╔â•â•██║
+ ${AnsiColor.GREEN}╚██████╔â•${AnsiColor.RED} ██║ ██║ ████████╗ ██║ ██████╔╠██║ ████████╗ ██║ ╚██╗
+ ${AnsiColor.GREEN} ╚â•â•â•â•â•â• ${AnsiColor.RED} ╚â•╠╚â•╠╚â•â•â•â•â•â•â•╠╚â•╠╚â•â•â•â•â•╠╚â•╠╚â•â•â•â•â•â•â•╠╚â•╠╚â•â•
+
+${AnsiColor.BRIGHT_BLUE}:: JHipster 🤓 :: Running Spring Boot ${spring-boot.version} ::
+:: http://jhipster.github.io ::${AnsiColor.DEFAULT}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/application-dev.yml b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/application-dev.yml
new file mode 100644
index 0000000000..7231a7cfa9
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/application-dev.yml
@@ -0,0 +1,148 @@
+# ===================================================================
+# Spring Boot configuration for the "dev" profile.
+#
+# This configuration overrides the application.yml file.
+#
+# More information on profiles: https://jhipster.github.io/profiles/
+# More information on configuration properties: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+# ===================================================================
+# Standard Spring Boot properties.
+# Full reference is available at:
+# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
+# ===================================================================
+
+eureka:
+ instance:
+ prefer-ip-address: true
+ client:
+ enabled: true
+ healthcheck:
+ enabled: true
+ registerWithEureka: true
+ fetchRegistry: true
+ serviceUrl:
+ defaultZone: http://admin:${jhipster.registry.password}@localhost:8761/eureka/
+
+spring:
+ profiles:
+ active: dev
+ include: swagger
+ devtools:
+ restart:
+ enabled: true
+ livereload:
+ enabled: false # we use gulp + BrowserSync for livereload
+ jackson:
+ serialization.indent_output: true
+ datasource:
+ type: com.zaxxer.hikari.HikariDataSource
+ url: jdbc:h2:file:./target/h2db/db/dealerapp;DB_CLOSE_DELAY=-1
+ username: dealerapp
+ password:
+ h2:
+ console:
+ enabled: false
+ jpa:
+ database-platform: io.github.jhipster.domain.util.FixedH2Dialect
+ database: H2
+ show-sql: true
+ properties:
+ hibernate.id.new_generator_mappings: true
+ hibernate.cache.use_second_level_cache: true
+ hibernate.cache.use_query_cache: false
+ hibernate.generate_statistics: true
+ hibernate.cache.region.factory_class: com.hazelcast.hibernate.HazelcastCacheRegionFactory
+ hibernate.cache.hazelcast.instance_name: dealerapp
+ hibernate.cache.use_minimal_puts: true
+ hibernate.cache.hazelcast.use_lite_member: true
+ mail:
+ host: localhost
+ port: 25
+ username:
+ password:
+ messages:
+ cache-seconds: 1
+ thymeleaf:
+ cache: false
+
+liquibase:
+ contexts: dev
+
+# ===================================================================
+# To enable SSL, generate a certificate using:
+# keytool -genkey -alias dealerapp -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
+#
+# You can also use Let's Encrypt:
+# https://maximilian-boehm.com/hp2121/Create-a-Java-Keystore-JKS-from-Let-s-Encrypt-Certificates.htm
+#
+# Then, modify the server.ssl properties so your "server" configuration looks like:
+#
+# server:
+# port: 8443
+# ssl:
+# key-store: keystore.p12
+# key-store-password:
+# keyStoreType: PKCS12
+# keyAlias: dealerapp
+# ===================================================================
+server:
+ port: 8082
+
+# ===================================================================
+# JHipster specific properties
+#
+# Full reference is available at: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+jhipster:
+ http:
+ version: V_1_1 # To use HTTP/2 you will need SSL support (see above the "server.ssl" configuration)
+ cache: # Cache configuration
+ hazelcast: # Hazelcast distributed cache
+ time-to-live-seconds: 3600
+ backup-count: 1
+ security:
+ authentication:
+ jwt:
+ secret: my-secret-token-to-change-in-production
+ # Token is valid 24 hours
+ token-validity-in-seconds: 86400
+ token-validity-in-seconds-for-remember-me: 2592000
+ mail: # specific JHipster mail property, for standard properties see MailProperties
+ from: dealerapp@localhost
+ base-url: http://127.0.0.1:8082
+ metrics: # DropWizard Metrics configuration, used by MetricsConfiguration
+ jmx.enabled: true
+ graphite: # Use the "graphite" Maven profile to have the Graphite dependencies
+ enabled: false
+ host: localhost
+ port: 2003
+ prefix: dealerapp
+ prometheus: # Use the "prometheus" Maven profile to have the Prometheus dependencies
+ enabled: false
+ endpoint: /prometheusMetrics
+ logs: # Reports Dropwizard metrics in the logs
+ enabled: false
+ reportFrequency: 60 # in seconds
+ logging:
+ logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration
+ enabled: false
+ host: localhost
+ port: 5000
+ queue-size: 512
+ spectator-metrics: # Reports Spectator Circuit Breaker metrics in the logs
+ enabled: false
+ # edit spring.metrics.export.delay-millis to set report frequency
+
+# ===================================================================
+# 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://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+application:
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/application-prod.yml b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/application-prod.yml
new file mode 100644
index 0000000000..8c14e671ea
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/application-prod.yml
@@ -0,0 +1,150 @@
+# ===================================================================
+# Spring Boot configuration for the "prod" profile.
+#
+# This configuration overrides the application.yml file.
+#
+# More information on profiles: https://jhipster.github.io/profiles/
+# More information on configuration properties: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+# ===================================================================
+# Standard Spring Boot properties.
+# Full reference is available at:
+# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
+# ===================================================================
+
+eureka:
+ instance:
+ prefer-ip-address: true
+ client:
+ enabled: true
+ healthcheck:
+ enabled: true
+ registerWithEureka: true
+ fetchRegistry: true
+ serviceUrl:
+ defaultZone: http://admin:${jhipster.registry.password}@localhost:8761/eureka/
+
+spring:
+ devtools:
+ restart:
+ enabled: false
+ livereload:
+ enabled: false
+ datasource:
+ type: com.zaxxer.hikari.HikariDataSource
+ url: jdbc:mysql://localhost:3306/dealerapp?useUnicode=true&characterEncoding=utf8&useSSL=false
+ username: root
+ password:
+ hikari:
+ data-source-properties:
+ cachePrepStmts: true
+ prepStmtCacheSize: 250
+ prepStmtCacheSqlLimit: 2048
+ useServerPrepStmts: true
+ jpa:
+ database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
+ database: MYSQL
+ show-sql: false
+ properties:
+ hibernate.id.new_generator_mappings: true
+ hibernate.cache.use_second_level_cache: true
+ hibernate.cache.use_query_cache: false
+ hibernate.generate_statistics: false
+ hibernate.cache.region.factory_class: com.hazelcast.hibernate.HazelcastCacheRegionFactory
+ hibernate.cache.hazelcast.instance_name: dealerapp
+ hibernate.cache.use_minimal_puts: true
+ hibernate.cache.hazelcast.use_lite_member: true
+ mail:
+ host: localhost
+ port: 25
+ username:
+ password:
+ thymeleaf:
+ cache: true
+
+liquibase:
+ contexts: prod
+
+# ===================================================================
+# To enable SSL, generate a certificate using:
+# keytool -genkey -alias dealerapp -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
+#
+# You can also use Let's Encrypt:
+# https://maximilian-boehm.com/hp2121/Create-a-Java-Keystore-JKS-from-Let-s-Encrypt-Certificates.htm
+#
+# Then, modify the server.ssl properties so your "server" configuration looks like:
+#
+# server:
+# port: 443
+# ssl:
+# key-store: keystore.p12
+# key-store-password:
+# keyStoreType: PKCS12
+# keyAlias: dealerapp
+# ===================================================================
+server:
+ port: 8082
+ compression:
+ enabled: true
+ mime-types: text/html,text/xml,text/plain,text/css, application/javascript, application/json
+ min-response-size: 1024
+
+# ===================================================================
+# JHipster specific properties
+#
+# Full reference is available at: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+jhipster:
+ http:
+ version: V_1_1 # To use HTTP/2 you will need SSL support (see above the "server.ssl" configuration)
+ cache: # Used by the CachingHttpHeadersFilter
+ timeToLiveInDays: 1461
+ cache: # Cache configuration
+ hazelcast: # Hazelcast distributed cache
+ time-to-live-seconds: 3600
+ backup-count: 1
+ security:
+ authentication:
+ jwt:
+ secret: d4c73e937677223a85c7fcebae7a6ce0c48c3b01
+ # Token is valid 24 hours
+ token-validity-in-seconds: 86400
+ token-validity-in-seconds-for-remember-me: 2592000
+ mail: # specific JHipster mail property, for standard properties see MailProperties
+ from: dealerapp@localhost
+ base-url: http://my-server-url-to-change # Modify according to your server's URL
+ metrics: # DropWizard Metrics configuration, used by MetricsConfiguration
+ jmx.enabled: true
+ graphite:
+ enabled: false
+ host: localhost
+ port: 2003
+ prefix: dealerapp
+ prometheus:
+ enabled: false
+ endpoint: /prometheusMetrics
+ logs: # Reports Dropwizard metrics in the logs
+ enabled: false
+ reportFrequency: 60 # in seconds
+ logging:
+ logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration
+ enabled: false
+ host: localhost
+ port: 5000
+ queue-size: 512
+ spectator-metrics: # Reports Spectator Circuit Breaker metrics in the logs
+ enabled: false
+ # edit spring.metrics.export.delay-millis to set report frequency
+
+# ===================================================================
+# 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://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+application:
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/application.yml b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/application.yml
new file mode 100644
index 0000000000..8c77dfd2f3
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/application.yml
@@ -0,0 +1,119 @@
+# ===================================================================
+# Spring Boot configuration.
+#
+# This configuration will be overriden by the Spring profile you use,
+# for example application-dev.yml if you use the "dev" profile.
+#
+# More information on profiles: https://jhipster.github.io/profiles/
+# More information on configuration properties: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+# ===================================================================
+# Standard Spring Boot properties.
+# Full reference is available at:
+# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
+# ===================================================================
+
+eureka:
+ instance:
+ appname: dealerapp
+ instanceId: dealerapp:${spring.application.instance_id:${random.value}}
+ statusPageUrlPath: ${management.context-path}/info
+ healthCheckUrlPath: ${management.context-path}/health
+ metadata-map:
+ profile: ${spring.profiles.active}
+ version: ${info.project.version}
+ribbon:
+ eureka:
+ enabled: true
+# See https://github.com/Netflix/Hystrix/wiki/Configuration
+#hystrix:
+# command:
+# default:
+# execution:
+# isolation:
+# thread:
+# timeoutInMilliseconds: 10000
+
+management:
+ security:
+ roles: ADMIN
+ context-path: /management
+ health:
+ mail:
+ enabled: false # When using the MailService, configure an SMTP server and set this to true
+spring:
+ application:
+ name: dealerapp
+ jackson:
+ serialization.write_dates_as_timestamps: false
+ jpa:
+ open-in-view: false
+ hibernate:
+ ddl-auto: none
+ naming:
+ physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
+ implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
+ messages:
+ basename: i18n/messages
+ mvc:
+ favicon:
+ enabled: false
+ thymeleaf:
+ mode: XHTML
+
+security:
+ basic:
+ enabled: false
+
+server:
+ session:
+ cookie:
+ http-only: true
+
+
+# ===================================================================
+# JHipster specific properties
+#
+# Full reference is available at: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+jhipster:
+ async:
+ core-pool-size: 2
+ max-pool-size: 50
+ queue-capacity: 10000
+ # By default CORS is disabled. Uncomment to enable.
+ #cors:
+ #allowed-origins: "*"
+ #allowed-methods: GET, PUT, POST, DELETE, OPTIONS
+ #allowed-headers: "*"
+ #exposed-headers:
+ #allow-credentials: true
+ #max-age: 1800
+ mail:
+ from: dealerapp@localhost
+ swagger:
+ default-include-pattern: /api/.*
+ title: dealerapp API
+ description: dealerapp API documentation
+ version: 0.0.1
+ terms-of-service-url:
+ contact-name:
+ contact-url:
+ contact-email:
+ license:
+ license-url:
+ ribbon:
+ display-on-active-profiles: dev
+
+# ===================================================================
+# 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://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+application:
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/bootstrap-prod.yml b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/bootstrap-prod.yml
new file mode 100644
index 0000000000..5c7ed3cc2c
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/bootstrap-prod.yml
@@ -0,0 +1,22 @@
+# ===================================================================
+# Spring Cloud Config bootstrap configuration for the "prod" profile
+# ===================================================================
+
+spring:
+ cloud:
+ config:
+ fail-fast: true
+ retry:
+ initial-interval: 1000
+ max-interval: 2000
+ max-attempts: 100
+ 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: dealerapp
+ 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 config source git repository
+
+jhipster:
+ registry:
+ password: admin
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/bootstrap.yml b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/bootstrap.yml
new file mode 100644
index 0000000000..c9528d6c90
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/bootstrap.yml
@@ -0,0 +1,30 @@
+# ===================================================================
+# Spring Cloud Config bootstrap configuration for the "dev" profile
+# In prod profile, properties will be overwriten by the ones defined in bootstrap-prod.yml
+# ===================================================================
+
+jhipster:
+ registry:
+ password: admin
+
+spring:
+ application:
+ name: dealerapp
+ profiles:
+ # The commented value for `active` can be replaced with valid Spring profiles to load.
+ # Otherwise, it will be filled in by maven when building the WAR file
+ # Either way, it can be overridden by `--spring.profiles.active` value passed in the commandline or `-Dspring.profiles.active` set in `JAVA_OPTS`
+ active: #spring.profiles.active#
+ cloud:
+ config:
+ fail-fast: true
+ 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: dealerapp
+ profile: dev # 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 config source git repository
+
+info:
+ project:
+ version: #project.version#
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml
new file mode 100644
index 0000000000..2a1ee4d6bf
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/liquibase/changelog/20170503044952_added_entity_Dealer.xml b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/liquibase/changelog/20170503044952_added_entity_Dealer.xml
new file mode 100644
index 0000000000..128e46a24e
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/liquibase/changelog/20170503044952_added_entity_Dealer.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/liquibase/master.xml b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/liquibase/master.xml
new file mode 100644
index 0000000000..121f0ad396
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/resources/config/liquibase/master.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/resources/i18n/messages.properties b/jhipster/jhipster-microservice/dealer-app/src/main/resources/i18n/messages.properties
new file mode 100644
index 0000000000..a26917e0cc
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/resources/i18n/messages.properties
@@ -0,0 +1,22 @@
+# Error page
+error.title=Your request cannot be processed
+error.subtitle=Sorry, an error has occurred.
+error.status=Status:
+error.message=Message:
+
+# Activation e-mail
+email.activation.title=dealerapp account activation
+email.activation.greeting=Dear {0}
+email.activation.text1=Your dealerapp account has been created, please click on the URL below to activate it:
+email.activation.text2=Regards,
+email.signature=dealerapp Team.
+
+# Creation email
+email.creation.text1=Your dealerapp account has been created, please click on the URL below to access it:
+
+# Reset e-mail
+email.reset.title=dealerapp password reset
+email.reset.greeting=Dear {0}
+email.reset.text1=For your dealerapp account a password reset was requested, please click on the URL below to reset it:
+email.reset.text2=Regards,
+
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/resources/logback-spring.xml b/jhipster/jhipster-microservice/dealer-app/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000000..2ae9944ae0
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/resources/logback-spring.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
diff --git a/jhipster/jhipster-microservice/dealer-app/src/main/resources/templates/error.html b/jhipster/jhipster-microservice/dealer-app/src/main/resources/templates/error.html
new file mode 100644
index 0000000000..774b080d6c
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/main/resources/templates/error.html
@@ -0,0 +1,162 @@
+
+
+
+
+ Your request cannot be processed
+
+
+
+
+
Your request cannot be processed :(
+
+
Sorry, an error has occurred.
+
+
Status: (
)
+
+ Message:
+
+
+
+
+
+
+
diff --git a/jhipster/jhipster-microservice/dealer-app/src/test/java/com/dealer/app/web/rest/DealerResourceIntegrationTest.java b/jhipster/jhipster-microservice/dealer-app/src/test/java/com/dealer/app/web/rest/DealerResourceIntegrationTest.java
new file mode 100644
index 0000000000..38197c418c
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/test/java/com/dealer/app/web/rest/DealerResourceIntegrationTest.java
@@ -0,0 +1,235 @@
+package com.dealer.app.web.rest;
+
+import com.dealer.app.DealerappApp;
+
+import com.dealer.app.domain.Dealer;
+import com.dealer.app.repository.DealerRepository;
+import com.dealer.app.web.rest.errors.ExceptionTranslator;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.persistence.EntityManager;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.hasItem;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+/**
+ * Test class for the DealerResource REST controller.
+ *
+ * @see DealerResource
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = DealerappApp.class)
+public class DealerResourceIntegrationTest {
+
+ private static final String DEFAULT_NAME = "AAAAAAAAAA";
+ private static final String UPDATED_NAME = "BBBBBBBBBB";
+
+ private static final String DEFAULT_ADDRESS = "AAAAAAAAAA";
+ private static final String UPDATED_ADDRESS = "BBBBBBBBBB";
+
+ @Autowired
+ private DealerRepository dealerRepository;
+
+ @Autowired
+ private MappingJackson2HttpMessageConverter jacksonMessageConverter;
+
+ @Autowired
+ private PageableHandlerMethodArgumentResolver pageableArgumentResolver;
+
+ @Autowired
+ private ExceptionTranslator exceptionTranslator;
+
+ @Autowired
+ private EntityManager em;
+
+ private MockMvc restDealerMockMvc;
+
+ private Dealer dealer;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ DealerResource dealerResource = new DealerResource(dealerRepository);
+ this.restDealerMockMvc = MockMvcBuilders.standaloneSetup(dealerResource)
+ .setCustomArgumentResolvers(pageableArgumentResolver)
+ .setControllerAdvice(exceptionTranslator)
+ .setMessageConverters(jacksonMessageConverter).build();
+ }
+
+ /**
+ * Create an entity for this test.
+ *
+ * This is a static method, as tests for other entities might also need it,
+ * if they test an entity which requires the current entity.
+ */
+ public static Dealer createEntity(EntityManager em) {
+ Dealer dealer = new Dealer()
+ .name(DEFAULT_NAME)
+ .address(DEFAULT_ADDRESS);
+ return dealer;
+ }
+
+ @Before
+ public void initTest() {
+ dealer = createEntity(em);
+ }
+
+ @Test
+ @Transactional
+ public void createDealer() throws Exception {
+ int databaseSizeBeforeCreate = dealerRepository.findAll().size();
+
+ // Create the Dealer
+ restDealerMockMvc.perform(post("/api/dealers")
+ .contentType(TestUtil.APPLICATION_JSON_UTF8)
+ .content(TestUtil.convertObjectToJsonBytes(dealer)))
+ .andExpect(status().isCreated());
+
+ // Validate the Dealer in the database
+ List dealerList = dealerRepository.findAll();
+ assertThat(dealerList).hasSize(databaseSizeBeforeCreate + 1);
+ Dealer testDealer = dealerList.get(dealerList.size() - 1);
+ assertThat(testDealer.getName()).isEqualTo(DEFAULT_NAME);
+ assertThat(testDealer.getAddress()).isEqualTo(DEFAULT_ADDRESS);
+ }
+
+ @Test
+ @Transactional
+ public void createDealerWithExistingId() throws Exception {
+ int databaseSizeBeforeCreate = dealerRepository.findAll().size();
+
+ // Create the Dealer with an existing ID
+ dealer.setId(1L);
+
+ // An entity with an existing ID cannot be created, so this API call must fail
+ restDealerMockMvc.perform(post("/api/dealers")
+ .contentType(TestUtil.APPLICATION_JSON_UTF8)
+ .content(TestUtil.convertObjectToJsonBytes(dealer)))
+ .andExpect(status().isBadRequest());
+
+ // Validate the Alice in the database
+ List dealerList = dealerRepository.findAll();
+ assertThat(dealerList).hasSize(databaseSizeBeforeCreate);
+ }
+
+ @Test
+ @Transactional
+ public void getAllDealers() throws Exception {
+ // Initialize the database
+ dealerRepository.saveAndFlush(dealer);
+
+ // Get all the dealerList
+ restDealerMockMvc.perform(get("/api/dealers?sort=id,desc"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
+ .andExpect(jsonPath("$.[*].id").value(hasItem(dealer.getId().intValue())))
+ .andExpect(jsonPath("$.[*].name").value(hasItem(DEFAULT_NAME.toString())))
+ .andExpect(jsonPath("$.[*].address").value(hasItem(DEFAULT_ADDRESS.toString())));
+ }
+
+ @Test
+ @Transactional
+ public void getDealer() throws Exception {
+ // Initialize the database
+ dealerRepository.saveAndFlush(dealer);
+
+ // Get the dealer
+ restDealerMockMvc.perform(get("/api/dealers/{id}", dealer.getId()))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
+ .andExpect(jsonPath("$.id").value(dealer.getId().intValue()))
+ .andExpect(jsonPath("$.name").value(DEFAULT_NAME.toString()))
+ .andExpect(jsonPath("$.address").value(DEFAULT_ADDRESS.toString()));
+ }
+
+ @Test
+ @Transactional
+ public void getNonExistingDealer() throws Exception {
+ // Get the dealer
+ restDealerMockMvc.perform(get("/api/dealers/{id}", Long.MAX_VALUE))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @Transactional
+ public void updateDealer() throws Exception {
+ // Initialize the database
+ dealerRepository.saveAndFlush(dealer);
+ int databaseSizeBeforeUpdate = dealerRepository.findAll().size();
+
+ // Update the dealer
+ Dealer updatedDealer = dealerRepository.findOne(dealer.getId());
+ updatedDealer
+ .name(UPDATED_NAME)
+ .address(UPDATED_ADDRESS);
+
+ restDealerMockMvc.perform(put("/api/dealers")
+ .contentType(TestUtil.APPLICATION_JSON_UTF8)
+ .content(TestUtil.convertObjectToJsonBytes(updatedDealer)))
+ .andExpect(status().isOk());
+
+ // Validate the Dealer in the database
+ List dealerList = dealerRepository.findAll();
+ assertThat(dealerList).hasSize(databaseSizeBeforeUpdate);
+ Dealer testDealer = dealerList.get(dealerList.size() - 1);
+ assertThat(testDealer.getName()).isEqualTo(UPDATED_NAME);
+ assertThat(testDealer.getAddress()).isEqualTo(UPDATED_ADDRESS);
+ }
+
+ @Test
+ @Transactional
+ public void updateNonExistingDealer() throws Exception {
+ int databaseSizeBeforeUpdate = dealerRepository.findAll().size();
+
+ // Create the Dealer
+
+ // If the entity doesn't have an ID, it will be created instead of just being updated
+ restDealerMockMvc.perform(put("/api/dealers")
+ .contentType(TestUtil.APPLICATION_JSON_UTF8)
+ .content(TestUtil.convertObjectToJsonBytes(dealer)))
+ .andExpect(status().isCreated());
+
+ // Validate the Dealer in the database
+ List dealerList = dealerRepository.findAll();
+ assertThat(dealerList).hasSize(databaseSizeBeforeUpdate + 1);
+ }
+
+ @Test
+ @Transactional
+ public void deleteDealer() throws Exception {
+ // Initialize the database
+ dealerRepository.saveAndFlush(dealer);
+ int databaseSizeBeforeDelete = dealerRepository.findAll().size();
+
+ // Get the dealer
+ restDealerMockMvc.perform(delete("/api/dealers/{id}", dealer.getId())
+ .accept(TestUtil.APPLICATION_JSON_UTF8))
+ .andExpect(status().isOk());
+
+ // Validate the database is empty
+ List dealerList = dealerRepository.findAll();
+ assertThat(dealerList).hasSize(databaseSizeBeforeDelete - 1);
+ }
+
+ @Test
+ @Transactional
+ public void equalsVerifier() throws Exception {
+ TestUtil.equalsVerifier(Dealer.class);
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/test/java/com/dealer/app/web/rest/TestUtil.java b/jhipster/jhipster-microservice/dealer-app/src/test/java/com/dealer/app/web/rest/TestUtil.java
new file mode 100644
index 0000000000..7a51b3380d
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/test/java/com/dealer/app/web/rest/TestUtil.java
@@ -0,0 +1,120 @@
+package com.dealer.app.web.rest;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.http.MediaType;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeParseException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Utility class for testing REST controllers.
+ */
+public class TestUtil {
+
+ /** MediaType for JSON UTF8 */
+ public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(
+ MediaType.APPLICATION_JSON.getType(),
+ MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
+
+ /**
+ * Convert an object to JSON byte array.
+ *
+ * @param object
+ * the object to convert
+ * @return the JSON byte array
+ * @throws IOException
+ */
+ public static byte[] convertObjectToJsonBytes(Object object)
+ throws IOException {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+
+ JavaTimeModule module = new JavaTimeModule();
+ mapper.registerModule(module);
+
+ return mapper.writeValueAsBytes(object);
+ }
+
+ /**
+ * Create a byte array with a specific size filled with specified data.
+ *
+ * @param size the size of the byte array
+ * @param data the data to put in the byte array
+ * @return the JSON byte array
+ */
+ public static byte[] createByteArray(int size, String data) {
+ byte[] byteArray = new byte[size];
+ for (int i = 0; i < size; i++) {
+ byteArray[i] = Byte.parseByte(data, 2);
+ }
+ return byteArray;
+ }
+
+ /**
+ * A matcher that tests that the examined string represents the same instant as the reference datetime.
+ */
+ public static class ZonedDateTimeMatcher extends TypeSafeDiagnosingMatcher {
+
+ private final ZonedDateTime date;
+
+ public ZonedDateTimeMatcher(ZonedDateTime date) {
+ this.date = date;
+ }
+
+ @Override
+ protected boolean matchesSafely(String item, Description mismatchDescription) {
+ try {
+ if (!date.isEqual(ZonedDateTime.parse(item))) {
+ mismatchDescription.appendText("was ").appendValue(item);
+ return false;
+ }
+ return true;
+ } catch (DateTimeParseException e) {
+ mismatchDescription.appendText("was ").appendValue(item)
+ .appendText(", which could not be parsed as a ZonedDateTime");
+ return false;
+ }
+
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("a String representing the same Instant as ").appendValue(date);
+ }
+ }
+
+ /**
+ * Creates a matcher that matches when the examined string reprensents the same instant as the reference datetime
+ * @param date the reference datetime against which the examined string is checked
+ */
+ public static ZonedDateTimeMatcher sameInstant(ZonedDateTime date) {
+ return new ZonedDateTimeMatcher(date);
+ }
+
+ /**
+ * Verifies the equals/hashcode contract on the domain object.
+ */
+ public static void equalsVerifier(Class clazz) throws Exception {
+ Object domainObject1 = clazz.getConstructor().newInstance();
+ assertThat(domainObject1.toString()).isNotNull();
+ assertThat(domainObject1).isEqualTo(domainObject1);
+ assertThat(domainObject1.hashCode()).isEqualTo(domainObject1.hashCode());
+ // Test with an instance of another class
+ Object testOtherObject = new Object();
+ assertThat(domainObject1).isNotEqualTo(testOtherObject);
+ // Test with an instance of the same class
+ Object domainObject2 = clazz.getConstructor().newInstance();
+ assertThat(domainObject1).isNotEqualTo(domainObject2);
+ // HashCodes are equals because the objects are not persisted yet
+ assertThat(domainObject1.hashCode()).isEqualTo(domainObject2.hashCode());
+ }
+}
diff --git a/jhipster/jhipster-microservice/dealer-app/src/test/resources/config/application.yml b/jhipster/jhipster-microservice/dealer-app/src/test/resources/config/application.yml
new file mode 100644
index 0000000000..8959533002
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/test/resources/config/application.yml
@@ -0,0 +1,102 @@
+# ===================================================================
+# Spring Boot configuration.
+#
+# This configuration is used for unit/integration tests.
+#
+# More information on profiles: https://jhipster.github.io/profiles/
+# More information on configuration properties: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+# ===================================================================
+# Standard Spring Boot properties.
+# Full reference is available at:
+# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
+# ===================================================================
+
+eureka:
+ client:
+ enabled: false
+ instance:
+ appname: dealerapp
+ instanceId: dealerapp:${spring.application.instance_id:${random.value}}
+
+spring:
+ application:
+ name: dealerapp
+ jackson:
+ serialization.write_dates_as_timestamps: false
+ cache:
+ type: none
+ datasource:
+ type: com.zaxxer.hikari.HikariDataSource
+ url: jdbc:h2:mem:dealerapp;DB_CLOSE_DELAY=-1
+ name:
+ username:
+ password:
+ jpa:
+ database-platform: io.github.jhipster.domain.util.FixedH2Dialect
+ database: H2
+ open-in-view: false
+ show-sql: true
+ hibernate:
+ ddl-auto: none
+ naming:
+ physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
+ implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
+ properties:
+ hibernate.id.new_generator_mappings: true
+ hibernate.cache.use_second_level_cache: false
+ hibernate.cache.use_query_cache: false
+ hibernate.generate_statistics: true
+ hibernate.hbm2ddl.auto: validate
+ mail:
+ host: localhost
+ messages:
+ basename: i18n/messages
+ mvc:
+ favicon:
+ enabled: false
+ thymeleaf:
+ mode: XHTML
+
+liquibase:
+ contexts: test
+
+security:
+ basic:
+ enabled: false
+
+server:
+ port: 10344
+ address: localhost
+
+# ===================================================================
+# JHipster specific properties
+#
+# Full reference is available at: https://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+jhipster:
+ async:
+ core-pool-size: 2
+ max-pool-size: 50
+ queue-capacity: 10000
+ security:
+ authentication:
+ jwt:
+ secret: d4c73e937677223a85c7fcebae7a6ce0c48c3b01
+ # Token is valid 24 hours
+ token-validity-in-seconds: 86400
+ metrics: # DropWizard Metrics configuration, used by MetricsConfiguration
+ jmx.enabled: true
+
+# ===================================================================
+# 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://jhipster.github.io/common-application-properties/
+# ===================================================================
+
+application:
diff --git a/jhipster/jhipster-microservice/dealer-app/src/test/resources/config/bootstrap.yml b/jhipster/jhipster-microservice/dealer-app/src/test/resources/config/bootstrap.yml
new file mode 100644
index 0000000000..11cd6af21c
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/test/resources/config/bootstrap.yml
@@ -0,0 +1,4 @@
+spring:
+ cloud:
+ config:
+ enabled: false
diff --git a/jhipster/jhipster-microservice/dealer-app/src/test/resources/logback-test.xml b/jhipster/jhipster-microservice/dealer-app/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..83efcf9b13
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/src/test/resources/logback-test.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jhipster/jhipster-microservice/dealer-app/yarn.lock b/jhipster/jhipster-microservice/dealer-app/yarn.lock
new file mode 100644
index 0000000000..4333a516f1
--- /dev/null
+++ b/jhipster/jhipster-microservice/dealer-app/yarn.lock
@@ -0,0 +1,2439 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+abbrev@1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f"
+
+acorn-jsx@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
+ dependencies:
+ acorn "^3.0.4"
+
+acorn@^3.0.4:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
+
+ajv@^4.9.1:
+ version "4.11.8"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
+ dependencies:
+ co "^4.6.0"
+ json-stable-stringify "^1.0.1"
+
+amdefine@>=0.0.4:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
+
+ansi-escapes@^1.1.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
+
+ansi-regex@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+
+ansi-styles@^2.0.0, ansi-styles@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
+
+ansi@^0.3.0, ansi@~0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21"
+
+are-we-there-yet@~1.1.2:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d"
+ dependencies:
+ delegates "^1.0.0"
+ readable-stream "^2.0.6"
+
+argparse@^1.0.7:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
+ dependencies:
+ sprintf-js "~1.0.2"
+
+array-differ@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031"
+
+array-find-index@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
+
+array-union@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
+ dependencies:
+ array-uniq "^1.0.1"
+
+array-uniq@^1.0.0, array-uniq@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
+
+arrify@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
+
+asn1@~0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
+
+assert-plus@1.0.0, assert-plus@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+
+assert-plus@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
+
+ast-query@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/ast-query/-/ast-query-2.0.0.tgz#3588e79ad8de07ce50df1e781cc2bda1fd69a453"
+ dependencies:
+ acorn-jsx "^3.0.1"
+ class-extend "^0.1.1"
+ escodegen-wallaby "^1.6.7"
+ lodash "^4.6.1"
+ traverse "^0.6.6"
+
+async@^1.0.0, async@^1.4.2:
+ version "1.5.2"
+ resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
+
+async@^2.0.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/async/-/async-2.4.0.tgz#4990200f18ea5b837c2cc4f8c031a6985c385611"
+ dependencies:
+ lodash "^4.14.0"
+
+asynckit@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+
+aws-sign2@~0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
+
+aws4@^1.2.1:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
+
+balanced-match@^0.4.1:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
+
+bcrypt-pbkdf@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
+ dependencies:
+ tweetnacl "^0.14.3"
+
+bin-version-check@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/bin-version-check/-/bin-version-check-2.1.0.tgz#e4e5df290b9069f7d111324031efc13fdd11a5b0"
+ dependencies:
+ bin-version "^1.0.0"
+ minimist "^1.1.0"
+ semver "^4.0.3"
+ semver-truncate "^1.0.0"
+
+bin-version@^1.0.0:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/bin-version/-/bin-version-1.0.4.tgz#9eb498ee6fd76f7ab9a7c160436f89579435d78e"
+ dependencies:
+ find-versions "^1.0.0"
+
+"binaryextensions@1 || 2":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.0.0.tgz#e597d1a7a6a3558a2d1c7241a16c99965e6aa40f"
+
+boolbase@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
+
+boom@2.x.x:
+ version "2.10.1"
+ resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
+ dependencies:
+ hoek "2.x.x"
+
+boxen@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/boxen/-/boxen-0.3.1.tgz#a7d898243ae622f7abb6bb604d740a76c6a5461b"
+ dependencies:
+ chalk "^1.1.1"
+ filled-array "^1.0.0"
+ object-assign "^4.0.1"
+ repeating "^2.0.0"
+ string-width "^1.0.1"
+ widest-line "^1.0.0"
+
+brace-expansion@^1.0.0:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59"
+ dependencies:
+ balanced-match "^0.4.1"
+ concat-map "0.0.1"
+
+buffer-shims@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51"
+
+builtin-modules@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
+
+camelcase-keys@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
+ dependencies:
+ camelcase "^2.0.0"
+ map-obj "^1.0.0"
+
+camelcase@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
+
+capture-stack-trace@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d"
+
+caseless@~0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
+
+chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
+ dependencies:
+ ansi-styles "^2.2.1"
+ escape-string-regexp "^1.0.2"
+ has-ansi "^2.0.0"
+ strip-ansi "^3.0.0"
+ supports-color "^2.0.0"
+
+cheerio@0.22.0:
+ version "0.22.0"
+ resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e"
+ dependencies:
+ css-select "~1.2.0"
+ dom-serializer "~0.1.0"
+ entities "~1.1.1"
+ htmlparser2 "^3.9.1"
+ lodash.assignin "^4.0.9"
+ lodash.bind "^4.1.4"
+ lodash.defaults "^4.0.1"
+ lodash.filter "^4.4.0"
+ lodash.flatten "^4.2.0"
+ lodash.foreach "^4.3.0"
+ lodash.map "^4.4.0"
+ lodash.merge "^4.4.0"
+ lodash.pick "^4.2.1"
+ lodash.reduce "^4.4.0"
+ lodash.reject "^4.4.0"
+ lodash.some "^4.4.0"
+
+cheerio@^0.19.0:
+ version "0.19.0"
+ resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.19.0.tgz#772e7015f2ee29965096d71ea4175b75ab354925"
+ dependencies:
+ css-select "~1.0.0"
+ dom-serializer "~0.1.0"
+ entities "~1.1.1"
+ htmlparser2 "~3.8.1"
+ lodash "^3.2.0"
+
+class-extend@^0.1.0, class-extend@^0.1.1:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/class-extend/-/class-extend-0.1.2.tgz#8057a82b00f53f82a5d62c50ef8cffdec6fabc34"
+ dependencies:
+ object-assign "^2.0.0"
+
+cli-boxes@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
+
+cli-cursor@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
+ dependencies:
+ restore-cursor "^1.0.1"
+
+cli-list@^0.1.1:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/cli-list/-/cli-list-0.1.8.tgz#aee6d45c4c59bf80068bb968089fb06f1aeddc0a"
+
+cli-table@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23"
+ dependencies:
+ colors "1.0.3"
+
+cli-width@^1.0.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-1.1.1.tgz#a4d293ef67ebb7b88d4a4d42c0ccf00c4d1e366d"
+
+cli-width@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a"
+
+clone-regexp@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-1.0.0.tgz#eae0a2413f55c0942f818c229fefce845d7f3b1c"
+ dependencies:
+ is-regexp "^1.0.0"
+ is-supported-regexp-flag "^1.0.0"
+
+clone-stats@^0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1"
+
+clone@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149"
+
+co@^4.6.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
+
+code-point-at@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+
+colors@1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
+
+combined-stream@^1.0.5, combined-stream@~1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
+ dependencies:
+ delayed-stream "~1.0.0"
+
+commondir@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
+
+concat-map@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+
+concat-stream@^1.4.7:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7"
+ dependencies:
+ inherits "^2.0.3"
+ readable-stream "^2.2.2"
+ typedarray "^0.0.6"
+
+config-chain@~1.1.8:
+ version "1.1.11"
+ resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.11.tgz#aba09747dfbe4c3e70e766a6e41586e1859fc6f2"
+ dependencies:
+ ini "^1.3.4"
+ proto-list "~1.2.1"
+
+configstore@^1.0.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/configstore/-/configstore-1.4.0.tgz#c35781d0501d268c25c54b8b17f6240e8a4fb021"
+ dependencies:
+ graceful-fs "^4.1.2"
+ mkdirp "^0.5.0"
+ object-assign "^4.0.1"
+ os-tmpdir "^1.0.0"
+ osenv "^0.1.0"
+ uuid "^2.0.1"
+ write-file-atomic "^1.1.2"
+ xdg-basedir "^2.0.0"
+
+configstore@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/configstore/-/configstore-2.1.0.tgz#737a3a7036e9886102aa6099e47bb33ab1aba1a1"
+ dependencies:
+ dot-prop "^3.0.0"
+ graceful-fs "^4.1.2"
+ mkdirp "^0.5.0"
+ object-assign "^4.0.1"
+ os-tmpdir "^1.0.0"
+ osenv "^0.1.0"
+ uuid "^2.0.1"
+ write-file-atomic "^1.1.2"
+ xdg-basedir "^2.0.0"
+
+core-util-is@~1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+
+create-error-class@^3.0.1:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6"
+ dependencies:
+ capture-stack-trace "^1.0.0"
+
+cross-spawn@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982"
+ dependencies:
+ lru-cache "^4.0.1"
+ which "^1.2.9"
+
+cross-spawn@^4.0.0:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41"
+ dependencies:
+ lru-cache "^4.0.1"
+ which "^1.2.9"
+
+cryptiles@2.x.x:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
+ dependencies:
+ boom "2.x.x"
+
+css-select@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.0.0.tgz#b1121ca51848dd264e2244d058cee254deeb44b0"
+ dependencies:
+ boolbase "~1.0.0"
+ css-what "1.0"
+ domutils "1.4"
+ nth-check "~1.0.0"
+
+css-select@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
+ dependencies:
+ boolbase "~1.0.0"
+ css-what "2.1"
+ domutils "1.5.1"
+ nth-check "~1.0.1"
+
+css-what@1.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/css-what/-/css-what-1.0.0.tgz#d7cc2df45180666f99d2b14462639469e00f736c"
+
+css-what@2.1:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd"
+
+currently-unhandled@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
+ dependencies:
+ array-find-index "^1.0.1"
+
+dargs@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+dashdash@^1.12.0:
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
+ dependencies:
+ assert-plus "^1.0.0"
+
+dateformat@^1.0.11:
+ version "1.0.12"
+ resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9"
+ dependencies:
+ get-stdin "^4.0.1"
+ meow "^3.3.0"
+
+debug@^2.0.0, debug@^2.1.0, debug@^2.2.0:
+ version "2.6.6"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.6.tgz#a9fa6fbe9ca43cf1e79f73b75c0189cbb7d6db5a"
+ dependencies:
+ ms "0.7.3"
+
+decamelize@^1.0.0, decamelize@^1.1.2:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
+
+deep-extend@^0.4.0, deep-extend@~0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253"
+
+deep-is@~0.1.3:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
+
+default-uid@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/default-uid/-/default-uid-1.0.0.tgz#fcefa9df9f5ac40c8916d912dd1fe1146aa3c59e"
+
+delayed-stream@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+
+delegates@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
+
+detect-conflict@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/detect-conflict/-/detect-conflict-1.0.1.tgz#088657a66a961c05019db7c4230883b1c6b4176e"
+
+detect-newline@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-1.0.3.tgz#e97b1003877d70c09af1af35bfadff168de4920d"
+ dependencies:
+ get-stdin "^4.0.1"
+ minimist "^1.1.0"
+
+diff@^2.1.2:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-2.2.3.tgz#60eafd0d28ee906e4e8ff0a52c1229521033bf99"
+
+discontinuous-range@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
+
+dom-serializer@0, dom-serializer@~0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
+ dependencies:
+ domelementtype "~1.1.1"
+ entities "~1.1.1"
+
+domelementtype@1, domelementtype@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
+
+domelementtype@~1.1.1:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
+
+domhandler@2.3, domhandler@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738"
+ dependencies:
+ domelementtype "1"
+
+domutils@1.4:
+ version "1.4.3"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.4.3.tgz#0865513796c6b306031850e175516baf80b72a6f"
+ dependencies:
+ domelementtype "1"
+
+domutils@1.5, domutils@1.5.1, domutils@^1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
+ dependencies:
+ dom-serializer "0"
+ domelementtype "1"
+
+dot-prop@^2.0.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-2.4.0.tgz#848e28f7f1d50740c6747ab3cb07670462b6f89c"
+ dependencies:
+ is-obj "^1.0.0"
+
+dot-prop@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177"
+ dependencies:
+ is-obj "^1.0.0"
+
+downgrade-root@^1.0.0:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/downgrade-root/-/downgrade-root-1.2.2.tgz#531319715b0e81ffcc22eb28478ba27643e12c6c"
+ dependencies:
+ default-uid "^1.0.0"
+ is-root "^1.0.0"
+
+duplexer2@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
+ dependencies:
+ readable-stream "^2.0.2"
+
+each-async@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/each-async/-/each-async-1.1.1.tgz#dee5229bdf0ab6ba2012a395e1b869abf8813473"
+ dependencies:
+ onetime "^1.0.0"
+ set-immediate-shim "^1.0.0"
+
+ecc-jsbn@~0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
+ dependencies:
+ jsbn "~0.1.0"
+
+editions@^1.1.1:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.3.tgz#0907101bdda20fac3cbe334c27cbd0688dc99a5b"
+
+ejs@2.5.6, ejs@^2.3.1:
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.6.tgz#479636bfa3fe3b1debd52087f0acb204b4f19c88"
+
+entities@1.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26"
+
+entities@^1.1.1, entities@~1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
+
+error-ex@^1.2.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
+ dependencies:
+ is-arrayish "^0.2.1"
+
+error@^7.0.2:
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02"
+ dependencies:
+ string-template "~0.2.1"
+ xtend "~4.0.0"
+
+escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+
+escodegen-wallaby@^1.6.7:
+ version "1.6.11"
+ resolved "https://registry.yarnpkg.com/escodegen-wallaby/-/escodegen-wallaby-1.6.11.tgz#39100cde743f9acdd24bd868db5a12fbacde6ed1"
+ dependencies:
+ esprima "^2.7.1"
+ estraverse "^1.9.1"
+ esutils "^2.0.2"
+ optionator "^0.8.1"
+ optionalDependencies:
+ source-map "~0.2.0"
+
+esprima@^2.7.1:
+ version "2.7.3"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
+
+esprima@^3.1.1:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
+
+estraverse@^1.9.1:
+ version "1.9.3"
+ resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44"
+
+esutils@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
+
+execall@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/execall/-/execall-1.0.0.tgz#73d0904e395b3cab0658b08d09ec25307f29bb73"
+ dependencies:
+ clone-regexp "^1.0.0"
+
+exit-hook@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
+
+extend@^3.0.0, extend@~3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
+
+external-editor@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-1.1.1.tgz#12d7b0db850f7ff7e7081baf4005700060c4600b"
+ dependencies:
+ extend "^3.0.0"
+ spawn-sync "^1.0.15"
+ tmp "^0.0.29"
+
+extsprintf@1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550"
+
+fast-levenshtein@~2.0.4:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
+
+figures@^1.3.5:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
+ dependencies:
+ escape-string-regexp "^1.0.5"
+ object-assign "^4.1.0"
+
+filled-array@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/filled-array/-/filled-array-1.1.0.tgz#c3c4f6c663b923459a9aa29912d2d031f1507f84"
+
+find-up@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
+ dependencies:
+ path-exists "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+find-versions@^1.0.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-1.2.1.tgz#cbde9f12e38575a0af1be1b9a2c5d5fd8f186b62"
+ dependencies:
+ array-uniq "^1.0.0"
+ get-stdin "^4.0.1"
+ meow "^3.5.0"
+ semver-regex "^1.0.0"
+
+first-chunk-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70"
+ dependencies:
+ readable-stream "^2.0.2"
+
+foreachasync@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/foreachasync/-/foreachasync-3.0.0.tgz#5502987dc8714be3392097f32e0071c9dee07cf6"
+
+forever-agent@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+
+form-data@~2.1.1:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1"
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.5"
+ mime-types "^2.1.12"
+
+formatio@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.1.1.tgz#5ed3ccd636551097383465d996199100e86161e9"
+ dependencies:
+ samsam "~1.1"
+
+fs.realpath@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+
+fullname@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/fullname/-/fullname-2.1.0.tgz#c46bf0f7c3f24fd5b3358d00e4a41380eef87350"
+ dependencies:
+ npmconf "^2.1.1"
+ pify "^2.2.0"
+ pinkie-promise "^2.0.0"
+
+gauge@~1.2.5:
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93"
+ dependencies:
+ ansi "^0.3.0"
+ has-unicode "^2.0.0"
+ lodash.pad "^4.1.0"
+ lodash.padend "^4.1.0"
+ lodash.padstart "^4.1.0"
+
+generator-jhipster@4.0.8:
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/generator-jhipster/-/generator-jhipster-4.0.8.tgz#9daff076cc628500726026fad6cfb0a8b55eb1b0"
+ dependencies:
+ chalk "1.1.3"
+ cheerio "0.22.0"
+ ejs "2.5.6"
+ glob "7.1.1"
+ html-wiring "1.2.0"
+ insight "0.8.4"
+ jhipster-core "1.2.8"
+ js-yaml "3.8.1"
+ lodash "4.17.4"
+ mkdirp "0.5.1"
+ pluralize "3.1.0"
+ randexp "0.4.4"
+ semver "5.3.0"
+ shelljs "0.7.6"
+ yeoman-generator "0.24.1"
+ yo "1.8.5"
+
+get-stdin@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
+
+getpass@^0.1.1:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
+ dependencies:
+ assert-plus "^1.0.0"
+
+gh-got@^2.2.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-2.4.0.tgz#aa51418911ca5e4f92437114cd1209383a4aa019"
+ dependencies:
+ got "^5.2.0"
+ object-assign "^4.0.1"
+ pinkie-promise "^2.0.0"
+
+github-username@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/github-username/-/github-username-2.1.0.tgz#200e5a104af42ba08a54096c708d4b6ec2fa256b"
+ dependencies:
+ gh-got "^2.2.0"
+ meow "^3.5.0"
+
+glob@7.1.1, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.0.2"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+glob@^6.0.1:
+ version "6.0.4"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
+ dependencies:
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "2 || 3"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+globby@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-4.1.0.tgz#080f54549ec1b82a6c60e631fc82e1211dbe95f8"
+ dependencies:
+ array-union "^1.0.1"
+ arrify "^1.0.0"
+ glob "^6.0.1"
+ object-assign "^4.0.1"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+got@^5.0.0, got@^5.2.0:
+ version "5.7.1"
+ resolved "https://registry.yarnpkg.com/got/-/got-5.7.1.tgz#5f81635a61e4a6589f180569ea4e381680a51f35"
+ dependencies:
+ create-error-class "^3.0.1"
+ duplexer2 "^0.1.4"
+ is-redirect "^1.0.0"
+ is-retry-allowed "^1.0.0"
+ is-stream "^1.0.0"
+ lowercase-keys "^1.0.0"
+ node-status-codes "^1.0.0"
+ object-assign "^4.0.1"
+ parse-json "^2.1.0"
+ pinkie-promise "^2.0.0"
+ read-all-stream "^3.0.0"
+ readable-stream "^2.0.5"
+ timed-out "^3.0.0"
+ unzip-response "^1.0.2"
+ url-parse-lax "^1.0.0"
+
+graceful-fs@^4.1.11, graceful-fs@^4.1.2:
+ version "4.1.11"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
+
+grouped-queue@^0.3.0:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/grouped-queue/-/grouped-queue-0.3.3.tgz#c167d2a5319c5a0e0964ef6a25b7c2df8996c85c"
+ dependencies:
+ lodash "^4.17.2"
+
+gruntfile-editor@^1.0.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/gruntfile-editor/-/gruntfile-editor-1.2.1.tgz#366fc1f93cbf045813e1448aef1da9f18289d5eb"
+ dependencies:
+ ast-query "^2.0.0"
+ lodash "^4.6.1"
+
+har-schema@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
+
+har-validator@~4.2.1:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
+ dependencies:
+ ajv "^4.9.1"
+ har-schema "^1.0.5"
+
+has-ansi@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+has-flag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
+
+has-unicode@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
+
+hawk@~3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
+ dependencies:
+ boom "2.x.x"
+ cryptiles "2.x.x"
+ hoek "2.x.x"
+ sntp "1.x.x"
+
+hoek@2.x.x:
+ version "2.16.3"
+ resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
+
+hosted-git-info@^2.1.4:
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67"
+
+html-wiring@1.2.0, html-wiring@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/html-wiring/-/html-wiring-1.2.0.tgz#c5f90a776e0a27241dc6df9022c37186d0270f9e"
+ dependencies:
+ cheerio "^0.19.0"
+ detect-newline "^1.0.3"
+
+htmlparser2@^3.9.1:
+ version "3.9.2"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338"
+ dependencies:
+ domelementtype "^1.3.0"
+ domhandler "^2.3.0"
+ domutils "^1.5.1"
+ entities "^1.1.1"
+ inherits "^2.0.1"
+ readable-stream "^2.0.2"
+
+htmlparser2@~3.8.1:
+ version "3.8.3"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068"
+ dependencies:
+ domelementtype "1"
+ domhandler "2.3"
+ domutils "1.5"
+ entities "1.0"
+ readable-stream "1.1"
+
+http-signature@~1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
+ dependencies:
+ assert-plus "^0.2.0"
+ jsprim "^1.2.2"
+ sshpk "^1.7.0"
+
+humanize-string@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/humanize-string/-/humanize-string-1.0.1.tgz#fce2d6c545efc25dea1f23235182c98da0180b42"
+ dependencies:
+ decamelize "^1.0.0"
+
+imurmurhash@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
+
+indent-string@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80"
+ dependencies:
+ repeating "^2.0.0"
+
+inflight@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+ dependencies:
+ once "^1.3.0"
+ wrappy "1"
+
+inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+
+inherits@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
+
+ini@^1.2.0, ini@^1.3.4, ini@~1.3.0:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
+
+inquirer@^0.10.0:
+ version "0.10.1"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.10.1.tgz#ea25e4ce69ca145e05c99e46dcfec05e4012594a"
+ dependencies:
+ ansi-escapes "^1.1.0"
+ ansi-regex "^2.0.0"
+ chalk "^1.0.0"
+ cli-cursor "^1.0.1"
+ cli-width "^1.0.1"
+ figures "^1.3.5"
+ lodash "^3.3.1"
+ readline2 "^1.0.1"
+ run-async "^0.1.0"
+ rx-lite "^3.1.2"
+ strip-ansi "^3.0.0"
+ through "^2.3.6"
+
+inquirer@^0.11.0:
+ version "0.11.4"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.11.4.tgz#81e3374e8361beaff2d97016206d359d0b32fa4d"
+ dependencies:
+ ansi-escapes "^1.1.0"
+ ansi-regex "^2.0.0"
+ chalk "^1.0.0"
+ cli-cursor "^1.0.1"
+ cli-width "^1.0.1"
+ figures "^1.3.5"
+ lodash "^3.3.1"
+ readline2 "^1.0.1"
+ run-async "^0.1.0"
+ rx-lite "^3.1.2"
+ string-width "^1.0.1"
+ strip-ansi "^3.0.0"
+ through "^2.3.6"
+
+inquirer@^1.0.2:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-1.2.3.tgz#4dec6f32f37ef7bb0b2ed3f1d1a5c3f545074918"
+ dependencies:
+ ansi-escapes "^1.1.0"
+ chalk "^1.0.0"
+ cli-cursor "^1.0.1"
+ cli-width "^2.0.0"
+ external-editor "^1.1.0"
+ figures "^1.3.5"
+ lodash "^4.3.0"
+ mute-stream "0.0.6"
+ pinkie-promise "^2.0.0"
+ run-async "^2.2.0"
+ rx "^4.1.0"
+ string-width "^1.0.1"
+ strip-ansi "^3.0.0"
+ through "^2.3.6"
+
+insight@0.8.4:
+ version "0.8.4"
+ resolved "https://registry.yarnpkg.com/insight/-/insight-0.8.4.tgz#671caf65b47c9fe8c3d1b3206cf45bb211b75884"
+ dependencies:
+ async "^1.4.2"
+ chalk "^1.0.0"
+ configstore "^1.0.0"
+ inquirer "^0.10.0"
+ lodash.debounce "^3.0.1"
+ object-assign "^4.0.1"
+ os-name "^1.0.0"
+ request "^2.74.0"
+ tough-cookie "^2.0.0"
+ uuid "^3.0.0"
+
+insight@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/insight/-/insight-0.7.0.tgz#061f9189835bd38a97a60c2b76ea0c6b30099ff6"
+ dependencies:
+ async "^1.4.2"
+ chalk "^1.0.0"
+ configstore "^1.0.0"
+ inquirer "^0.10.0"
+ lodash.debounce "^3.0.1"
+ object-assign "^4.0.1"
+ os-name "^1.0.0"
+ request "^2.40.0"
+ tough-cookie "^2.0.0"
+
+interpret@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90"
+
+is-arrayish@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
+
+is-builtin-module@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"
+ dependencies:
+ builtin-modules "^1.0.0"
+
+is-docker@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-1.1.0.tgz#f04374d4eee5310e9a8e113bf1495411e46176a1"
+
+is-finite@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+is-fullwidth-code-point@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+is-npm@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
+
+is-obj@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
+
+is-promise@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
+
+is-redirect@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24"
+
+is-regexp@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
+
+is-retry-allowed@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
+
+is-root@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-root/-/is-root-1.0.0.tgz#07b6c233bc394cd9d02ba15c966bd6660d6342d5"
+
+is-stream@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+
+is-supported-regexp-flag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.0.tgz#8b520c85fae7a253382d4b02652e045576e13bb8"
+
+is-typedarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
+
+is-utf8@^0.2.0:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
+
+isarray@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
+
+isarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+
+isexe@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+
+isstream@~0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
+
+istextorbinary@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.1.0.tgz#dbed2a6f51be2f7475b68f89465811141b758874"
+ dependencies:
+ binaryextensions "1 || 2"
+ editions "^1.1.1"
+ textextensions "1 || 2"
+
+jhipster-core@1.2.8:
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/jhipster-core/-/jhipster-core-1.2.8.tgz#2211a468761a7132c5ddc7f101400e2fc57d5be4"
+ dependencies:
+ lodash "4.17.4"
+
+jodid25519@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967"
+ dependencies:
+ jsbn "~0.1.0"
+
+js-yaml@3.8.1:
+ version "3.8.1"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.1.tgz#782ba50200be7b9e5a8537001b7804db3ad02628"
+ dependencies:
+ argparse "^1.0.7"
+ esprima "^3.1.1"
+
+jsbn@~0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+
+json-schema@0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
+
+json-stable-stringify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
+ dependencies:
+ jsonify "~0.0.0"
+
+json-stringify-safe@~5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+
+jsonify@~0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
+
+jsprim@^1.2.2:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918"
+ dependencies:
+ assert-plus "1.0.0"
+ extsprintf "1.0.2"
+ json-schema "0.2.3"
+ verror "1.3.6"
+
+latest-version@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-2.0.0.tgz#56f8d6139620847b8017f8f1f4d78e211324168b"
+ dependencies:
+ package-json "^2.0.0"
+
+levn@~0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
+ dependencies:
+ prelude-ls "~1.1.2"
+ type-check "~0.3.2"
+
+load-json-file@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
+ dependencies:
+ graceful-fs "^4.1.2"
+ parse-json "^2.2.0"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+ strip-bom "^2.0.0"
+
+lodash._getnative@^3.0.0:
+ version "3.9.1"
+ resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
+
+lodash.assignin@^4.0.9:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2"
+
+lodash.bind@^4.1.4:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35"
+
+lodash.debounce@^3.0.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-3.1.1.tgz#812211c378a94cc29d5aa4e3346cf0bfce3a7df5"
+ dependencies:
+ lodash._getnative "^3.0.0"
+
+lodash.defaults@^4.0.1:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
+
+lodash.filter@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace"
+
+lodash.flatten@^4.2.0:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
+
+lodash.foreach@^4.3.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
+
+lodash.map@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
+
+lodash.merge@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5"
+
+lodash.pad@^4.1.0:
+ version "4.5.1"
+ resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70"
+
+lodash.padend@^4.1.0:
+ version "4.6.1"
+ resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e"
+
+lodash.padstart@^4.1.0:
+ version "4.6.1"
+ resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b"
+
+lodash.pick@^4.2.1:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
+
+lodash.reduce@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b"
+
+lodash.reject@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415"
+
+lodash.some@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
+
+lodash@4.17.4, lodash@^4.11.1, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.3.0, lodash@^4.6.1:
+ version "4.17.4"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
+
+lodash@^3.2.0, lodash@^3.3.1:
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
+
+log-symbols@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
+ dependencies:
+ chalk "^1.0.0"
+
+lolex@1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31"
+
+loud-rejection@^1.0.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f"
+ dependencies:
+ currently-unhandled "^0.4.1"
+ signal-exit "^3.0.0"
+
+lowercase-keys@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306"
+
+lru-cache@^4.0.1:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e"
+ dependencies:
+ pseudomap "^1.0.1"
+ yallist "^2.0.0"
+
+map-obj@^1.0.0, map-obj@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
+
+mem-fs-editor@^2.0.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-2.3.0.tgz#42a0ae1f55e76fd03f09e7c7b15b6307bdf5cb13"
+ dependencies:
+ commondir "^1.0.1"
+ deep-extend "^0.4.0"
+ ejs "^2.3.1"
+ glob "^7.0.3"
+ globby "^4.0.0"
+ mkdirp "^0.5.0"
+ multimatch "^2.0.0"
+ rimraf "^2.2.8"
+ through2 "^2.0.0"
+ vinyl "^1.1.0"
+
+mem-fs@^1.1.0:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/mem-fs/-/mem-fs-1.1.3.tgz#b8ae8d2e3fcb6f5d3f9165c12d4551a065d989cc"
+ dependencies:
+ through2 "^2.0.0"
+ vinyl "^1.1.0"
+ vinyl-file "^2.0.0"
+
+meow@^3.0.0, meow@^3.3.0, meow@^3.5.0:
+ version "3.7.0"
+ resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb"
+ dependencies:
+ camelcase-keys "^2.0.0"
+ decamelize "^1.1.2"
+ loud-rejection "^1.0.0"
+ map-obj "^1.0.1"
+ minimist "^1.1.3"
+ normalize-package-data "^2.3.4"
+ object-assign "^4.0.1"
+ read-pkg-up "^1.0.1"
+ redent "^1.0.0"
+ trim-newlines "^1.0.0"
+
+mime-db@~1.27.0:
+ version "1.27.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1"
+
+mime-types@^2.1.12, mime-types@~2.1.7:
+ version "2.1.15"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed"
+ dependencies:
+ mime-db "~1.27.0"
+
+"minimatch@2 || 3", minimatch@3.0.x, minimatch@^3.0.0, minimatch@^3.0.2:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774"
+ dependencies:
+ brace-expansion "^1.0.0"
+
+minimist@0.0.8:
+ version "0.0.8"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
+
+minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
+
+mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
+ dependencies:
+ minimist "0.0.8"
+
+ms@0.7.3:
+ version "0.7.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff"
+
+multimatch@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b"
+ dependencies:
+ array-differ "^1.0.0"
+ array-union "^1.0.1"
+ arrify "^1.0.0"
+ minimatch "^3.0.0"
+
+mute-stream@0.0.5:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0"
+
+mute-stream@0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.6.tgz#48962b19e169fd1dfc240b3f1e7317627bbc47db"
+
+node-status-codes@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f"
+
+nopt@^3.0.0, nopt@~3.0.1:
+ version "3.0.6"
+ resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
+ dependencies:
+ abbrev "1"
+
+normalize-package-data@^2.3.2, normalize-package-data@^2.3.4:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb"
+ dependencies:
+ hosted-git-info "^2.1.4"
+ is-builtin-module "^1.0.0"
+ semver "2 || 3 || 4 || 5"
+ validate-npm-package-license "^3.0.1"
+
+npm-keyword@^4.1.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/npm-keyword/-/npm-keyword-4.2.0.tgz#98ffebfdbb1336f27ef5fe1baca0dcacd0acf6c0"
+ dependencies:
+ got "^5.0.0"
+ object-assign "^4.0.1"
+ pinkie-promise "^2.0.0"
+ registry-url "^3.0.3"
+
+npmconf@^2.1.1:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/npmconf/-/npmconf-2.1.2.tgz#66606a4a736f1e77a059aa071a79c94ab781853a"
+ dependencies:
+ config-chain "~1.1.8"
+ inherits "~2.0.0"
+ ini "^1.2.0"
+ mkdirp "^0.5.0"
+ nopt "~3.0.1"
+ once "~1.3.0"
+ osenv "^0.1.0"
+ semver "2 || 3 || 4"
+ uid-number "0.0.5"
+
+npmlog@^2.0.3:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692"
+ dependencies:
+ ansi "~0.3.1"
+ are-we-there-yet "~1.1.2"
+ gauge "~1.2.5"
+
+nth-check@~1.0.0, nth-check@~1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4"
+ dependencies:
+ boolbase "~1.0.0"
+
+number-is-nan@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
+
+oauth-sign@~0.8.1:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
+
+object-assign@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa"
+
+object-assign@^4.0.1, object-assign@^4.1.0:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+
+object-values@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/object-values/-/object-values-1.0.0.tgz#72af839630119e5b98c3b02bb8c27e3237158105"
+
+once@^1.3.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+ dependencies:
+ wrappy "1"
+
+once@~1.3.0:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20"
+ dependencies:
+ wrappy "1"
+
+onetime@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
+
+opn@^3.0.2:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/opn/-/opn-3.0.3.tgz#b6d99e7399f78d65c3baaffef1fb288e9b85243a"
+ dependencies:
+ object-assign "^4.0.1"
+
+optionator@^0.8.1:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
+ dependencies:
+ deep-is "~0.1.3"
+ fast-levenshtein "~2.0.4"
+ levn "~0.3.0"
+ prelude-ls "~1.1.2"
+ type-check "~0.3.2"
+ wordwrap "~1.0.0"
+
+os-homedir@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
+
+os-name@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/os-name/-/os-name-1.0.3.tgz#1b379f64835af7c5a7f498b357cb95215c159edf"
+ dependencies:
+ osx-release "^1.0.0"
+ win-release "^1.0.0"
+
+os-shim@^0.1.2:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917"
+
+os-tmpdir@^1.0.0, os-tmpdir@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
+
+osenv@^0.1.0:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644"
+ dependencies:
+ os-homedir "^1.0.0"
+ os-tmpdir "^1.0.0"
+
+osx-release@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/osx-release/-/osx-release-1.1.0.tgz#f217911a28136949af1bf9308b241e2737d3cd6c"
+ dependencies:
+ minimist "^1.1.0"
+
+package-json@^2.0.0, package-json@^2.1.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/package-json/-/package-json-2.4.0.tgz#0d15bd67d1cbbddbb2ca222ff2edb86bcb31a8bb"
+ dependencies:
+ got "^5.0.0"
+ registry-auth-token "^3.0.1"
+ registry-url "^3.0.3"
+ semver "^5.1.0"
+
+pad-component@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/pad-component/-/pad-component-0.0.1.tgz#ad1f22ce1bf0fdc0d6ddd908af17f351a404b8ac"
+
+parse-help@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/parse-help/-/parse-help-0.1.1.tgz#2f4df942e77a5581bba9967c0c3f48e4c66d7dda"
+ dependencies:
+ execall "^1.0.0"
+
+parse-json@^2.1.0, parse-json@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
+ dependencies:
+ error-ex "^1.2.0"
+
+path-exists@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
+ dependencies:
+ pinkie-promise "^2.0.0"
+
+path-is-absolute@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+
+path-parse@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
+
+path-type@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
+ dependencies:
+ graceful-fs "^4.1.2"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+performance-now@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
+
+pify@^2.0.0, pify@^2.2.0, pify@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
+
+pinkie-promise@^2.0.0, pinkie-promise@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
+ dependencies:
+ pinkie "^2.0.0"
+
+pinkie@^2.0.0:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
+
+pluralize@3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-3.1.0.tgz#84213d0a12356069daa84060c559242633161368"
+
+prelude-ls@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
+
+prepend-http@^1.0.1:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
+
+pretty-bytes@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-3.0.1.tgz#27d0008d778063a0b4811bb35c79f1bd5d5fbccf"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+process-nextick-args@~1.0.6:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
+
+proto-list@~1.2.1:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
+
+pseudomap@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
+
+punycode@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
+
+qs@~6.4.0:
+ version "6.4.0"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
+
+randexp@0.4.4:
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.4.tgz#ba68265f4a9f9e85f5814d34e160291f939f168e"
+ dependencies:
+ discontinuous-range "1.0.0"
+ ret "~0.1.10"
+
+rc@^1.0.1, rc@^1.1.6:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95"
+ dependencies:
+ deep-extend "~0.4.0"
+ ini "~1.3.0"
+ minimist "^1.2.0"
+ strip-json-comments "~2.0.1"
+
+read-all-stream@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa"
+ dependencies:
+ pinkie-promise "^2.0.0"
+ readable-stream "^2.0.0"
+
+read-chunk@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-1.0.1.tgz#5f68cab307e663f19993527d9b589cace4661194"
+
+read-pkg-up@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
+ dependencies:
+ find-up "^1.0.0"
+ read-pkg "^1.0.0"
+
+read-pkg@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
+ dependencies:
+ load-json-file "^1.0.0"
+ normalize-package-data "^2.3.2"
+ path-type "^1.0.0"
+
+readable-stream@1.1:
+ version "1.1.13"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e"
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "0.0.1"
+ string_decoder "~0.10.x"
+
+readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2:
+ version "2.2.9"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.9.tgz#cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8"
+ dependencies:
+ buffer-shims "~1.0.0"
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "~1.0.0"
+ process-nextick-args "~1.0.6"
+ string_decoder "~1.0.0"
+ util-deprecate "~1.0.1"
+
+readline2@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35"
+ dependencies:
+ code-point-at "^1.0.0"
+ is-fullwidth-code-point "^1.0.0"
+ mute-stream "0.0.5"
+
+rechoir@^0.6.2:
+ version "0.6.2"
+ resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
+ dependencies:
+ resolve "^1.1.6"
+
+redent@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde"
+ dependencies:
+ indent-string "^2.1.0"
+ strip-indent "^1.0.1"
+
+registry-auth-token@^3.0.1:
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006"
+ dependencies:
+ rc "^1.1.6"
+ safe-buffer "^5.0.1"
+
+registry-url@^3.0.3:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942"
+ dependencies:
+ rc "^1.0.1"
+
+repeating@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
+ dependencies:
+ is-finite "^1.0.0"
+
+replace-ext@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924"
+
+request@^2.40.0, request@^2.74.0:
+ version "2.81.0"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
+ dependencies:
+ aws-sign2 "~0.6.0"
+ aws4 "^1.2.1"
+ caseless "~0.12.0"
+ combined-stream "~1.0.5"
+ extend "~3.0.0"
+ forever-agent "~0.6.1"
+ form-data "~2.1.1"
+ har-validator "~4.2.1"
+ hawk "~3.1.3"
+ http-signature "~1.1.0"
+ is-typedarray "~1.0.0"
+ isstream "~0.1.2"
+ json-stringify-safe "~5.0.1"
+ mime-types "~2.1.7"
+ oauth-sign "~0.8.1"
+ performance-now "^0.2.0"
+ qs "~6.4.0"
+ safe-buffer "^5.0.1"
+ stringstream "~0.0.4"
+ tough-cookie "~2.3.0"
+ tunnel-agent "^0.6.0"
+ uuid "^3.0.0"
+
+resolve@^1.1.6:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
+ dependencies:
+ path-parse "^1.0.5"
+
+restore-cursor@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
+ dependencies:
+ exit-hook "^1.0.0"
+ onetime "^1.0.0"
+
+ret@~0.1.10:
+ version "0.1.14"
+ resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.14.tgz#58c636837b12e161f8a380cf081c6a230fd1664e"
+
+rimraf@^2.2.0, rimraf@^2.2.8, rimraf@^2.4.4:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
+ dependencies:
+ glob "^7.0.5"
+
+root-check@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/root-check/-/root-check-1.0.0.tgz#c52a794bf0db9fad567536e41898f0c9e0a86697"
+ dependencies:
+ downgrade-root "^1.0.0"
+ sudo-block "^1.1.0"
+
+run-async@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389"
+ dependencies:
+ once "^1.3.0"
+
+run-async@^2.0.0, run-async@^2.2.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
+ dependencies:
+ is-promise "^2.1.0"
+
+rx-lite@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
+
+rx@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
+
+safe-buffer@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7"
+
+samsam@1.1.2, samsam@~1.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567"
+
+semver-diff@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
+ dependencies:
+ semver "^5.0.3"
+
+semver-regex@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-1.0.0.tgz#92a4969065f9c70c694753d55248fc68f8f652c9"
+
+semver-truncate@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/semver-truncate/-/semver-truncate-1.1.2.tgz#57f41de69707a62709a7e0104ba2117109ea47e8"
+ dependencies:
+ semver "^5.3.0"
+
+"semver@2 || 3 || 4", semver@^4.0.3:
+ version "4.3.6"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da"
+
+"semver@2 || 3 || 4 || 5", semver@5.3.0, semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
+
+set-immediate-shim@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
+
+shelljs@0.7.6, shelljs@^0.7.0:
+ version "0.7.6"
+ resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.6.tgz#379cccfb56b91c8601e4793356eb5382924de9ad"
+ dependencies:
+ glob "^7.0.0"
+ interpret "^1.0.0"
+ rechoir "^0.6.2"
+
+signal-exit@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
+
+sinon@^1.17.2:
+ version "1.17.7"
+ resolved "https://registry.yarnpkg.com/sinon/-/sinon-1.17.7.tgz#4542a4f49ba0c45c05eb2e9dd9d203e2b8efe0bf"
+ dependencies:
+ formatio "1.1.1"
+ lolex "1.3.2"
+ samsam "1.1.2"
+ util ">=0.10.3 <1"
+
+slide@^1.1.5:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707"
+
+sntp@1.x.x:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
+ dependencies:
+ hoek "2.x.x"
+
+sort-on@^1.0.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/sort-on/-/sort-on-1.3.0.tgz#0dfd5b364b23df7f2acd86985daeb889e1a7c840"
+ dependencies:
+ arrify "^1.0.0"
+ dot-prop "^2.0.0"
+
+source-map@~0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d"
+ dependencies:
+ amdefine ">=0.0.4"
+
+spawn-sync@^1.0.15:
+ version "1.0.15"
+ resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476"
+ dependencies:
+ concat-stream "^1.4.7"
+ os-shim "^0.1.2"
+
+spdx-correct@~1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
+ dependencies:
+ spdx-license-ids "^1.0.2"
+
+spdx-expression-parse@~1.0.0:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c"
+
+spdx-license-ids@^1.0.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
+
+sprintf-js@^1.0.3, sprintf-js@~1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
+
+sshpk@^1.7.0:
+ version "1.13.0"
+ resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c"
+ dependencies:
+ asn1 "~0.2.3"
+ assert-plus "^1.0.0"
+ dashdash "^1.12.0"
+ getpass "^0.1.1"
+ optionalDependencies:
+ bcrypt-pbkdf "^1.0.0"
+ ecc-jsbn "~0.1.1"
+ jodid25519 "^1.0.0"
+ jsbn "~0.1.0"
+ tweetnacl "~0.14.0"
+
+string-length@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/string-length/-/string-length-1.0.1.tgz#56970fb1c38558e9e70b728bf3de269ac45adfac"
+ dependencies:
+ strip-ansi "^3.0.0"
+
+string-template@~0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add"
+
+string-width@^1.0.0, string-width@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
+ dependencies:
+ code-point-at "^1.0.0"
+ is-fullwidth-code-point "^1.0.0"
+ strip-ansi "^3.0.0"
+
+string_decoder@~0.10.x:
+ version "0.10.31"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
+
+string_decoder@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.0.tgz#f06f41157b664d86069f84bdbdc9b0d8ab281667"
+ dependencies:
+ buffer-shims "~1.0.0"
+
+stringstream@~0.0.4:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
+
+strip-ansi@^3.0.0, strip-ansi@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+strip-bom-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca"
+ dependencies:
+ first-chunk-stream "^2.0.0"
+ strip-bom "^2.0.0"
+
+strip-bom@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
+ dependencies:
+ is-utf8 "^0.2.0"
+
+strip-indent@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2"
+ dependencies:
+ get-stdin "^4.0.1"
+
+strip-json-comments@~2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
+
+sudo-block@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/sudo-block/-/sudo-block-1.2.0.tgz#cc539bf8191624d4f507d83eeb45b4cea27f3463"
+ dependencies:
+ chalk "^1.0.0"
+ is-docker "^1.0.0"
+ is-root "^1.0.0"
+
+supports-color@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
+
+supports-color@^3.1.2:
+ version "3.2.3"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
+ dependencies:
+ has-flag "^1.0.0"
+
+tabtab@^1.3.0:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/tabtab/-/tabtab-1.3.2.tgz#bb9c2ca6324f659fde7634c2caf3c096e1187ca7"
+ dependencies:
+ debug "^2.2.0"
+ inquirer "^1.0.2"
+ minimist "^1.2.0"
+ mkdirp "^0.5.1"
+ npmlog "^2.0.3"
+ object-assign "^4.1.0"
+
+taketalk@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/taketalk/-/taketalk-1.0.0.tgz#b4d4f0deed206ae7df775b129ea2ca6de52f26dd"
+ dependencies:
+ get-stdin "^4.0.1"
+ minimist "^1.1.0"
+
+text-table@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
+
+"textextensions@1 || 2":
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.1.0.tgz#1be0dc2a0dc244d44be8a09af6a85afb93c4dbc3"
+
+through2@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
+ dependencies:
+ readable-stream "^2.1.5"
+ xtend "~4.0.1"
+
+through@^2.3.6:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+
+timed-out@^3.0.0:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.3.tgz#95860bfcc5c76c277f8f8326fd0f5b2e20eba217"
+
+titleize@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/titleize/-/titleize-1.0.0.tgz#7d350722061830ba6617631e0cfd3ea08398d95a"
+
+tmp@^0.0.29:
+ version "0.0.29"
+ resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.29.tgz#f25125ff0dd9da3ccb0c2dd371ee1288bb9128c0"
+ dependencies:
+ os-tmpdir "~1.0.1"
+
+tough-cookie@^2.0.0, tough-cookie@~2.3.0:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a"
+ dependencies:
+ punycode "^1.4.1"
+
+traverse@^0.6.6:
+ version "0.6.6"
+ resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137"
+
+trim-newlines@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
+
+tunnel-agent@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
+ dependencies:
+ safe-buffer "^5.0.1"
+
+tweetnacl@^0.14.3, tweetnacl@~0.14.0:
+ version "0.14.5"
+ resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+
+twig@^0.8.2:
+ version "0.8.9"
+ resolved "https://registry.yarnpkg.com/twig/-/twig-0.8.9.tgz#b1594f002b684e5f029de3e54e87bec4f084b6c2"
+ dependencies:
+ minimatch "3.0.x"
+ walk "2.3.x"
+
+type-check@~0.3.2:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
+ dependencies:
+ prelude-ls "~1.1.2"
+
+typedarray@^0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
+
+uid-number@0.0.5:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.5.tgz#5a3db23ef5dbd55b81fce0ec9a2ac6fccdebb81e"
+
+underscore.string@^3.0.3:
+ version "3.3.4"
+ resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.3.4.tgz#2c2a3f9f83e64762fdc45e6ceac65142864213db"
+ dependencies:
+ sprintf-js "^1.0.3"
+ util-deprecate "^1.0.2"
+
+untildify@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0"
+ dependencies:
+ os-homedir "^1.0.0"
+
+unzip-response@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe"
+
+update-notifier@^0.6.0:
+ version "0.6.3"
+ resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-0.6.3.tgz#776dec8daa13e962a341e8a1d98354306b67ae08"
+ dependencies:
+ boxen "^0.3.1"
+ chalk "^1.0.0"
+ configstore "^2.0.0"
+ is-npm "^1.0.0"
+ latest-version "^2.0.0"
+ semver-diff "^2.0.0"
+
+url-parse-lax@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
+ dependencies:
+ prepend-http "^1.0.1"
+
+user-home@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f"
+ dependencies:
+ os-homedir "^1.0.0"
+
+util-deprecate@^1.0.2, util-deprecate@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+
+"util@>=0.10.3 <1":
+ version "0.10.3"
+ resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
+ dependencies:
+ inherits "2.0.1"
+
+uuid@^2.0.1:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a"
+
+uuid@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1"
+
+validate-npm-package-license@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"
+ dependencies:
+ spdx-correct "~1.0.0"
+ spdx-expression-parse "~1.0.0"
+
+verror@1.3.6:
+ version "1.3.6"
+ resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c"
+ dependencies:
+ extsprintf "1.0.2"
+
+vinyl-file@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/vinyl-file/-/vinyl-file-2.0.0.tgz#a7ebf5ffbefda1b7d18d140fcb07b223efb6751a"
+ dependencies:
+ graceful-fs "^4.1.2"
+ pify "^2.3.0"
+ pinkie-promise "^2.0.0"
+ strip-bom "^2.0.0"
+ strip-bom-stream "^2.0.0"
+ vinyl "^1.1.0"
+
+vinyl@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884"
+ dependencies:
+ clone "^1.0.0"
+ clone-stats "^0.0.1"
+ replace-ext "0.0.1"
+
+walk@2.3.x:
+ version "2.3.9"
+ resolved "https://registry.yarnpkg.com/walk/-/walk-2.3.9.tgz#31b4db6678f2ae01c39ea9fb8725a9031e558a7b"
+ dependencies:
+ foreachasync "^3.0.0"
+
+which@^1.2.9:
+ version "1.2.14"
+ resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
+ dependencies:
+ isexe "^2.0.0"
+
+widest-line@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c"
+ dependencies:
+ string-width "^1.0.1"
+
+win-release@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/win-release/-/win-release-1.1.1.tgz#5fa55e02be7ca934edfc12665632e849b72e5209"
+ dependencies:
+ semver "^5.0.1"
+
+wordwrap@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
+
+wrap-ansi@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
+ dependencies:
+ string-width "^1.0.1"
+ strip-ansi "^3.0.1"
+
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+
+write-file-atomic@^1.1.2:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f"
+ dependencies:
+ graceful-fs "^4.1.11"
+ imurmurhash "^0.1.4"
+ slide "^1.1.5"
+
+xdg-basedir@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2"
+ dependencies:
+ os-homedir "^1.0.0"
+
+xtend@~4.0.0, xtend@~4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
+
+yallist@^2.0.0:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
+
+yeoman-assert@^2.0.0:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/yeoman-assert/-/yeoman-assert-2.2.3.tgz#a5682a83632c50ac0ee84173a5a10fd6f3206474"
+
+yeoman-character@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/yeoman-character/-/yeoman-character-1.1.0.tgz#90d4b5beaf92759086177015b2fdfa2e0684d7c7"
+ dependencies:
+ supports-color "^3.1.2"
+
+yeoman-doctor@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/yeoman-doctor/-/yeoman-doctor-2.1.0.tgz#94ab784896a64f53a9fac452d5e9133e2750a236"
+ dependencies:
+ bin-version-check "^2.1.0"
+ chalk "^1.0.0"
+ each-async "^1.1.1"
+ log-symbols "^1.0.1"
+ object-values "^1.0.0"
+ semver "^5.0.3"
+ twig "^0.8.2"
+ user-home "^2.0.0"
+
+yeoman-environment@^1.1.0, yeoman-environment@^1.5.2, yeoman-environment@^1.6.1:
+ version "1.6.6"
+ resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-1.6.6.tgz#cd85fa67d156060e440d7807d7ef7cf0d2d1d671"
+ dependencies:
+ chalk "^1.0.0"
+ debug "^2.0.0"
+ diff "^2.1.2"
+ escape-string-regexp "^1.0.2"
+ globby "^4.0.0"
+ grouped-queue "^0.3.0"
+ inquirer "^1.0.2"
+ lodash "^4.11.1"
+ log-symbols "^1.0.1"
+ mem-fs "^1.1.0"
+ text-table "^0.2.0"
+ untildify "^2.0.0"
+
+yeoman-generator@0.24.1, yeoman-generator@^0.24.1:
+ version "0.24.1"
+ resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-0.24.1.tgz#1ca74429d9c5c95db0b22859ec180a2599bc1f8e"
+ dependencies:
+ async "^2.0.0"
+ chalk "^1.0.0"
+ class-extend "^0.1.0"
+ cli-table "^0.3.1"
+ cross-spawn "^4.0.0"
+ dargs "^4.0.0"
+ dateformat "^1.0.11"
+ debug "^2.1.0"
+ detect-conflict "^1.0.0"
+ error "^7.0.2"
+ find-up "^1.0.0"
+ github-username "^2.0.0"
+ glob "^7.0.3"
+ gruntfile-editor "^1.0.0"
+ html-wiring "^1.0.0"
+ istextorbinary "^2.1.0"
+ lodash "^4.11.1"
+ mem-fs-editor "^2.0.0"
+ mkdirp "^0.5.0"
+ nopt "^3.0.0"
+ path-exists "^2.0.0"
+ path-is-absolute "^1.0.0"
+ pretty-bytes "^3.0.1"
+ read-chunk "^1.0.0"
+ read-pkg-up "^1.0.1"
+ rimraf "^2.2.0"
+ run-async "^2.0.0"
+ shelljs "^0.7.0"
+ text-table "^0.2.0"
+ through2 "^2.0.0"
+ underscore.string "^3.0.3"
+ user-home "^2.0.0"
+ yeoman-assert "^2.0.0"
+ yeoman-environment "^1.1.0"
+ yeoman-test "^1.0.0"
+ yeoman-welcome "^1.0.0"
+
+yeoman-test@^1.0.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/yeoman-test/-/yeoman-test-1.6.0.tgz#abff291733e16e8923d9eefc8691c632888bf948"
+ dependencies:
+ inquirer "^1.0.2"
+ lodash "^4.3.0"
+ mkdirp "^0.5.1"
+ pinkie-promise "^2.0.1"
+ rimraf "^2.4.4"
+ sinon "^1.17.2"
+ yeoman-environment "^1.5.2"
+ yeoman-generator "^0.24.1"
+
+yeoman-welcome@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/yeoman-welcome/-/yeoman-welcome-1.0.1.tgz#f6cf198fd4fba8a771672c26cdfb8a64795c84ec"
+ dependencies:
+ chalk "^1.0.0"
+
+yo@1.8.5:
+ version "1.8.5"
+ resolved "https://registry.yarnpkg.com/yo/-/yo-1.8.5.tgz#776ab9ec79a7882f8d4f7a9e10214fdab050d928"
+ dependencies:
+ async "^1.0.0"
+ chalk "^1.0.0"
+ cli-list "^0.1.1"
+ configstore "^1.0.0"
+ cross-spawn "^3.0.1"
+ figures "^1.3.5"
+ fullname "^2.0.0"
+ got "^5.0.0"
+ humanize-string "^1.0.0"
+ inquirer "^0.11.0"
+ insight "^0.7.0"
+ lodash "^3.2.0"
+ meow "^3.0.0"
+ npm-keyword "^4.1.0"
+ opn "^3.0.2"
+ package-json "^2.1.0"
+ parse-help "^0.1.1"
+ read-pkg-up "^1.0.1"
+ repeating "^2.0.0"
+ root-check "^1.0.0"
+ sort-on "^1.0.0"
+ string-length "^1.0.0"
+ tabtab "^1.3.0"
+ titleize "^1.0.0"
+ update-notifier "^0.6.0"
+ user-home "^2.0.0"
+ yeoman-character "^1.0.0"
+ yeoman-doctor "^2.0.0"
+ yeoman-environment "^1.6.1"
+ yosay "^1.0.0"
+
+yosay@^1.0.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/yosay/-/yosay-1.2.1.tgz#9466ef969830e85b474e267b50f7688693ed3b5b"
+ dependencies:
+ ansi-regex "^2.0.0"
+ ansi-styles "^2.0.0"
+ chalk "^1.0.0"
+ cli-boxes "^1.0.0"
+ pad-component "0.0.1"
+ repeating "^2.0.0"
+ string-width "^1.0.0"
+ strip-ansi "^3.0.0"
+ taketalk "^1.0.0"
+ wrap-ansi "^2.0.0"
diff --git a/jhipster/jhipster-microservice/gateway-app/.bowerrc b/jhipster/jhipster-microservice/gateway-app/.bowerrc
new file mode 100644
index 0000000000..ad10799262
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/.bowerrc
@@ -0,0 +1,3 @@
+{
+ "directory": "src/main/webapp/bower_components"
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/.editorconfig b/jhipster/jhipster-microservice/gateway-app/.editorconfig
new file mode 100644
index 0000000000..a03599dd04
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/.editorconfig
@@ -0,0 +1,24 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+[*]
+
+# Change these settings to your own preference
+indent_style = space
+indent_size = 4
+
+# We recommend you to keep these unchanged
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[{package,bower}.json]
+indent_style = space
+indent_size = 2
diff --git a/jhipster/jhipster-microservice/gateway-app/.eslintignore b/jhipster/jhipster-microservice/gateway-app/.eslintignore
new file mode 100644
index 0000000000..047e14a334
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/.eslintignore
@@ -0,0 +1,6 @@
+# more info here - http://eslint.org/docs/user-guide/configuring.html#ignoring-files-and-directories
+
+# node_modules ignored by default
+
+# ignore bower_components
+src/main/webapp/bower_components
diff --git a/jhipster/jhipster-microservice/gateway-app/.eslintrc.json b/jhipster/jhipster-microservice/gateway-app/.eslintrc.json
new file mode 100644
index 0000000000..50047b2bc0
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/.eslintrc.json
@@ -0,0 +1,29 @@
+// See: http://eslint.org/
+// See: https://www.npmjs.com/package/eslint-plugin-angular
+{
+ "extends": [
+ "eslint:recommended",
+ "angular"
+ ],
+ "env": {
+ "node": true,
+ "browser": true
+ },
+ // severity for a rule should be one of the following: 0 = off, 1 = warning, 2 = error
+ "rules": {
+ // coding style
+ "wrap-iife": [2, "inside"],
+ "eqeqeq": 2,
+ "no-use-before-define": [2, "nofunc"],
+ "no-unused-vars": [2, {"vars": "local", "args": "none"}],
+ "no-multi-str": 2,
+ "no-irregular-whitespace": 2,
+ "semi": [2, "always"],
+ "indent": 2,
+
+ // os/git options
+ // we want to run on all OSes
+ "linebreak-style": 0,
+ "eol-last": 2
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/.gitattributes b/jhipster/jhipster-microservice/gateway-app/.gitattributes
new file mode 100644
index 0000000000..2a13efa88f
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/.gitattributes
@@ -0,0 +1,22 @@
+# All text files should have the "lf" (Unix) line endings
+* text eol=lf
+
+# Explicitly declare text files you want to always be normalized and converted
+# to native line endings on checkout.
+*.java text
+*.js text
+*.css text
+*.html text
+
+# Denote all files that are truly binary and should not be modified.
+*.png binary
+*.jpg binary
+*.jar binary
+*.pdf binary
+*.eot binary
+*.ttf binary
+*.gzip binary
+*.gz binary
+*.ai binary
+*.eps binary
+*.swf binary
diff --git a/jhipster/jhipster-microservice/gateway-app/.gitignore b/jhipster/jhipster-microservice/gateway-app/.gitignore
new file mode 100644
index 0000000000..74b29e2042
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/.gitignore
@@ -0,0 +1,141 @@
+######################
+# Project Specific
+######################
+/target/www/**
+/src/test/javascript/coverage/
+/src/test/javascript/PhantomJS*/
+
+######################
+# Node
+######################
+/node/
+node_tmp/
+node_modules/
+npm-debug.log.*
+
+######################
+# SASS
+######################
+.sass-cache/
+
+######################
+# Eclipse
+######################
+*.pydevproject
+.project
+.metadata
+tmp/
+tmp/**/*
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.classpath
+.settings/
+.loadpath
+.factorypath
+/src/main/resources/rebel.xml
+
+# External tool builders
+.externalToolBuilders/**
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# PDT-specific
+.buildpath
+
+######################
+# Intellij
+######################
+.idea/
+*.iml
+*.iws
+*.ipr
+*.ids
+*.orig
+
+######################
+# Visual Studio Code
+######################
+.vscode/
+
+######################
+# Maven
+######################
+/log/
+/target/
+
+######################
+# Gradle
+######################
+.gradle/
+/build/
+
+######################
+# Package Files
+######################
+*.jar
+*.war
+*.ear
+*.db
+
+######################
+# Windows
+######################
+# Windows image file caches
+Thumbs.db
+
+# Folder config file
+Desktop.ini
+
+######################
+# Mac OSX
+######################
+.DS_Store
+.svn
+
+# Thumbnails
+._*
+
+# Files that might appear on external disk
+.Spotlight-V100
+.Trashes
+
+######################
+# Directories
+######################
+/bin/
+/deploy/
+
+######################
+# Logs
+######################
+*.log
+
+######################
+# Others
+######################
+*.class
+*.*~
+*~
+.merge_file*
+
+######################
+# Gradle Wrapper
+######################
+!gradle/wrapper/gradle-wrapper.jar
+
+######################
+# Maven Wrapper
+######################
+!.mvn/wrapper/maven-wrapper.jar
+
+######################
+# ESLint
+######################
+.eslintcache
diff --git a/jhipster/jhipster-microservice/gateway-app/.jhipster/Car.json b/jhipster/jhipster-microservice/gateway-app/.jhipster/Car.json
new file mode 100644
index 0000000000..ceaef3cd63
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/.jhipster/Car.json
@@ -0,0 +1,25 @@
+{
+ "fluentMethods": true,
+ "relationships": [],
+ "fields": [
+ {
+ "fieldName": "make",
+ "fieldType": "String"
+ },
+ {
+ "fieldName": "brand",
+ "fieldType": "String"
+ },
+ {
+ "fieldName": "price",
+ "fieldType": "Double"
+ }
+ ],
+ "changelogDate": "20170503041524",
+ "dto": "no",
+ "service": "no",
+ "entityTableName": "car",
+ "pagination": "infinite-scroll",
+ "microserviceName": "carapp",
+ "searchEngine": false
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/.jhipster/Dealer.json b/jhipster/jhipster-microservice/gateway-app/.jhipster/Dealer.json
new file mode 100644
index 0000000000..e9b4a8112e
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/.jhipster/Dealer.json
@@ -0,0 +1,21 @@
+{
+ "fluentMethods": true,
+ "relationships": [],
+ "fields": [
+ {
+ "fieldName": "name",
+ "fieldType": "String"
+ },
+ {
+ "fieldName": "address",
+ "fieldType": "String"
+ }
+ ],
+ "changelogDate": "20170503044952",
+ "dto": "no",
+ "service": "no",
+ "entityTableName": "dealer",
+ "pagination": "infinite-scroll",
+ "microserviceName": "dealerapp",
+ "searchEngine": false
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/.mvn/wrapper/maven-wrapper.jar b/jhipster/jhipster-microservice/gateway-app/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000000..5fd4d5023f
Binary files /dev/null and b/jhipster/jhipster-microservice/gateway-app/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/jhipster/jhipster-microservice/gateway-app/.mvn/wrapper/maven-wrapper.properties b/jhipster/jhipster-microservice/gateway-app/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000000..c954cec91c
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1 @@
+distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
diff --git a/jhipster/jhipster-microservice/gateway-app/.yo-rc.json b/jhipster/jhipster-microservice/gateway-app/.yo-rc.json
new file mode 100644
index 0000000000..c6e9540740
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/.yo-rc.json
@@ -0,0 +1,29 @@
+{
+ "generator-jhipster": {
+ "jhipsterVersion": "4.0.8",
+ "baseName": "gateway",
+ "packageName": "com.gateway",
+ "packageFolder": "com/gateway",
+ "serverPort": "8080",
+ "authenticationType": "jwt",
+ "hibernateCache": "hazelcast",
+ "clusteredHttpSession": false,
+ "websocket": false,
+ "databaseType": "sql",
+ "devDatabaseType": "h2Disk",
+ "prodDatabaseType": "mysql",
+ "searchEngine": false,
+ "messageBroker": false,
+ "serviceDiscoveryType": "eureka",
+ "buildTool": "maven",
+ "enableSocialSignIn": false,
+ "jwtSecretKey": "cd875958b5c9a8fa965803fd599da3c13abf1015",
+ "clientFramework": "angular1",
+ "useSass": false,
+ "clientPackageManager": "yarn",
+ "applicationType": "gateway",
+ "testFrameworks": [],
+ "jhiPrefix": "jhi",
+ "enableTranslation": false
+ }
+}
\ No newline at end of file
diff --git a/jhipster/jhipster-microservice/gateway-app/README.md b/jhipster/jhipster-microservice/gateway-app/README.md
new file mode 100644
index 0000000000..8b10a5934f
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/README.md
@@ -0,0 +1,116 @@
+# gateway
+This application was generated using JHipster 4.0.8, you can find documentation and help at [https://jhipster.github.io/documentation-archive/v4.0.8](https://jhipster.github.io/documentation-archive/v4.0.8).
+
+This is a "gateway" application intended to be part of a microservice architecture, please refer to the [Doing microservices with JHipster][] page of the documentation for more information.
+
+This application is configured for Service Discovery and Configuration with the JHipster-Registry. On launch, it will refuse to start if it is not able to connect to the JHipster-Registry at [http://localhost:8761](http://localhost:8761). For more information, read our documentation on [Service Discovery and Configuration with the JHipster-Registry][].
+
+## Development
+
+Before you can build this project, you must install and configure the following dependencies on your machine:
+
+1. [Node.js][]: We use Node to run a development web server and build the project.
+ Depending on your system, you can install Node either from source or as a pre-packaged bundle.
+2. [Yarn][]: We use Yarn to manage Node dependencies.
+ Depending on your system, you can install Yarn either from source or as a pre-packaged bundle.
+
+After installing Node, you should be able to run the following command to install development tools.
+You will only need to run this command when dependencies change in [package.json](package.json).
+
+ yarn install
+
+We use [Gulp][] as our build system. Install the Gulp command-line tool globally with:
+
+ yarn global add gulp-cli
+
+Run the following commands in two separate terminals to create a blissful development experience where your browser
+auto-refreshes when files change on your hard drive.
+
+ ./mvnw
+ gulp
+
+[Bower][] is used to manage CSS and JavaScript dependencies used in this application. You can upgrade dependencies by
+specifying a newer version in [bower.json](bower.json). You can also run `bower update` and `bower install` to manage dependencies.
+Add the `-h` flag on any command to see how you can use it. For example, `bower update -h`.
+
+For further instructions on how to develop with JHipster, have a look at [Using JHipster in development][].
+
+
+## Building for production
+
+To optimize the gateway application for production, run:
+
+ ./mvnw -Pprod clean package
+
+This will concatenate and minify the client CSS and JavaScript files. It will also modify `index.html` so it references these new files.
+To ensure everything worked, run:
+
+ java -jar target/*.war
+
+Then navigate to [http://localhost:8080](http://localhost:8080) in your browser.
+
+Refer to [Using JHipster in production][] for more details.
+
+## Testing
+
+To launch your application's tests, run:
+
+ ./mvnw clean test
+
+### Client tests
+
+Unit tests are run by [Karma][] and written with [Jasmine][]. They're located in [src/test/javascript/](src/test/javascript/) and can be run with:
+
+ gulp test
+
+
+
+For more information, refer to the [Running tests page][].
+
+## Using Docker to simplify development (optional)
+
+You can use Docker to improve your JHipster development experience. A number of docker-compose configuration are available in the [src/main/docker](src/main/docker) folder to launch required third party services.
+For example, to start a mysql database in a docker container, run:
+
+ docker-compose -f src/main/docker/mysql.yml up -d
+
+To stop it and remove the container, run:
+
+ docker-compose -f src/main/docker/mysql.yml down
+
+You can also fully dockerize your application and all the services that it depends on.
+To achieve this, first build a docker image of your app by running:
+
+ ./mvnw package -Pprod docker:build
+
+Then run:
+
+ docker-compose -f src/main/docker/app.yml up -d
+
+For more information refer to [Using Docker and Docker-Compose][], this page also contains information on the docker-compose sub-generator (`yo jhipster:docker-compose`), which is able to generate docker configurations for one or several JHipster applications.
+
+## Continuous Integration (optional)
+
+To configure CI for your project, run the ci-cd sub-generator (`yo jhipster:ci-cd`), this will let you generate configuration files for a number of Continuous Integration systems. Consult the [Setting up Continuous Integration][] page for more information.
+
+[JHipster Homepage and latest documentation]: https://jhipster.github.io
+[JHipster 4.0.8 archive]: https://jhipster.github.io/documentation-archive/v4.0.8
+[Doing microservices with JHipster]: https://jhipster.github.io/documentation-archive/v4.0.8/microservices-architecture/
+[Using JHipster in development]: https://jhipster.github.io/documentation-archive/v4.0.8/development/
+[Service Discovery and Configuration with the JHipster-Registry]: https://jhipster.github.io/documentation-archive/v4.0.8/microservices-architecture/#jhipster-registry
+[Using Docker and Docker-Compose]: https://jhipster.github.io/documentation-archive/v4.0.8/docker-compose
+[Using JHipster in production]: https://jhipster.github.io/documentation-archive/v4.0.8/production/
+[Running tests page]: https://jhipster.github.io/documentation-archive/v4.0.8/running-tests/
+[Setting up Continuous Integration]: https://jhipster.github.io/documentation-archive/v4.0.8/setting-up-ci/
+
+
+[Node.js]: https://nodejs.org/
+[Yarn]: https://yarnpkg.org/
+[Bower]: http://bower.io/
+[Gulp]: http://gulpjs.com/
+[BrowserSync]: http://www.browsersync.io/
+[Karma]: http://karma-runner.github.io/
+[Jasmine]: http://jasmine.github.io/2.0/introduction.html
+[Protractor]: https://angular.github.io/protractor/
+[Leaflet]: http://leafletjs.com/
+[DefinitelyTyped]: http://definitelytyped.org/
diff --git a/jhipster/jhipster-microservice/gateway-app/bower.json b/jhipster/jhipster-microservice/gateway-app/bower.json
new file mode 100644
index 0000000000..eedc9790c2
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/bower.json
@@ -0,0 +1,52 @@
+{
+ "version": "0.0.0",
+ "name": "gateway",
+ "appPath": "src/main/webapp/",
+ "testPath": "src/test/javascript/spec",
+ "dependencies": {
+ "angular": "1.5.8",
+ "angular-aria": "1.5.8",
+ "angular-bootstrap": "1.3.3",
+ "angular-cache-buster": "0.4.3",
+ "angular-cookies": "1.5.8",
+ "ngstorage": "0.3.10",
+ "angular-loading-bar": "0.9.0",
+ "angular-resource": "1.5.8",
+ "angular-sanitize": "1.5.8",
+ "angular-ui-router": "0.3.1",
+ "bootstrap": "3.3.7",
+ "bootstrap-ui-datetime-picker": "2.4.3",
+ "jquery": "3.1.0",
+ "json3": "3.3.2",
+ "messageformat": "0.3.1",
+ "modernizr": "3.3.1",
+ "ng-file-upload": "12.0.4",
+ "ngInfiniteScroll": "1.3.0",
+ "swagger-ui": "2.1.5"
+ },
+ "devDependencies": {
+ "angular-mocks": "1.5.8"
+ },
+ "overrides": {
+ "angular": {
+ "dependencies": {
+ "jquery": "3.1.0"
+ }
+ },
+ "angular-cache-buster": {
+ "dependencies": {
+ "angular": "1.5.8"
+ }
+ },
+ "bootstrap": {
+ "main": [
+ "dist/css/bootstrap.css"
+ ]
+ }
+ },
+ "resolutions": {
+ "angular": "1.5.8",
+ "angular-bootstrap": "2.0.0",
+ "jquery": "3.1.0"
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/gulp/build.js b/jhipster/jhipster-microservice/gateway-app/gulp/build.js
new file mode 100644
index 0000000000..ecb5c362ce
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/gulp/build.js
@@ -0,0 +1,51 @@
+'use strict';
+
+var fs = require('fs'),
+ gulp = require('gulp'),
+ lazypipe = require('lazypipe'),
+ footer = require('gulp-footer'),
+ sourcemaps = require('gulp-sourcemaps'),
+ rev = require('gulp-rev'),
+ htmlmin = require('gulp-htmlmin'),
+ ngAnnotate = require('gulp-ng-annotate'),
+ prefix = require('gulp-autoprefixer'),
+ cssnano = require('gulp-cssnano'),
+ uglify = require('gulp-uglify'),
+ useref = require("gulp-useref"),
+ revReplace = require("gulp-rev-replace"),
+ plumber = require('gulp-plumber'),
+ gulpIf = require('gulp-if'),
+ handleErrors = require('./handle-errors');
+
+var config = require('./config');
+
+var initTask = lazypipe()
+ .pipe(sourcemaps.init);
+var jsTask = lazypipe()
+ .pipe(ngAnnotate)
+ .pipe(uglify);
+var cssTask = lazypipe()
+ .pipe(prefix)
+ .pipe(cssnano);
+
+module.exports = function() {
+ var templates = fs.readFileSync(config.tmp + '/templates.js');
+ var manifest = gulp.src(config.revManifest);
+
+ return gulp.src([config.app + '**/*.html',
+ '!' + config.app + 'app/**/*.html',
+ '!' + config.app + 'swagger-ui/**/*',
+ '!' + config.bower + '**/*.html'])
+ .pipe(plumber({errorHandler: handleErrors}))
+ //init sourcemaps and prepend semicolon
+ .pipe(useref({}, initTask))
+ //append html templates
+ .pipe(gulpIf('**/app.js', footer(templates)))
+ .pipe(gulpIf('*.js', jsTask()))
+ .pipe(gulpIf('*.css', cssTask()))
+ .pipe(gulpIf('*.html', htmlmin({collapseWhitespace: true})))
+ .pipe(gulpIf('**/*.!(html)', rev()))
+ .pipe(revReplace({manifest: manifest}))
+ .pipe(sourcemaps.write('.'))
+ .pipe(gulp.dest(config.dist));
+};
diff --git a/jhipster/jhipster-microservice/gateway-app/gulp/config.js b/jhipster/jhipster-microservice/gateway-app/gulp/config.js
new file mode 100644
index 0000000000..49df6e6ddd
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/gulp/config.js
@@ -0,0 +1,23 @@
+'use strict';
+
+module.exports = {
+ app: 'src/main/webapp/',
+ dist: 'target/www/',
+ swaggerDist: 'target/www/swagger-ui/',
+ test: 'src/test/javascript/',
+ bower: 'src/main/webapp/bower_components/',
+ tmp: 'target/tmp',
+ revManifest: 'target/tmp/rev-manifest.json',
+ port: 9000,
+ apiPort: 8080,
+ liveReloadPort: 35729,
+ uri: 'http://localhost:',
+ constantTemplate:
+ '(function () {\n' +
+ ' \'use strict\';\n' +
+ ' // DO NOT EDIT THIS FILE, EDIT THE GULP TASK NGCONSTANT SETTINGS INSTEAD WHICH GENERATES THIS FILE\n' +
+ ' angular\n' +
+ ' .module(\'<%- moduleName %>\')\n' +
+ '<% constants.forEach(function(constant) { %> .constant(\'<%- constant.name %>\', <%= constant.value %>)\n<% }) %>;\n' +
+ '})();\n'
+};
diff --git a/jhipster/jhipster-microservice/gateway-app/gulp/copy.js b/jhipster/jhipster-microservice/gateway-app/gulp/copy.js
new file mode 100644
index 0000000000..2e6e71ba71
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/gulp/copy.js
@@ -0,0 +1,81 @@
+'use strict';
+
+var gulp = require('gulp'),
+ rev = require('gulp-rev'),
+ plumber = require('gulp-plumber'),
+ es = require('event-stream'),
+ flatten = require('gulp-flatten'),
+ replace = require('gulp-replace'),
+ bowerFiles = require('main-bower-files'),
+ changed = require('gulp-changed');
+
+var handleErrors = require('./handle-errors');
+var config = require('./config');
+
+module.exports = {
+ fonts: fonts,
+ common: common,
+ swagger: swagger,
+ images: images
+}
+
+function fonts() {
+ return es.merge(gulp.src(config.bower + 'bootstrap/fonts/*.*')
+ .pipe(plumber({errorHandler: handleErrors}))
+ .pipe(changed(config.dist + 'content/fonts/'))
+ .pipe(rev())
+ .pipe(gulp.dest(config.dist + 'content/fonts/'))
+ .pipe(rev.manifest(config.revManifest, {
+ base: config.dist,
+ merge: true
+ }))
+ .pipe(gulp.dest(config.dist)),
+ gulp.src(config.app + 'content/**/*.{woff,woff2,svg,ttf,eot,otf}')
+ .pipe(plumber({errorHandler: handleErrors}))
+ .pipe(changed(config.dist + 'content/fonts/'))
+ .pipe(flatten())
+ .pipe(rev())
+ .pipe(gulp.dest(config.dist + 'content/fonts/'))
+ .pipe(rev.manifest(config.revManifest, {
+ base: config.dist,
+ merge: true
+ }))
+ .pipe(gulp.dest(config.dist))
+ );
+}
+
+function common() {
+ return gulp.src([config.app + 'robots.txt', config.app + 'favicon.ico', config.app + '.htaccess'], { dot: true })
+ .pipe(plumber({errorHandler: handleErrors}))
+ .pipe(changed(config.dist))
+ .pipe(gulp.dest(config.dist));
+}
+
+function swagger() {
+ return es.merge(
+ gulp.src([config.bower + 'swagger-ui/dist/**',
+ '!' + config.bower + 'swagger-ui/dist/index.html',
+ '!' + config.bower + 'swagger-ui/dist/swagger-ui.min.js',
+ '!' + config.bower + 'swagger-ui/dist/swagger-ui.js'])
+ .pipe(plumber({errorHandler: handleErrors}))
+ .pipe(changed(config.swaggerDist))
+ .pipe(gulp.dest(config.swaggerDist)),
+ gulp.src(config.app + 'swagger-ui/index.html')
+ .pipe(plumber({errorHandler: handleErrors}))
+ .pipe(changed(config.swaggerDist))
+ .pipe(replace('../bower_components/swagger-ui/dist/', ''))
+ .pipe(replace('swagger-ui.js', 'lib/swagger-ui.min.js'))
+ .pipe(gulp.dest(config.swaggerDist)),
+ gulp.src(config.bower + 'swagger-ui/dist/swagger-ui.min.js')
+ .pipe(plumber({errorHandler: handleErrors}))
+ .pipe(changed(config.swaggerDist + 'lib/'))
+ .pipe(gulp.dest(config.swaggerDist + 'lib/'))
+ );
+}
+
+function images() {
+ return gulp.src(bowerFiles({filter: ['**/*.{gif,jpg,png}']}), { base: config.bower })
+ .pipe(plumber({errorHandler: handleErrors}))
+ .pipe(changed(config.dist + 'bower_components'))
+ .pipe(gulp.dest(config.dist + 'bower_components'));
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/gulp/handle-errors.js b/jhipster/jhipster-microservice/gateway-app/gulp/handle-errors.js
new file mode 100644
index 0000000000..98c4d4a64c
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/gulp/handle-errors.js
@@ -0,0 +1,22 @@
+'use strict';
+
+var notify = require("gulp-notify");
+var argv = require('yargs').argv;
+
+module.exports = function() {
+
+ var args = Array.prototype.slice.call(arguments);
+ var notification = argv.notification === undefined ? true : argv.notification;
+ // Send error to notification center with gulp-notify
+ if(notification) {
+ notify.onError({
+ title: "JHipster Gulp Build",
+ subtitle: "Failure!",
+ message: "Error: <%= error.message %>",
+ sound: "Beep"
+ }).apply(this, args);
+ }
+ // Keep gulp from hanging on this task
+ this.emit('end');
+
+};
diff --git a/jhipster/jhipster-microservice/gateway-app/gulp/inject.js b/jhipster/jhipster-microservice/gateway-app/gulp/inject.js
new file mode 100644
index 0000000000..1808e31a99
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/gulp/inject.js
@@ -0,0 +1,69 @@
+'use strict';
+
+var gulp = require('gulp'),
+ plumber = require('gulp-plumber'),
+ inject = require('gulp-inject'),
+ es = require('event-stream'),
+ naturalSort = require('gulp-natural-sort'),
+ angularFilesort = require('gulp-angular-filesort'),
+ bowerFiles = require('main-bower-files');
+
+var handleErrors = require('./handle-errors');
+
+var config = require('./config');
+
+module.exports = {
+ app: app,
+ vendor: vendor,
+ test: test,
+ troubleshoot: troubleshoot
+}
+
+function app() {
+ return gulp.src(config.app + 'index.html')
+ .pipe(inject(gulp.src(config.app + 'app/**/*.js')
+ .pipe(plumber({errorHandler: handleErrors}))
+ .pipe(naturalSort())
+ .pipe(angularFilesort()), {relative: true}))
+ .pipe(gulp.dest(config.app));
+}
+
+function vendor() {
+ var stream = gulp.src(config.app + 'index.html')
+ .pipe(plumber({errorHandler: handleErrors}))
+ .pipe(inject(gulp.src(bowerFiles(), {read: false}), {
+ name: 'bower',
+ relative: true
+ }))
+ .pipe(gulp.dest(config.app));
+
+ return stream;
+}
+
+function test() {
+ return gulp.src(config.test + 'karma.conf.js')
+ .pipe(plumber({errorHandler: handleErrors}))
+ .pipe(inject(gulp.src(bowerFiles({includeDev: true, filter: ['**/*.js']}), {read: false}), {
+ starttag: '// bower:js',
+ endtag: '// endbower',
+ transform: function (filepath) {
+ return '\'' + filepath.substring(1, filepath.length) + '\',';
+ }
+ }))
+ .pipe(gulp.dest(config.test));
+}
+
+function troubleshoot() {
+ /* this task removes the troubleshooting content from index.html*/
+ return gulp.src(config.app + 'index.html')
+ .pipe(plumber({errorHandler: handleErrors}))
+ /* having empty src as we dont have to read any files*/
+ .pipe(inject(gulp.src('', {read: false}), {
+ starttag: '',
+ removeTags: true,
+ transform: function () {
+ return '';
+ }
+ }))
+ .pipe(gulp.dest(config.app));
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/gulp/serve.js b/jhipster/jhipster-microservice/gateway-app/gulp/serve.js
new file mode 100644
index 0000000000..243a01784f
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/gulp/serve.js
@@ -0,0 +1,62 @@
+'use strict';
+
+var gulp = require('gulp'),
+ util = require('./utils'),
+ url = require('url'),
+ browserSync = require('browser-sync'),
+ proxy = require('proxy-middleware');
+
+var config = require('./config');
+
+module.exports = function () {
+ var baseUri = config.uri + config.apiPort;
+ // Routes to proxy to the backend. Routes ending with a / will setup
+ // a redirect so that if accessed without a trailing slash, will
+ // redirect. This is required for some endpoints for proxy-middleware
+ // to correctly handle them.
+ var proxyRoutes = [
+ '/'
+ ];
+
+ var requireTrailingSlash = proxyRoutes.filter(function (r) {
+ return util.endsWith(r, '/');
+ }).map(function (r) {
+ // Strip trailing slash so we can use the route to match requests
+ // with non trailing slash
+ return r.substr(0, r.length - 1);
+ });
+
+ var proxies = [
+ // Ensure trailing slash in routes that require it
+ function (req, res, next) {
+ requireTrailingSlash.forEach(function (route){
+ if (url.parse(req.url).path === route) {
+ res.statusCode = 301;
+ res.setHeader('Location', route + '/');
+ res.end();
+ }
+ });
+
+ next();
+ }
+ ]
+ .concat(
+ // Build a list of proxies for routes: [route1_proxy, route2_proxy, ...]
+ proxyRoutes.map(function (r) {
+ var options = url.parse(baseUri + r);
+ options.route = r;
+ options.preserveHost = true;
+ return proxy(options);
+ }));
+
+ browserSync({
+ open: true,
+ port: config.port,
+ server: {
+ baseDir: config.app,
+ middleware: proxies
+ }
+ });
+
+ gulp.start('watch');
+};
diff --git a/jhipster/jhipster-microservice/gateway-app/gulp/utils.js b/jhipster/jhipster-microservice/gateway-app/gulp/utils.js
new file mode 100644
index 0000000000..abb80d3e31
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/gulp/utils.js
@@ -0,0 +1,36 @@
+'use strict';
+
+var fs = require('fs');
+
+module.exports = {
+ endsWith : endsWith,
+ parseVersion : parseVersion,
+ isLintFixed : isLintFixed
+};
+
+function endsWith(str, suffix) {
+ return str.indexOf('/', str.length - suffix.length) !== -1;
+}
+
+var parseString = require('xml2js').parseString;
+// return the version number from `pom.xml` file
+function parseVersion() {
+ var version = null;
+ var pomXml = fs.readFileSync('pom.xml', 'utf8');
+ parseString(pomXml, function (err, result) {
+ if (result.project.version && result.project.version[0]) {
+ version = result.project.version[0];
+ } else if (result.project.parent && result.project.parent[0] && result.project.parent[0].version && result.project.parent[0].version[0]) {
+ version = result.project.parent[0].version[0];
+ }
+ });
+ if (version === null) {
+ throw new Error('pom.xml is malformed. No version is defined');
+ }
+ return version;
+}
+
+function isLintFixed(file) {
+ // Has ESLint fixed the file contents?
+ return file.eslint !== null && file.eslint.fixed;
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/gulpfile.js b/jhipster/jhipster-microservice/gateway-app/gulpfile.js
new file mode 100644
index 0000000000..e4b86a0df0
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/gulpfile.js
@@ -0,0 +1,166 @@
+// Generated on 2017-05-03 using generator-jhipster 4.0.8
+'use strict';
+
+var gulp = require('gulp'),
+ rev = require('gulp-rev'),
+ templateCache = require('gulp-angular-templatecache'),
+ htmlmin = require('gulp-htmlmin'),
+ imagemin = require('gulp-imagemin'),
+ ngConstant = require('gulp-ng-constant'),
+ rename = require('gulp-rename'),
+ eslint = require('gulp-eslint'),
+ del = require('del'),
+ runSequence = require('run-sequence'),
+ browserSync = require('browser-sync'),
+ KarmaServer = require('karma').Server,
+ plumber = require('gulp-plumber'),
+ changed = require('gulp-changed'),
+ gulpIf = require('gulp-if');
+
+var handleErrors = require('./gulp/handle-errors'),
+ serve = require('./gulp/serve'),
+ util = require('./gulp/utils'),
+ copy = require('./gulp/copy'),
+ inject = require('./gulp/inject'),
+ build = require('./gulp/build');
+
+var config = require('./gulp/config');
+
+gulp.task('clean', function () {
+ return del([config.dist], { dot: true });
+});
+
+gulp.task('copy', ['copy:fonts', 'copy:common']);
+
+gulp.task('copy:fonts', copy.fonts);
+
+gulp.task('copy:common', copy.common);
+
+gulp.task('copy:swagger', copy.swagger);
+
+gulp.task('copy:images', copy.images);
+
+gulp.task('images', function () {
+ return gulp.src(config.app + 'content/images/**')
+ .pipe(plumber({errorHandler: handleErrors}))
+ .pipe(changed(config.dist + 'content/images'))
+ .pipe(imagemin({optimizationLevel: 5, progressive: true, interlaced: true}))
+ .pipe(rev())
+ .pipe(gulp.dest(config.dist + 'content/images'))
+ .pipe(rev.manifest(config.revManifest, {
+ base: config.dist,
+ merge: true
+ }))
+ .pipe(gulp.dest(config.dist))
+ .pipe(browserSync.reload({stream: true}));
+});
+
+
+gulp.task('styles', [], function () {
+ return gulp.src(config.app + 'content/css')
+ .pipe(browserSync.reload({stream: true}));
+});
+
+gulp.task('inject', function() {
+ runSequence('inject:dep', 'inject:app');
+});
+
+gulp.task('inject:dep', ['inject:test', 'inject:vendor']);
+
+gulp.task('inject:app', inject.app);
+
+gulp.task('inject:vendor', inject.vendor);
+
+gulp.task('inject:test', inject.test);
+
+gulp.task('inject:troubleshoot', inject.troubleshoot);
+
+gulp.task('assets:prod', ['images', 'styles', 'html', 'copy:swagger', 'copy:images'], build);
+
+gulp.task('html', function () {
+ return gulp.src(config.app + 'app/**/*.html')
+ .pipe(htmlmin({collapseWhitespace: true}))
+ .pipe(templateCache({
+ module: 'gatewayApp',
+ root: 'app/',
+ moduleSystem: 'IIFE'
+ }))
+ .pipe(gulp.dest(config.tmp));
+});
+
+gulp.task('ngconstant:dev', function () {
+ return ngConstant({
+ name: 'gatewayApp',
+ constants: {
+ VERSION: util.parseVersion(),
+ DEBUG_INFO_ENABLED: true
+ },
+ template: config.constantTemplate,
+ stream: true
+ })
+ .pipe(rename('app.constants.js'))
+ .pipe(gulp.dest(config.app + 'app/'));
+});
+
+gulp.task('ngconstant:prod', function () {
+ return ngConstant({
+ name: 'gatewayApp',
+ constants: {
+ VERSION: util.parseVersion(),
+ DEBUG_INFO_ENABLED: false
+ },
+ template: config.constantTemplate,
+ stream: true
+ })
+ .pipe(rename('app.constants.js'))
+ .pipe(gulp.dest(config.app + 'app/'));
+});
+
+// check app for eslint errors
+gulp.task('eslint', function () {
+ return gulp.src(['gulpfile.js', config.app + 'app/**/*.js'])
+ .pipe(plumber({errorHandler: handleErrors}))
+ .pipe(eslint())
+ .pipe(eslint.format())
+ .pipe(eslint.failOnError());
+});
+
+// check app for eslint errors anf fix some of them
+gulp.task('eslint:fix', function () {
+ return gulp.src(config.app + 'app/**/*.js')
+ .pipe(plumber({errorHandler: handleErrors}))
+ .pipe(eslint({
+ fix: true
+ }))
+ .pipe(eslint.format())
+ .pipe(gulpIf(util.isLintFixed, gulp.dest(config.app + 'app')));
+});
+
+gulp.task('test', ['inject:test', 'ngconstant:dev'], function (done) {
+ new KarmaServer({
+ configFile: __dirname + '/' + config.test + 'karma.conf.js',
+ singleRun: true
+ }, done).start();
+});
+
+
+gulp.task('watch', function () {
+ gulp.watch('bower.json', ['install']);
+ gulp.watch(['gulpfile.js', 'pom.xml'], ['ngconstant:dev']);
+ gulp.watch(config.app + 'content/css/**/*.css', ['styles']);
+ gulp.watch(config.app + 'content/images/**', ['images']);
+ gulp.watch(config.app + 'app/**/*.js', ['inject:app']);
+ gulp.watch([config.app + '*.html', config.app + 'app/**', config.app + 'i18n/**']).on('change', browserSync.reload);
+});
+
+gulp.task('install', function () {
+ runSequence(['inject:dep', 'ngconstant:dev'], 'inject:app', 'inject:troubleshoot');
+});
+
+gulp.task('serve', ['install'], serve);
+
+gulp.task('build', ['clean'], function (cb) {
+ runSequence(['copy', 'inject:vendor', 'ngconstant:prod'], 'inject:app', 'inject:troubleshoot', 'assets:prod', cb);
+});
+
+gulp.task('default', ['serve']);
diff --git a/jhipster/jhipster-microservice/gateway-app/mvnw b/jhipster/jhipster-microservice/gateway-app/mvnw
new file mode 100755
index 0000000000..a1ba1bf554
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/mvnw
@@ -0,0 +1,233 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven2 Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ #
+ # Look for the Apple JDKs first to preserve the existing behaviour, and then look
+ # for the new JDKs provided by Oracle.
+ #
+ if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
+ #
+ # Oracle JDKs
+ #
+ export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=`/usr/libexec/java_home`
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Migwn, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+ # TODO classpath?
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`which java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+fi
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+ local basedir=$(pwd)
+ local wdir=$(pwd)
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ wdir=$(cd "$wdir/.."; pwd)
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} "$@"
diff --git a/jhipster/jhipster-microservice/gateway-app/mvnw.cmd b/jhipster/jhipster-microservice/gateway-app/mvnw.cmd
new file mode 100644
index 0000000000..2b934e89dd
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/mvnw.cmd
@@ -0,0 +1,145 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven2 Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+set MAVEN_CMD_LINE_ARGS=%*
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+
+set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
\ No newline at end of file
diff --git a/jhipster/jhipster-microservice/gateway-app/package.json b/jhipster/jhipster-microservice/gateway-app/package.json
new file mode 100644
index 0000000000..ece70314ab
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/package.json
@@ -0,0 +1,68 @@
+{
+ "name": "gateway",
+ "version": "0.0.0",
+ "description": "Description for gateway",
+ "private": true,
+ "cacheDirectories": [
+ "node_modules",
+ "src/main/webapp/bower_components"
+ ],
+ "devDependencies": {
+ "bower": "1.7.9",
+ "browser-sync": "2.17.0",
+ "del": "2.2.2",
+ "eslint-config-angular": "0.5.0",
+ "eslint-plugin-angular": "1.3.1",
+ "event-stream": "3.3.4",
+ "generator-jhipster": "4.0.8",
+ "gulp": "3.9.1",
+ "gulp-angular-filesort": "1.1.1",
+ "gulp-angular-templatecache": "2.0.0",
+ "gulp-autoprefixer": "3.1.1",
+ "gulp-changed": "1.3.2",
+ "gulp-cssnano": "2.1.2",
+ "gulp-eslint": "3.0.1",
+ "gulp-flatten": "0.3.1",
+ "gulp-footer": "1.0.5",
+ "gulp-htmlmin": "2.0.0",
+ "gulp-if": "2.0.1",
+ "gulp-imagemin": "3.0.3",
+ "gulp-inject": "4.1.0",
+ "gulp-natural-sort": "0.1.1",
+ "gulp-ng-annotate": "2.0.0",
+ "gulp-ng-constant": "1.1.0",
+ "gulp-notify": "2.2.0",
+ "gulp-plumber": "1.1.0",
+ "gulp-rename": "1.2.2",
+ "gulp-replace": "0.5.4",
+ "gulp-rev": "7.1.2",
+ "gulp-rev-replace": "0.4.3",
+ "gulp-sourcemaps": "1.6.0",
+ "gulp-uglify": "2.0.0",
+ "gulp-useref": "3.1.2",
+ "jasmine-core": "2.5.0",
+ "karma": "1.2.0",
+ "karma-chrome-launcher": "2.0.0",
+ "karma-coverage": "1.1.1",
+ "karma-jasmine": "1.0.2",
+ "karma-junit-reporter": "1.1.0",
+ "karma-phantomjs-launcher": "1.0.2",
+ "karma-script-launcher": "1.0.0",
+ "lazypipe": "1.0.1",
+ "lodash": "4.15.0",
+ "main-bower-files": "2.13.1",
+ "map-stream": "0.0.6",
+ "phantomjs-prebuilt": "2.1.12",
+ "proxy-middleware": "0.15.0",
+ "run-sequence": "1.2.2",
+ "xml2js": "0.4.17",
+
+ "yargs": "5.0.0"
+ },
+ "engines": {
+ "node": "^4.3"
+ },
+ "scripts": {
+ "test": "gulp test"
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/pom.xml b/jhipster/jhipster-microservice/gateway-app/pom.xml
new file mode 100644
index 0000000000..32aa432279
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/pom.xml
@@ -0,0 +1,1039 @@
+
+
+ 4.0.0
+
+
+ parent-boot-5
+ com.baeldung
+ 0.0.1-SNAPSHOT
+ ../../../parent-boot-5
+
+
+ com.gateway
+ gateway
+ 0.0.1-SNAPSHOT
+ war
+ Gateway
+
+
+ ${maven.version}
+
+
+
+ -Djava.security.egd=file:/dev/./urandom -Xmx256m
+ 3.6.2
+ 2.0.0
+ 1.10
+ 2.5
+ 3.5
+ 0.4.13
+ 1.3
+ 1.2
+ 5.2.8.Final
+ 2.6.0
+ 0.7.9
+ 3.21.0-GA
+ 1.0.0
+ 1.1.0
+ 0.7.0
+ 3.6
+ 2.0.0
+ 4.8
+ 1.3.0
+ jdt_apt
+ 1.1.0.Final
+ 1.4.1
+ 3.0.1
+ yyyyMMddHHmmss
+ 3.0.0
+ 3.1.3
+ v6.10.0
+
+
+
+ 0.0.20
+
+ ${project.build.directory}/test-results
+ false
+ 3.2.2
+ 2.12.1
+ 3.2
+
+ src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.*
+
+ S3437,UndocumentedApi,BoldAndItalicTagsCheck
+
+
+ src/main/webapp/app/**/*.*
+ Web:BoldAndItalicTagsCheck
+
+ src/main/java/**/*
+ squid:S3437
+
+ src/main/java/**/*
+ squid:UndocumentedApi
+
+ ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec
+ ${project.testresult.directory}/coverage/jacoco/jacoco.exec
+ jacoco
+
+ ${project.testresult.directory}/karma
+
+ ${project.testresult.directory}/coverage/report-lcov/lcov.info
+
+ ${project.testresult.directory}/coverage/report-lcov/lcov.info
+
+ ${project.basedir}/src/main/
+ ${project.testresult.directory}/surefire-reports
+ ${project.basedir}/src/test/
+
+ 2.5.0
+
+ Camden.SR5
+ 2.6.1
+ 1.4.10.Final
+ 1.1.0.Final
+ v0.21.3
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+
+
+ io.github.jhipster
+ jhipster
+ ${jhipster.server.version}
+
+
+ io.dropwizard.metrics
+ metrics-core
+
+
+ io.dropwizard.metrics
+ metrics-annotation
+ ${dropwizard-metrics.version}
+
+
+ io.dropwizard.metrics
+ metrics-json
+ ${dropwizard-metrics.version}
+
+
+ io.dropwizard.metrics
+ metrics-jvm
+ ${dropwizard-metrics.version}
+
+
+ io.dropwizard.metrics
+ metrics-servlet
+ ${dropwizard-metrics.version}
+
+
+ io.dropwizard.metrics
+ metrics-servlets
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-hibernate5
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-hppc
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-json-org
+
+
+ com.h2database
+ h2
+
+
+ com.hazelcast
+ hazelcast
+
+
+ com.hazelcast
+ hazelcast-hibernate52
+ ${hazelcast-hibernate52.version}
+
+
+ com.hazelcast
+ hazelcast-spring
+
+
+ org.awaitility
+ awaitility
+ ${awaitility.version}
+ test
+
+
+ com.jayway.jsonpath
+ json-path
+ test
+
+
+
+ io.springfox
+ springfox-swagger2
+ ${springfox.version}
+
+
+ org.mapstruct
+ mapstruct
+
+
+
+
+ io.springfox
+ springfox-bean-validators
+ ${springfox.version}
+
+
+ com.mattbertolini
+ liquibase-slf4j
+ ${liquibase-slf4j.version}
+
+
+ com.ryantenney.metrics
+ metrics-spring
+ ${metrics-spring.version}
+
+
+ com.codahale.metrics
+ metrics-annotation
+
+
+ com.codahale.metrics
+ metrics-core
+
+
+ com.codahale.metrics
+ metrics-healthchecks
+
+
+
+
+ com.zaxxer
+ HikariCP
+
+
+ tools
+ com.sun
+
+
+
+
+
+ commons-codec
+ commons-codec
+ ${commons-codec.version}
+
+
+ commons-io
+ commons-io
+ ${commons-io.version}
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang.version}
+
+
+ javax.cache
+ cache-api
+
+
+ mysql
+ mysql-connector-java
+
+
+ net.jpountz.lz4
+ lz4
+ ${lz4.version}
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+ org.hibernate
+ hibernate-envers
+
+
+ org.hibernate
+ hibernate-validator
+
+
+ org.liquibase
+ liquibase-core
+
+
+ jetty-servlet
+ org.eclipse.jetty
+
+
+
+
+ org.mapstruct
+ mapstruct-jdk8
+ ${mapstruct.version}
+
+
+ org.springframework
+ spring-context-support
+
+
+ org.springframework.boot
+ spring-boot-actuator
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+ org.springframework.boot
+ spring-boot-loader-tools
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-logging
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+
+
+
+
+ io.jsonwebtoken
+ jjwt
+ ${jjwt.version}
+
+
+
+ com.datastax.cassandra
+ cassandra-driver-core
+
+
+ com.codahale.metrics
+ metrics-core
+
+
+
+
+ com.datastax.cassandra
+ cassandra-driver-extras
+ ${cassandra-driver.version}
+
+
+ com.datastax.cassandra
+ cassandra-driver-mapping
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-zuul
+
+
+ org.springframework.cloud
+ spring-cloud-starter
+
+
+ org.springframework.cloud
+ spring-cloud-starter-ribbon
+
+
+
+ io.netty
+ netty-transport-native-epoll
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-hystrix
+
+
+ org.springframework.cloud
+ spring-cloud-starter-spectator
+
+
+ org.springframework.retry
+ spring-retry
+
+
+ org.springframework.cloud
+ spring-cloud-starter-eureka
+
+
+ org.springframework.cloud
+ spring-cloud-starter-config
+
+
+ org.springframework.cloud
+ spring-cloud-starter-feign
+
+
+ net.logstash.logback
+ logstash-logback-encoder
+ ${logstash-logback-encoder.version}
+
+
+ ch.qos.logback
+ logback-core
+
+
+ ch.qos.logback
+ logback-classic
+
+
+ ch.qos.logback
+ logback-access
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-cloud-connectors
+
+
+
+ org.springframework.security
+ spring-security-data
+
+
+
+
+ spring-boot:run
+
+
+ com.github.ekryd.sortpom
+ sortpom-maven-plugin
+ ${sortpom-maven-plugin.version}
+
+
+ verify
+
+ sort
+
+
+
+
+ true
+ 4
+ groupId,artifactId
+ groupId,artifactId
+ true
+ false
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${mapstruct.version}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-eclipse-plugin
+
+ true
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ ${maven-enforcer-plugin.version}
+
+
+ enforce-versions
+
+ enforce
+
+
+
+
+
+
+ You are running an older version of Maven. JHipster requires at least Maven ${maven.version}
+ [${maven.version},)
+
+
+ You are running an older version of Java. JHipster requires at least JDK ${java.version}
+ [${java.version}.0,)
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ ${maven-resources-plugin.version}
+
+
+ default-resources
+ validate
+
+ copy-resources
+
+
+ target/classes
+ false
+
+ #
+
+
+
+ src/main/resources/
+ true
+
+ **/*.xml
+ **/*.yml
+
+
+
+ src/main/resources/
+ false
+
+ **/*.xml
+ **/*.yml
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ alphabetical
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco-maven-plugin.version}
+
+
+ pre-unit-tests
+
+ prepare-agent
+
+
+
+ ${project.testresult.directory}/coverage/jacoco/jacoco.exec
+
+
+
+
+ post-unit-test
+ test
+
+ report
+
+
+ ${project.testresult.directory}/coverage/jacoco/jacoco.exec
+ ${project.testresult.directory}/coverage/jacoco
+
+
+
+
+
+ org.sonarsource.scanner.maven
+ sonar-maven-plugin
+ ${sonar-maven-plugin.version}
+
+
+ org.liquibase
+ liquibase-maven-plugin
+ ${liquibase.version}
+
+ src/main/resources/config/liquibase/master.xml
+ src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml
+ org.h2.Driver
+ jdbc:h2:file:./target/h2db/db/gateway
+
+ gateway
+
+ hibernate:spring:com.gateway.domain?dialect=org.hibernate.dialect.H2Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
+ true
+ debug
+
+
+
+ org.javassist
+ javassist
+ ${javassist.version}
+
+
+ org.liquibase.ext
+ liquibase-hibernate5
+ ${liquibase-hibernate5.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+ ${project.parent.version}
+
+
+ javax.validation
+ validation-api
+ ${validation-api.version}
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+ true
+
+
+
+
+ com.spotify
+ docker-maven-plugin
+ ${docker-maven-plugin.version}
+
+ gateway
+ src/main/docker
+
+
+ /
+ ${project.build.directory}
+ ${project.build.finalName}.war
+
+
+
+
+
+
+
+
+
+
+ org.eclipse.m2e
+ lifecycle-mapping
+ 1.0.0
+
+
+
+
+
+ org.jacoco
+
+ jacoco-maven-plugin
+
+
+ ${jacoco-maven-plugin.version}
+
+
+ prepare-agent
+
+
+
+
+
+
+
+
+ com.github.eirslett
+ frontend-maven-plugin
+ ${frontend-maven-plugin.version}
+
+ install-node-and-yarn
+ yarn
+ bower
+ gulp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ no-liquibase
+
+ ,no-liquibase
+
+
+
+ swagger
+
+ ,swagger
+
+
+
+ dev
+
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-undertow
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ src/main/webapp/
+
+
+
+
+
+
+ DEBUG
+
+ dev${profile.no-liquibase}
+
+
+
+ prod
+
+
+ org.springframework.boot
+ spring-boot-starter-undertow
+
+
+
+
+
+ maven-clean-plugin
+
+
+
+ target/www/
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ target/www/
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+ build-info
+
+
+
+
+
+ com.github.eirslett
+ frontend-maven-plugin
+ ${frontend-maven-plugin.version}
+
+
+ install node and yarn
+
+ install-node-and-yarn
+
+
+ ${node.version}
+ ${yarn.version}
+
+
+
+ yarn install
+
+ yarn
+
+
+ install
+
+
+
+ bower install
+
+ bower
+
+
+ install --no-color
+
+
+
+ gulp build
+
+ gulp
+
+
+ build --no-notification
+
+
+
+ gulp test
+
+ gulp
+
+ test
+
+ test --no-notification
+
+
+
+
+
+
+
+
+ INFO
+
+ prod${profile.swagger}${profile.no-liquibase}
+
+
+
+
+ cc
+
+
+ org.springframework.boot
+ spring-boot-starter-undertow
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ src/main/webapp/
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+ true
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ default-compile
+ none
+
+
+ default-testCompile
+ none
+
+
+
+
+ net.alchim31.maven
+ scala-maven-plugin
+ ${scala-maven-plugin.version}
+
+
+ compile
+ compile
+
+ add-source
+ compile
+
+
+
+ test-compile
+ test-compile
+
+ add-source
+ testCompile
+
+
+
+
+ incremental
+ true
+ ${scala.version}
+
+
+
+
+
+
+ DEBUG
+
+ dev,swagger
+
+
+
+
+ graphite
+
+
+ io.dropwizard.metrics
+ metrics-graphite
+
+
+
+
+
+ prometheus
+
+
+ io.prometheus
+ simpleclient
+ ${prometheus-simpleclient.version}
+
+
+ io.prometheus
+ simpleclient_servlet
+ ${prometheus-simpleclient.version}
+
+
+ io.prometheus
+ simpleclient_dropwizard
+ ${prometheus-simpleclient.version}
+
+
+
+
+
+ IDE
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${mapstruct.version}
+
+
+
+
+
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/Dockerfile b/jhipster/jhipster-microservice/gateway-app/src/main/docker/Dockerfile
new file mode 100644
index 0000000000..08c44eb8cf
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/Dockerfile
@@ -0,0 +1,13 @@
+FROM openjdk:8-jre-alpine
+
+ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
+ JHIPSTER_SLEEP=0
+
+# add directly the war
+ADD *.war /app.war
+
+VOLUME /tmp
+EXPOSE 8080 5701/udp
+CMD echo "The application will start in ${JHIPSTER_SLEEP}s..." && \
+ sleep ${JHIPSTER_SLEEP} && \
+ java -Djava.security.egd=file:/dev/./urandom -jar /app.war
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/app.yml b/jhipster/jhipster-microservice/gateway-app/src/main/docker/app.yml
new file mode 100644
index 0000000000..bb53e40da5
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/app.yml
@@ -0,0 +1,38 @@
+#-------------------------------------------------------------------------------
+# Note for using the rate-limiting:
+# The comment part won't be copied if you use the subgenerator docker-compose
+# you have to manually copy it
+#-------------------------------------------------------------------------------
+version: '2'
+services:
+ gateway-app:
+ image: gateway
+ environment:
+ - SPRING_PROFILES_ACTIVE=prod,swagger
+ - SPRING_CLOUD_CONFIG_URI=http://admin:$${jhipster.registry.password}@jhipster-registry:8761/config
+ - SPRING_DATASOURCE_URL=jdbc:mysql://gateway-mysql:3306/gateway?useUnicode=true&characterEncoding=utf8&useSSL=false
+ - SPRING_DATA_CASSANDRA_CONTACTPOINTS=gateway-cassandra
+ - JHIPSTER_SLEEP=30 # gives time for the Cassandra cluster to start and execute the migration scripts
+ ports:
+ - 8080:8080
+ gateway-mysql:
+ extends:
+ file: mysql.yml
+ service: gateway-mysql
+ # Uncomment to have Cassandra working with the gateway
+ # gateway-cassandra:
+ # extends:
+ # file: cassandra-cluster.yml
+ # service: gateway-cassandra
+ # gateway-cassandra-migration:
+ # extends:
+ # file: cassandra-migration.yml
+ # service: gateway-cassandra-migration
+ # environment:
+ # - CREATE_KEYSPACE_SCRIPT=create-keyspace-prod.cql
+ jhipster-registry:
+ extends:
+ file: jhipster-registry.yml
+ service: jhipster-registry
+ environment:
+ - SPRING_CLOUD_CONFIG_SERVER_NATIVE_SEARCH_LOCATIONS=file:./central-config/docker-config/
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra-cluster.yml b/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra-cluster.yml
new file mode 100644
index 0000000000..1329b4d3f3
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra-cluster.yml
@@ -0,0 +1,22 @@
+version: '2'
+services:
+ gateway-cassandra:
+ image: cassandra:3.9
+ # volumes:
+ # - ~/volumes/jhipster/gateway/cassandra/:/var/lib/cassandra/data
+ ports:
+ - 7000:7000
+ - 7001:7001
+ - 7199:7199
+ - 9042:9042
+ - 9160:9160
+ gateway-cassandra-node:
+ image: cassandra:3.9
+ environment:
+ - CASSANDRA_SEEDS=gateway-cassandra
+ gateway-cassandra-migration:
+ extends:
+ file: cassandra-migration.yml
+ service: gateway-cassandra-migration
+ environment:
+ - CREATE_KEYSPACE_SCRIPT=create-keyspace-prod.cql
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra-migration.yml b/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra-migration.yml
new file mode 100644
index 0000000000..3e24f7814c
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra-migration.yml
@@ -0,0 +1,12 @@
+version: '2'
+services:
+ gateway-cassandra-migration:
+ environment:
+ - CASSANDRA_CONTACT_POINT=gateway-cassandra
+ - USER=docker-cassandra-migration
+ # - DEBUG_LOG=1 # uncomment to show debug logs during the migration process
+ build:
+ context: .
+ dockerfile: cassandra/Cassandra-Migration.Dockerfile
+ volumes:
+ - ../resources/config/cql:/cql:ro
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra.yml b/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra.yml
new file mode 100644
index 0000000000..afb20a9732
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra.yml
@@ -0,0 +1,18 @@
+version: '2'
+services:
+ gateway-cassandra:
+ image: cassandra:3.9
+ # volumes:
+ # - ~/volumes/jhipster/gateway/cassandra/:/var/lib/cassandra/data
+ ports:
+ - 7000:7000
+ - 7001:7001
+ - 7199:7199
+ - 9042:9042
+ - 9160:9160
+ gateway-cassandra-migration:
+ extends:
+ file: cassandra-migration.yml
+ service: gateway-cassandra-migration
+ environment:
+ - CREATE_KEYSPACE_SCRIPT=create-keyspace.cql
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra/Cassandra-Migration.Dockerfile b/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra/Cassandra-Migration.Dockerfile
new file mode 100644
index 0000000000..e5ceb1e56a
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra/Cassandra-Migration.Dockerfile
@@ -0,0 +1,11 @@
+FROM cassandra:3.9
+
+# script to orchestrate the automatic keyspace creation and apply all migration scripts
+ADD cassandra/scripts/autoMigrate.sh /usr/local/bin/autoMigrate
+RUN chmod 755 /usr/local/bin/autoMigrate
+
+# script to run any cql script from src/main/resources/config/cql
+ADD cassandra/scripts/execute-cql.sh /usr/local/bin/execute-cql
+RUN chmod 755 /usr/local/bin/execute-cql
+
+ENTRYPOINT ["autoMigrate"]
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra/scripts/autoMigrate.sh b/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra/scripts/autoMigrate.sh
new file mode 100755
index 0000000000..83ed6347a2
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra/scripts/autoMigrate.sh
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+
+# Orchestrate the automatic execution of all the cql migration scripts when starting the cluster
+
+# Protect from iterating on empty directories
+shopt -s nullglob
+
+function log {
+ echo "[$(date)]: $*"
+}
+
+function logDebug {
+ ((DEBUG_LOG)) && echo "[DEBUG][$(date)]: $*"
+}
+
+function waitForClusterConnection() {
+ log "Waiting for Cassandra connection..."
+ retryCount=0
+ maxRetry=20
+ cqlsh -e "Describe KEYSPACES;" $CASSANDRA_CONTACT_POINT &>/dev/null
+ while [ $? -ne 0 ] && [ "$retryCount" -ne "$maxRetry" ]; do
+ logDebug 'Cassandra not reachable yet. sleep and retry. retryCount =' $retryCount
+ sleep 5
+ ((retryCount+=1))
+ cqlsh -e "Describe KEYSPACES;" $CASSANDRA_CONTACT_POINT &>/dev/null
+ done
+
+ if [ $? -ne 0 ]; then
+ log "Not connected after " $retryCount " retry. Abort the migration."
+ exit 1
+ fi
+
+ log "Connected to Cassandra cluster"
+}
+
+function executeScripts() {
+ local filePattern=$1
+ # loop over migration scripts
+ for cqlFile in $filePattern; do
+ . $EXECUTE_CQL_SCRIPT $cqlFile
+ done
+}
+
+# parse arguments
+if [ "$#" -gt 0 ]; then
+ log "Override for local usage"
+ CQL_FILES_PATH=$1
+ CREATE_KEYSPACE_SCRIPT="create-keyspace.cql" # default create-keyspace script
+ if [ "$#" -eq 2 ]; then
+ CREATE_KEYSPACE_SCRIPT=$2
+ fi
+ CREATE_KEYSPACE_SCRIPT_FOLDER="$(dirname $CQL_FILES_PATH)"
+ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+ EXECUTE_CQL_SCRIPT=$SCRIPT_DIR'/execute-cql.sh'
+else
+ CQL_FILES_PATH="/cql/changelog/"
+ EXECUTE_CQL_SCRIPT="./usr/local/bin/execute-cql"
+ CREATE_KEYSPACE_SCRIPT_FOLDER="/cql"
+fi
+
+log "Start Cassandra migration tool"
+waitForClusterConnection
+log "Use $CREATE_KEYSPACE_SCRIPT_FOLDER/$CREATE_KEYSPACE_SCRIPT script to create the keyspace if necessary"
+cqlsh -f $CREATE_KEYSPACE_SCRIPT_FOLDER'/'$CREATE_KEYSPACE_SCRIPT $CASSANDRA_CONTACT_POINT
+log "Execute all non already executed scripts from $CQL_FILES_PATH"
+executeScripts "$CQL_FILES_PATH*.cql"
+log "Migration done"
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra/scripts/execute-cql.sh b/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra/scripts/execute-cql.sh
new file mode 100755
index 0000000000..39739b56fe
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/cassandra/scripts/execute-cql.sh
@@ -0,0 +1,124 @@
+#!/usr/bin/env bash
+
+KEYSPACE_NAME=gateway
+
+unset scripts
+declare -A scripts
+
+function log {
+ echo "[$(date)]: $*"
+}
+
+function logDebug {
+ ((DEBUG_LOG)) && echo "[DEBUG][$(date)]: $*"
+}
+
+function exitWithError() {
+ echo "ERROR :
+ $*"
+ exit 1
+}
+
+#usage checks
+if [ -z "$1" ]; then
+ echo "usage: ./execute-cql cqlFile.cql"
+ exit 1
+fi
+if [ -z "$CASSANDRA_CONTACT_POINT" ]; then
+ echo "CASSANDRA_CONTACT_POINT environment variable must be defined"
+ exit 1
+fi
+
+cqlFile=$1
+filename=$(basename "$1")
+
+#load already executed scripts in the `scripts` global variable: dictionary[scriptName->checksum]
+function loadExecutedScripts {
+ #allow spaces in cqlsh output
+ IFS=$'\n'
+ local rows=($(cqlsh -k $KEYSPACE_NAME -e "select * from schema_version" $CASSANDRA_CONTACT_POINT | tail -n+4 | sed '$d' |sed '$d'))
+
+ for r in "${rows[@]}"
+ do
+ local scriptName=$(echo "$r" |cut -d '|' -f 1 | sed s'/^[[:space:]]*//' | sed s'/[[:space:]]*$//')
+ local checksum=$(echo "$r" |cut -d '|' -f 2 | sed s'/^[[:space:]]*//' | sed s'/[[:space:]]*$//')
+ scripts+=(["$scriptName"]="$checksum")
+ done
+ unset IFS
+}
+
+function exists {
+ if [ "$2" != in ]; then
+ echo "Incorrect usage."
+ echo "Correct usage: exists {key} in {array}"
+ return 1
+ fi
+
+ eval '[ ${'$3'[$1]+exists} ]'
+}
+
+function checksumEquals {
+ local checksum=$(md5sum $cqlFile | cut -d ' ' -f 1)
+ local foundChecksum=${scripts[${filename}]}
+
+ if [[ "$checksum" == "$foundChecksum" ]]; then
+ logDebug "checksum equals for $cqlFile, checksum=$checksum"
+ return 0
+ else
+ logDebug "different checksum found for $cqlFile
+ checksum=$checksum
+ foundChecksum=$foundChecksum"
+ return 1
+ fi
+}
+
+function isExecuted {
+ if exists $filename in scripts; then
+ if checksumEquals $cqlFile; then
+ return 0
+ else
+ exitWithError "$cqlFile has already been executed but has a different checksum logged in the schema_version table.
+ scripts must not be changed after being executed.
+ to resolve this issue you can:
+ - revert the modified script to its initial state and create a new script
+ OR
+ - delete the script entry from the schema_version table
+ "
+ fi
+ else
+ return 1
+ fi
+}
+
+function executeCqlScript {
+ log "execute: $cqlFile"
+ cqlsh -k $KEYSPACE_NAME -f $cqlFile $CASSANDRA_CONTACT_POINT
+
+ # if execution failed
+ if [ $? -ne 0 ]; then
+ exitWithError "fail to apply script $filename
+ stop applying database changes"
+ fi
+ logDebug "execution of $cqlFile succeeded"
+}
+
+function logExecutedScript {
+ local duration=$1
+ local checksum=$(md5sum $cqlFile | cut -d ' ' -f 1)
+
+ logDebug "save $cqlFile execution in schema_version table"
+ local query="INSERT INTO schema_version (script_name, checksum, executed_by, executed_on, execution_time, status) VALUES ('$filename', '$checksum', '$USER', toTimestamp(now()), $duration, 'success');"
+ cqlsh -k $KEYSPACE_NAME -e "$query" $CASSANDRA_CONTACT_POINT
+}
+
+loadExecutedScripts
+if isExecuted; then
+ logDebug "skipping $cqlFile already executed"
+else
+ _start=$(date +"%s")
+ executeCqlScript
+ _end=$(date +"%s")
+ duration=`expr $_end - $_start`
+ logExecutedScript $duration
+ log "$cqlFile executed with success in $duration seconds"
+fi
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/central-server-config/README.md b/jhipster/jhipster-microservice/gateway-app/src/main/docker/central-server-config/README.md
new file mode 100644
index 0000000000..022a152863
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/central-server-config/README.md
@@ -0,0 +1,7 @@
+# Central configuration sources details
+
+The JHipster-Registry will use the following directories as its configuration source :
+- localhost-config : when running the registry in docker with the jhipster-registry.yml docker-compose file
+- docker-config : when running the registry and the app both in docker with the app.yml docker-compose file
+
+For more info, refer to http://jhipster.github.io/microservices-architecture/#registry_app_configuration
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/central-server-config/docker-config/application.yml b/jhipster/jhipster-microservice/gateway-app/src/main/docker/central-server-config/docker-config/application.yml
new file mode 100644
index 0000000000..f11d367241
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/central-server-config/docker-config/application.yml
@@ -0,0 +1,15 @@
+# Common configuration shared between all applications
+configserver:
+ name: Docker JHipster Registry
+ status: Connected to the JHipster Registry running in Docker
+
+jhipster:
+ security:
+ authentication:
+ jwt:
+ secret: my-secret-token-to-change-in-production
+
+eureka:
+ client:
+ serviceUrl:
+ defaultZone: http://admin:${jhipster.registry.password}@jhipster-registry:8761/eureka/
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/central-server-config/localhost-config/application.yml b/jhipster/jhipster-microservice/gateway-app/src/main/docker/central-server-config/localhost-config/application.yml
new file mode 100644
index 0000000000..052a6d0535
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/central-server-config/localhost-config/application.yml
@@ -0,0 +1,15 @@
+# Common configuration shared between all applications
+configserver:
+ name: Docker JHipster Registry
+ status: Connected to the JHipster Registry running in Docker
+
+jhipster:
+ security:
+ authentication:
+ jwt:
+ secret: my-secret-token-to-change-in-production
+
+eureka:
+ client:
+ serviceUrl:
+ defaultZone: http://admin:${jhipster.registry.password}@localhost:8761/eureka/
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/jhipster-registry.yml b/jhipster/jhipster-microservice/gateway-app/src/main/docker/jhipster-registry.yml
new file mode 100644
index 0000000000..58feb685d4
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/jhipster-registry.yml
@@ -0,0 +1,18 @@
+version: '2'
+services:
+ jhipster-registry:
+ image: jhipster/jhipster-registry:v2.5.8
+ volumes:
+ - ./central-server-config:/central-config
+ # When run with the "dev" Spring profile, the JHipster Registry will
+ # read the config from the local filesystem (central-server-config directory)
+ # When run with the "prod" Spring profile, it will read the config from a git repository
+ # See http://jhipster.github.io/microservices-architecture/#registry_app_configuration
+ environment:
+ - SPRING_PROFILES_ACTIVE=dev
+ - SECURITY_USER_PASSWORD=admin
+ - SPRING_CLOUD_CONFIG_SERVER_NATIVE_SEARCH_LOCATIONS=file:./central-config/localhost-config/
+ # - GIT_URI=https://github.com/jhipster/jhipster-registry/
+ # - GIT_SEARCH_PATHS=central-config
+ ports:
+ - 8761:8761
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/mysql.yml b/jhipster/jhipster-microservice/gateway-app/src/main/docker/mysql.yml
new file mode 100644
index 0000000000..464243fd14
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/mysql.yml
@@ -0,0 +1,13 @@
+version: '2'
+services:
+ gateway-mysql:
+ image: mysql:5.7.13
+ # volumes:
+ # - ~/volumes/jhipster/gateway/mysql/:/var/lib/mysql/
+ environment:
+ - MYSQL_USER=root
+ - MYSQL_ALLOW_EMPTY_PASSWORD=yes
+ - MYSQL_DATABASE=gateway
+ ports:
+ - 3306:3306
+ command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/docker/sonar.yml b/jhipster/jhipster-microservice/gateway-app/src/main/docker/sonar.yml
new file mode 100644
index 0000000000..2790075014
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/docker/sonar.yml
@@ -0,0 +1,7 @@
+version: '2'
+services:
+ gateway-sonar:
+ image: sonarqube:6.2-alpine
+ ports:
+ - 9000:9000
+ - 9092:9092
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/ApplicationWebXml.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/ApplicationWebXml.java
new file mode 100644
index 0000000000..75c23ce9f5
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/ApplicationWebXml.java
@@ -0,0 +1,21 @@
+package com.gateway;
+
+import com.gateway.config.DefaultProfileUtil;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+
+/**
+ * This is a helper Java class that provides an alternative to creating a web.xml.
+ * This will be invoked only when the application is deployed to a servlet container like Tomcat, JBoss etc.
+ */
+public class ApplicationWebXml extends SpringBootServletInitializer {
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ /**
+ * set a default to use when no profile is configured.
+ */
+ DefaultProfileUtil.addDefaultProfile(application.application());
+ return application.sources(GatewayApp.class);
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/GatewayApp.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/GatewayApp.java
new file mode 100644
index 0000000000..1905b055b6
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/GatewayApp.java
@@ -0,0 +1,93 @@
+package com.gateway;
+
+import com.gateway.config.ApplicationProperties;
+import com.gateway.config.DefaultProfileUtil;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.actuate.autoconfigure.*;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.core.env.Environment;
+
+import javax.annotation.PostConstruct;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.Collection;
+
+@ComponentScan
+@EnableAutoConfiguration(exclude = {MetricFilterAutoConfiguration.class, MetricRepositoryAutoConfiguration.class, MetricsDropwizardAutoConfiguration.class})
+@EnableConfigurationProperties({LiquibaseProperties.class, ApplicationProperties.class})
+@EnableDiscoveryClient
+@EnableZuulProxy
+public class GatewayApp {
+
+ private static final Logger log = LoggerFactory.getLogger(GatewayApp.class);
+
+ private final Environment env;
+
+ public GatewayApp(Environment env) {
+ this.env = env;
+ }
+
+ /**
+ * Initializes gateway.
+ *
+ * Spring profiles can be configured with a program arguments --spring.profiles.active=your-active-profile
+ *
+ * You can find more information on how profiles work with JHipster on http://jhipster.github.io/profiles/.
+ */
+ @PostConstruct
+ public void initApplication() {
+ Collection activeProfiles = Arrays.asList(env.getActiveProfiles());
+ if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
+ log.error("You have misconfigured your application! It should not run " +
+ "with both the 'dev' and 'prod' profiles at the same time.");
+ }
+ if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD)) {
+ log.error("You have misconfigured your application! It should not" +
+ "run with both the 'dev' and 'cloud' profiles at the same time.");
+ }
+ }
+
+ /**
+ * Main method, used to run the application.
+ *
+ * @param args the command line arguments
+ * @throws UnknownHostException if the local host name could not be resolved into an address
+ */
+ public static void main(String[] args) throws UnknownHostException {
+ SpringApplication app = new SpringApplication(GatewayApp.class);
+ DefaultProfileUtil.addDefaultProfile(app);
+ Environment env = app.run(args).getEnvironment();
+ String protocol = "http";
+ if (env.getProperty("server.ssl.key-store") != null) {
+ protocol = "https";
+ }
+ log.info("\n----------------------------------------------------------\n\t" +
+ "Application '{}' is running! Access URLs:\n\t" +
+ "Local: \t\t{}://localhost:{}\n\t" +
+ "External: \t{}://{}:{}\n\t" +
+ "Profile(s): \t{}\n----------------------------------------------------------",
+ env.getProperty("spring.application.name"),
+ protocol,
+ env.getProperty("server.port"),
+ protocol,
+ InetAddress.getLocalHost().getHostAddress(),
+ env.getProperty("server.port"),
+ env.getActiveProfiles());
+
+ String configServerStatus = env.getProperty("configserver.status");
+ log.info("\n----------------------------------------------------------\n\t" +
+ "Config Server: \t{}\n----------------------------------------------------------",
+ configServerStatus == null ? "Not found or not setup for this application" : configServerStatus);
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/aop/logging/LoggingAspect.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/aop/logging/LoggingAspect.java
new file mode 100644
index 0000000000..dd2c4464be
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/aop/logging/LoggingAspect.java
@@ -0,0 +1,79 @@
+package com.gateway.aop.logging;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.env.Environment;
+
+import java.util.Arrays;
+
+/**
+ * Aspect for logging execution of service and repository Spring components.
+ *
+ * By default, it only runs with the "dev" profile.
+ */
+@Aspect
+public class LoggingAspect {
+
+ private final Logger log = LoggerFactory.getLogger(this.getClass());
+
+ private final Environment env;
+
+ public LoggingAspect(Environment env) {
+ this.env = env;
+ }
+
+ /**
+ * Pointcut that matches all repositories, services and Web REST endpoints.
+ */
+ @Pointcut("within(com.gateway.repository..*) || within(com.gateway.service..*) || within(com.gateway.web.rest..*)")
+ public void loggingPointcut() {
+ // Method is empty as this is just a Pointcut, the implementations are in the advices.
+ }
+
+ /**
+ * Advice that logs methods throwing exceptions.
+ */
+ @AfterThrowing(pointcut = "loggingPointcut()", throwing = "e")
+ public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
+ log.error("Exception in {}.{}() with cause = \'{}\' and exception = \'{}\'", joinPoint.getSignature().getDeclaringTypeName(),
+ joinPoint.getSignature().getName(), e.getCause() != null? e.getCause() : "NULL", e.getMessage(), e);
+
+ } else {
+ log.error("Exception in {}.{}() with cause = {}", joinPoint.getSignature().getDeclaringTypeName(),
+ joinPoint.getSignature().getName(), e.getCause() != null? e.getCause() : "NULL");
+ }
+ }
+
+ /**
+ * Advice that logs when a method is entered and exited.
+ */
+ @Around("loggingPointcut()")
+ public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
+ if (log.isDebugEnabled()) {
+ log.debug("Enter: {}.{}() with argument[s] = {}", joinPoint.getSignature().getDeclaringTypeName(),
+ joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs()));
+ }
+ try {
+ Object result = joinPoint.proceed();
+ if (log.isDebugEnabled()) {
+ log.debug("Exit: {}.{}() with result = {}", joinPoint.getSignature().getDeclaringTypeName(),
+ joinPoint.getSignature().getName(), result);
+ }
+ return result;
+ } catch (IllegalArgumentException e) {
+ log.error("Illegal argument: {} in {}.{}()", Arrays.toString(joinPoint.getArgs()),
+ joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
+
+ throw e;
+ }
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/ApplicationProperties.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/ApplicationProperties.java
new file mode 100644
index 0000000000..18e87d7966
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/ApplicationProperties.java
@@ -0,0 +1,15 @@
+package com.gateway.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Properties specific to JHipster.
+ *
+ *
+ * Properties are configured in the application.yml file.
+ *
+ */
+@ConfigurationProperties(prefix = "application", ignoreUnknownFields = false)
+public class ApplicationProperties {
+
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/AsyncConfiguration.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/AsyncConfiguration.java
new file mode 100644
index 0000000000..92ed89b5e4
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/AsyncConfiguration.java
@@ -0,0 +1,46 @@
+package com.gateway.config;
+
+import io.github.jhipster.async.ExceptionHandlingAsyncTaskExecutor;
+import io.github.jhipster.config.JHipsterProperties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
+import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.*;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+
+@Configuration
+@EnableAsync
+@EnableScheduling
+public class AsyncConfiguration implements AsyncConfigurer {
+
+ private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class);
+
+ private final JHipsterProperties jHipsterProperties;
+
+ public AsyncConfiguration(JHipsterProperties jHipsterProperties) {
+ this.jHipsterProperties = jHipsterProperties;
+ }
+
+ @Override
+ @Bean(name = "taskExecutor")
+ public Executor getAsyncExecutor() {
+ log.debug("Creating Async Task Executor");
+ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+ executor.setCorePoolSize(jHipsterProperties.getAsync().getCorePoolSize());
+ executor.setMaxPoolSize(jHipsterProperties.getAsync().getMaxPoolSize());
+ executor.setQueueCapacity(jHipsterProperties.getAsync().getQueueCapacity());
+ executor.setThreadNamePrefix("gateway-Executor-");
+ return new ExceptionHandlingAsyncTaskExecutor(executor);
+ }
+
+ @Override
+ public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+ return new SimpleAsyncUncaughtExceptionHandler();
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/CacheConfiguration.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/CacheConfiguration.java
new file mode 100644
index 0000000000..d5f464f490
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/CacheConfiguration.java
@@ -0,0 +1,134 @@
+package com.gateway.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+import io.github.jhipster.config.JHipsterProperties;
+
+import com.hazelcast.config.Config;
+import com.hazelcast.core.HazelcastInstance;
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.config.MapConfig;
+import com.hazelcast.config.EvictionPolicy;
+import com.hazelcast.config.MaxSizeConfig;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.context.annotation.*;
+import org.springframework.core.env.Environment;
+
+import javax.annotation.PreDestroy;
+
+@Configuration
+@EnableCaching
+@AutoConfigureAfter(value = { MetricsConfiguration.class })
+@AutoConfigureBefore(value = { WebConfigurer.class, DatabaseConfiguration.class })
+public class CacheConfiguration {
+
+ private final Logger log = LoggerFactory.getLogger(CacheConfiguration.class);
+
+ private final Environment env;
+
+ private final DiscoveryClient discoveryClient;
+
+ private final ServerProperties serverProperties;
+
+ public CacheConfiguration(Environment env, DiscoveryClient discoveryClient, ServerProperties serverProperties) {
+ this.env = env;
+ this.discoveryClient = discoveryClient;
+ this.serverProperties = serverProperties;
+ }
+
+ @PreDestroy
+ public void destroy() {
+ log.info("Closing Cache Manager");
+ Hazelcast.shutdownAll();
+ }
+
+ @Bean
+ public CacheManager cacheManager(HazelcastInstance hazelcastInstance) {
+ log.debug("Starting HazelcastCacheManager");
+ CacheManager cacheManager = new com.hazelcast.spring.cache.HazelcastCacheManager(hazelcastInstance);
+ return cacheManager;
+ }
+
+ @Bean
+ public HazelcastInstance hazelcastInstance(JHipsterProperties jHipsterProperties) {
+ log.debug("Configuring Hazelcast");
+ Config config = new Config();
+ config.setInstanceName("gateway");
+ // The serviceId is by default the application's name, see Spring Boot's eureka.instance.appname property
+ String serviceId = discoveryClient.getLocalServiceInstance().getServiceId();
+ log.debug("Configuring Hazelcast clustering for instanceId: {}", serviceId);
+
+ // In development, everything goes through 127.0.0.1, with a different port
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
+ log.debug("Application is running with the \"dev\" profile, Hazelcast " +
+ "cluster will only work with localhost instances");
+
+ System.setProperty("hazelcast.local.localAddress", "127.0.0.1");
+ config.getNetworkConfig().setPort(serverProperties.getPort() + 5701);
+ config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(true);
+ for (ServiceInstance instance : discoveryClient.getInstances(serviceId)) {
+ String clusterMember = "127.0.0.1:" + (instance.getPort() + 5701);
+ log.debug("Adding Hazelcast (dev) cluster member " + clusterMember);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().addMember(clusterMember);
+ }
+ } else { // Production configuration, one host per instance all using port 5701
+ config.getNetworkConfig().setPort(5701);
+ config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(true);
+ for (ServiceInstance instance : discoveryClient.getInstances(serviceId)) {
+ String clusterMember = instance.getHost() + ":5701";
+ log.debug("Adding Hazelcast (prod) cluster member " + clusterMember);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().addMember(clusterMember);
+ }
+ }
+ config.getMapConfigs().put("default", initializeDefaultMapConfig());
+ config.getMapConfigs().put("com.gateway.domain.*", initializeDomainMapConfig(jHipsterProperties));
+ return Hazelcast.newHazelcastInstance(config);
+ }
+
+ private MapConfig initializeDefaultMapConfig() {
+ MapConfig mapConfig = new MapConfig();
+
+ /*
+ Number of backups. If 1 is set as the backup-count for example,
+ then all entries of the map will be copied to another JVM for
+ fail-safety. Valid numbers are 0 (no backup), 1, 2, 3.
+ */
+ mapConfig.setBackupCount(0);
+
+ /*
+ Valid values are:
+ NONE (no eviction),
+ LRU (Least Recently Used),
+ LFU (Least Frequently Used).
+ NONE is the default.
+ */
+ mapConfig.setEvictionPolicy(EvictionPolicy.LRU);
+
+ /*
+ Maximum size of the map. When max size is reached,
+ map is evicted based on the policy defined.
+ Any integer between 0 and Integer.MAX_VALUE. 0 means
+ Integer.MAX_VALUE. Default is 0.
+ */
+ mapConfig.setMaxSizeConfig(new MaxSizeConfig(0, MaxSizeConfig.MaxSizePolicy.USED_HEAP_SIZE));
+
+ return mapConfig;
+ }
+
+ private MapConfig initializeDomainMapConfig(JHipsterProperties jHipsterProperties) {
+ MapConfig mapConfig = new MapConfig();
+ mapConfig.setTimeToLiveSeconds(jHipsterProperties.getCache().getHazelcast().getTimeToLiveSeconds());
+ return mapConfig;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/CloudDatabaseConfiguration.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/CloudDatabaseConfiguration.java
new file mode 100644
index 0000000000..ad025f4149
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/CloudDatabaseConfiguration.java
@@ -0,0 +1,24 @@
+package com.gateway.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cache.CacheManager;
+import org.springframework.cloud.config.java.AbstractCloudConfig;
+import org.springframework.context.annotation.*;
+
+import javax.sql.DataSource;
+
+@Configuration
+@Profile(JHipsterConstants.SPRING_PROFILE_CLOUD)
+public class CloudDatabaseConfiguration extends AbstractCloudConfig {
+
+ private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class);
+
+ @Bean
+ public DataSource dataSource(CacheManager cacheManager) {
+ log.info("Configuring JDBC datasource from a cloud provider");
+ return connectionFactory().dataSource();
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/Constants.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/Constants.java
new file mode 100644
index 0000000000..aa79156573
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/Constants.java
@@ -0,0 +1,16 @@
+package com.gateway.config;
+
+/**
+ * Application constants.
+ */
+public final class Constants {
+
+ //Regex for acceptable logins
+ public static final String LOGIN_REGEX = "^[_'.@A-Za-z0-9-]*$";
+
+ public static final String SYSTEM_ACCOUNT = "system";
+ public static final String ANONYMOUS_USER = "anonymoususer";
+
+ private Constants() {
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/DatabaseConfiguration.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/DatabaseConfiguration.java
new file mode 100644
index 0000000000..83bf0db1bc
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/DatabaseConfiguration.java
@@ -0,0 +1,75 @@
+package com.gateway.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+import io.github.jhipster.config.liquibase.AsyncSpringLiquibase;
+
+import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
+import liquibase.integration.spring.SpringLiquibase;
+import org.h2.tools.Server;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.env.Environment;
+import org.springframework.core.task.TaskExecutor;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+
+@Configuration
+@EnableJpaRepositories("com.gateway.repository")
+@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
+@EnableTransactionManagement
+public class DatabaseConfiguration {
+
+ private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);
+
+ private final Environment env;
+
+ public DatabaseConfiguration(Environment env) {
+ this.env = env;
+ }
+
+ /**
+ * Open the TCP port for the H2 database, so it is available remotely.
+ *
+ * @return the H2 database TCP server
+ * @throws SQLException if the server failed to start
+ */
+ @Bean(initMethod = "start", destroyMethod = "stop")
+ @Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
+ public Server h2TCPServer() throws SQLException {
+ return Server.createTcpServer("-tcp","-tcpAllowOthers");
+ }
+
+ @Bean
+ public SpringLiquibase liquibase(@Qualifier("taskExecutor") TaskExecutor taskExecutor,
+ DataSource dataSource, LiquibaseProperties liquibaseProperties) {
+
+ // Use liquibase.integration.spring.SpringLiquibase if you don't want Liquibase to start asynchronously
+ SpringLiquibase liquibase = new AsyncSpringLiquibase(taskExecutor, env);
+ liquibase.setDataSource(dataSource);
+ liquibase.setChangeLog("classpath:config/liquibase/master.xml");
+ liquibase.setContexts(liquibaseProperties.getContexts());
+ liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema());
+ liquibase.setDropFirst(liquibaseProperties.isDropFirst());
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_NO_LIQUIBASE)) {
+ liquibase.setShouldRun(false);
+ } else {
+ liquibase.setShouldRun(liquibaseProperties.isEnabled());
+ log.debug("Configuring Liquibase");
+ }
+ return liquibase;
+ }
+
+ @Bean
+ public Hibernate5Module hibernate5Module() {
+ return new Hibernate5Module();
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/DateTimeFormatConfiguration.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/DateTimeFormatConfiguration.java
new file mode 100644
index 0000000000..e9391c5b1d
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/DateTimeFormatConfiguration.java
@@ -0,0 +1,17 @@
+package com.gateway.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@Configuration
+public class DateTimeFormatConfiguration extends WebMvcConfigurerAdapter {
+
+ @Override
+ public void addFormatters(FormatterRegistry registry) {
+ DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
+ registrar.setUseIsoFormat(true);
+ registrar.registerFormatters(registry);
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/DefaultProfileUtil.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/DefaultProfileUtil.java
new file mode 100644
index 0000000000..379abc93d5
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/DefaultProfileUtil.java
@@ -0,0 +1,48 @@
+package com.gateway.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.core.env.Environment;
+
+import java.util.*;
+
+/**
+ * Utility class to load a Spring profile to be used as default
+ * when there is no spring.profiles.active set in the environment or as command line argument.
+ * If the value is not available in application.yml then dev profile will be used as default.
+ */
+public final class DefaultProfileUtil {
+
+ private static final String SPRING_PROFILE_DEFAULT = "spring.profiles.default";
+
+ private DefaultProfileUtil() {
+ }
+
+ /**
+ * Set a default to use when no profile is configured.
+ *
+ * @param app the Spring application
+ */
+ public static void addDefaultProfile(SpringApplication app) {
+ Map defProperties = new HashMap<>();
+ /*
+ * The default profile to use when no other profiles are defined
+ * This cannot be set in the application.yml file.
+ * See https://github.com/spring-projects/spring-boot/issues/1219
+ */
+ defProperties.put(SPRING_PROFILE_DEFAULT, JHipsterConstants.SPRING_PROFILE_DEVELOPMENT);
+ app.setDefaultProperties(defProperties);
+ }
+
+ /**
+ * Get the profiles that are applied else get default profiles.
+ */
+ public static String[] getActiveProfiles(Environment env) {
+ String[] profiles = env.getActiveProfiles();
+ if (profiles.length == 0) {
+ return env.getDefaultProfiles();
+ }
+ return profiles;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/GatewayConfiguration.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/GatewayConfiguration.java
new file mode 100644
index 0000000000..301d7304bd
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/GatewayConfiguration.java
@@ -0,0 +1,71 @@
+package com.gateway.config;
+
+import io.github.jhipster.config.JHipsterProperties;
+
+import com.gateway.gateway.ratelimiting.RateLimitingFilter;
+import com.gateway.gateway.ratelimiting.RateLimitingRepository;
+import com.gateway.gateway.accesscontrol.AccessControlFilter;
+import com.gateway.gateway.responserewriting.SwaggerBasePathRewritingFilter;
+
+import com.datastax.driver.core.*;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class GatewayConfiguration {
+
+ @Configuration
+ public static class SwaggerBasePathRewritingConfiguration {
+
+ @Bean
+ public SwaggerBasePathRewritingFilter swaggerBasePathRewritingFilter(){
+ return new SwaggerBasePathRewritingFilter();
+ }
+ }
+
+ @Configuration
+ public static class AccessControlFilterConfiguration {
+
+ @Bean
+ public AccessControlFilter accessControlFilter(RouteLocator routeLocator, JHipsterProperties jHipsterProperties){
+ return new AccessControlFilter(routeLocator, jHipsterProperties);
+ }
+ }
+
+ /**
+ * Configures the Zuul filter that limits the number of API calls per user.
+ *
+ * For this filter to work, you need to have:
+ *
+ * - A working Cassandra cluster
+ *
- A schema with the JHipster rate-limiting tables configured, using the
+ * "create_keyspace.cql" and "create_tables.cql" scripts from the
+ * "src/main/resources/config/cql" directory
+ *
- Your cluster configured in your application-*.yml files, using the
+ * "spring.data.cassandra" keys
+ *
+ */
+ @Configuration
+ @ConditionalOnProperty("jhipster.gateway.rate-limiting.enabled")
+ public static class RateLimitingConfiguration {
+
+ private final JHipsterProperties jHipsterProperties;
+
+ public RateLimitingConfiguration(JHipsterProperties jHipsterProperties) {
+ this.jHipsterProperties = jHipsterProperties;
+ }
+
+ @Bean
+ public RateLimitingRepository rateLimitingRepository(Session session) {
+ return new RateLimitingRepository(session);
+ }
+
+ @Bean
+ public RateLimitingFilter rateLimitingFilter(RateLimitingRepository rateLimitingRepository) {
+ return new RateLimitingFilter(rateLimitingRepository, jHipsterProperties);
+ }
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/LocaleConfiguration.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/LocaleConfiguration.java
new file mode 100644
index 0000000000..1affdfe7f4
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/LocaleConfiguration.java
@@ -0,0 +1,35 @@
+package com.gateway.config;
+
+import io.github.jhipster.config.locale.AngularCookieLocaleResolver;
+
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
+
+@Configuration
+public class LocaleConfiguration extends WebMvcConfigurerAdapter implements EnvironmentAware {
+
+ @Override
+ public void setEnvironment(Environment environment) {
+ // unused
+ }
+
+ @Bean(name = "localeResolver")
+ public LocaleResolver localeResolver() {
+ AngularCookieLocaleResolver cookieLocaleResolver = new AngularCookieLocaleResolver();
+ cookieLocaleResolver.setCookieName("NG_TRANSLATE_LANG_KEY");
+ return cookieLocaleResolver;
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
+ localeChangeInterceptor.setParamName("language");
+ registry.addInterceptor(localeChangeInterceptor);
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/LoggingAspectConfiguration.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/LoggingAspectConfiguration.java
new file mode 100644
index 0000000000..bd02cc46cf
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/LoggingAspectConfiguration.java
@@ -0,0 +1,19 @@
+package com.gateway.config;
+
+import com.gateway.aop.logging.LoggingAspect;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.springframework.context.annotation.*;
+import org.springframework.core.env.Environment;
+
+@Configuration
+@EnableAspectJAutoProxy
+public class LoggingAspectConfiguration {
+
+ @Bean
+ @Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
+ public LoggingAspect loggingAspect(Environment env) {
+ return new LoggingAspect(env);
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/LoggingConfiguration.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/LoggingConfiguration.java
new file mode 100644
index 0000000000..c9c0a06adc
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/LoggingConfiguration.java
@@ -0,0 +1,113 @@
+package com.gateway.config;
+
+import io.github.jhipster.config.JHipsterProperties;
+
+import ch.qos.logback.classic.AsyncAppender;
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.LoggerContextListener;
+import ch.qos.logback.core.spi.ContextAwareBase;
+import net.logstash.logback.appender.LogstashSocketAppender;
+import net.logstash.logback.stacktrace.ShortenedThrowableConverter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class LoggingConfiguration {
+
+ private final Logger log = LoggerFactory.getLogger(LoggingConfiguration.class);
+
+ private LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+
+ @Value("${spring.application.name}")
+ private String appName;
+
+ @Value("${server.port}")
+ private String serverPort;
+
+ @Value("${eureka.instance.instanceId}")
+ private String instanceId;
+
+ private final JHipsterProperties jHipsterProperties;
+
+ public LoggingConfiguration(JHipsterProperties jHipsterProperties) {
+ this.jHipsterProperties = jHipsterProperties;
+ if (jHipsterProperties.getLogging().getLogstash().isEnabled()) {
+ addLogstashAppender(context);
+
+ // Add context listener
+ LogbackLoggerContextListener loggerContextListener = new LogbackLoggerContextListener();
+ loggerContextListener.setContext(context);
+ context.addListener(loggerContextListener);
+ }
+ }
+
+ public void addLogstashAppender(LoggerContext context) {
+ log.info("Initializing Logstash logging");
+
+ LogstashSocketAppender logstashAppender = new LogstashSocketAppender();
+ logstashAppender.setName("LOGSTASH");
+ logstashAppender.setContext(context);
+ String customFields = "{\"app_name\":\"" + appName + "\",\"app_port\":\"" + serverPort + "\"," +
+ "\"instance_id\":\"" + instanceId + "\"}";
+
+ // Set the Logstash appender config from JHipster properties
+ logstashAppender.setSyslogHost(jHipsterProperties.getLogging().getLogstash().getHost());
+ logstashAppender.setPort(jHipsterProperties.getLogging().getLogstash().getPort());
+ logstashAppender.setCustomFields(customFields);
+
+ // Limit the maximum length of the forwarded stacktrace so that it won't exceed the 8KB UDP limit of logstash
+ ShortenedThrowableConverter throwableConverter = new ShortenedThrowableConverter();
+ throwableConverter.setMaxLength(7500);
+ throwableConverter.setRootCauseFirst(true);
+ logstashAppender.setThrowableConverter(throwableConverter);
+
+ logstashAppender.start();
+
+ // Wrap the appender in an Async appender for performance
+ AsyncAppender asyncLogstashAppender = new AsyncAppender();
+ asyncLogstashAppender.setContext(context);
+ asyncLogstashAppender.setName("ASYNC_LOGSTASH");
+ asyncLogstashAppender.setQueueSize(jHipsterProperties.getLogging().getLogstash().getQueueSize());
+ asyncLogstashAppender.addAppender(logstashAppender);
+ asyncLogstashAppender.start();
+
+ context.getLogger("ROOT").addAppender(asyncLogstashAppender);
+ }
+
+ /**
+ * Logback configuration is achieved by configuration file and API.
+ * When configuration file change is detected, the configuration is reset.
+ * This listener ensures that the programmatic configuration is also re-applied after reset.
+ */
+ class LogbackLoggerContextListener extends ContextAwareBase implements LoggerContextListener {
+
+ @Override
+ public boolean isResetResistant() {
+ return true;
+ }
+
+ @Override
+ public void onStart(LoggerContext context) {
+ addLogstashAppender(context);
+ }
+
+ @Override
+ public void onReset(LoggerContext context) {
+ addLogstashAppender(context);
+ }
+
+ @Override
+ public void onStop(LoggerContext context) {
+ // Nothing to do.
+ }
+
+ @Override
+ public void onLevelChange(ch.qos.logback.classic.Logger logger, Level level) {
+ // Nothing to do.
+ }
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/MetricsConfiguration.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/MetricsConfiguration.java
new file mode 100644
index 0000000000..79689196df
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/MetricsConfiguration.java
@@ -0,0 +1,113 @@
+package com.gateway.config;
+
+import io.github.jhipster.config.JHipsterProperties;
+import io.github.jhipster.config.metrics.SpectatorLogMetricWriter;
+
+import com.netflix.spectator.api.Registry;
+import org.springframework.boot.actuate.autoconfigure.ExportMetricReader;
+import org.springframework.boot.actuate.autoconfigure.ExportMetricWriter;
+import org.springframework.boot.actuate.metrics.writer.MetricWriter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.netflix.metrics.spectator.SpectatorMetricReader;
+
+import com.codahale.metrics.JmxReporter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Slf4jReporter;
+import com.codahale.metrics.health.HealthCheckRegistry;
+import com.codahale.metrics.jvm.*;
+import com.ryantenney.metrics.spring.config.annotation.EnableMetrics;
+import com.ryantenney.metrics.spring.config.annotation.MetricsConfigurerAdapter;
+import com.zaxxer.hikari.HikariDataSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.*;
+
+import javax.annotation.PostConstruct;
+import java.lang.management.ManagementFactory;
+import java.util.concurrent.TimeUnit;
+
+@Configuration
+@EnableMetrics(proxyTargetClass = true)
+public class MetricsConfiguration extends MetricsConfigurerAdapter {
+
+ private static final String PROP_METRIC_REG_JVM_MEMORY = "jvm.memory";
+ private static final String PROP_METRIC_REG_JVM_GARBAGE = "jvm.garbage";
+ private static final String PROP_METRIC_REG_JVM_THREADS = "jvm.threads";
+ private static final String PROP_METRIC_REG_JVM_FILES = "jvm.files";
+ private static final String PROP_METRIC_REG_JVM_BUFFERS = "jvm.buffers";
+ private final Logger log = LoggerFactory.getLogger(MetricsConfiguration.class);
+
+ private MetricRegistry metricRegistry = new MetricRegistry();
+
+ private HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry();
+
+ private final JHipsterProperties jHipsterProperties;
+
+ private HikariDataSource hikariDataSource;
+
+ public MetricsConfiguration(JHipsterProperties jHipsterProperties) {
+ this.jHipsterProperties = jHipsterProperties;
+ }
+
+ @Autowired(required = false)
+ public void setHikariDataSource(HikariDataSource hikariDataSource) {
+ this.hikariDataSource = hikariDataSource;
+ }
+
+ @Override
+ @Bean
+ public MetricRegistry getMetricRegistry() {
+ return metricRegistry;
+ }
+
+ @Override
+ @Bean
+ public HealthCheckRegistry getHealthCheckRegistry() {
+ return healthCheckRegistry;
+ }
+
+ @PostConstruct
+ public void init() {
+ log.debug("Registering JVM gauges");
+ metricRegistry.register(PROP_METRIC_REG_JVM_MEMORY, new MemoryUsageGaugeSet());
+ metricRegistry.register(PROP_METRIC_REG_JVM_GARBAGE, new GarbageCollectorMetricSet());
+ metricRegistry.register(PROP_METRIC_REG_JVM_THREADS, new ThreadStatesGaugeSet());
+ metricRegistry.register(PROP_METRIC_REG_JVM_FILES, new FileDescriptorRatioGauge());
+ metricRegistry.register(PROP_METRIC_REG_JVM_BUFFERS, new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()));
+ if (hikariDataSource != null) {
+ log.debug("Monitoring the datasource");
+ hikariDataSource.setMetricRegistry(metricRegistry);
+ }
+ if (jHipsterProperties.getMetrics().getJmx().isEnabled()) {
+ log.debug("Initializing Metrics JMX reporting");
+ JmxReporter jmxReporter = JmxReporter.forRegistry(metricRegistry).build();
+ jmxReporter.start();
+ }
+ if (jHipsterProperties.getMetrics().getLogs().isEnabled()) {
+ log.info("Initializing Metrics Log reporting");
+ final Slf4jReporter reporter = Slf4jReporter.forRegistry(metricRegistry)
+ .outputTo(LoggerFactory.getLogger("metrics"))
+ .convertRatesTo(TimeUnit.SECONDS)
+ .convertDurationsTo(TimeUnit.MILLISECONDS)
+ .build();
+ reporter.start(jHipsterProperties.getMetrics().getLogs().getReportFrequency(), TimeUnit.SECONDS);
+ }
+ }
+
+ /* Spectator metrics log reporting */
+ @Bean
+ @ConditionalOnProperty("jhipster.logging.spectator-metrics.enabled")
+ @ExportMetricReader
+ public SpectatorMetricReader SpectatorMetricReader(Registry registry) {
+ log.info("Initializing Spectator Metrics Log reporting");
+ return new SpectatorMetricReader(registry);
+ }
+
+ @Bean
+ @ConditionalOnProperty("jhipster.logging.spectator-metrics.enabled")
+ @ExportMetricWriter
+ MetricWriter metricWriter() {
+ return new SpectatorLogMetricWriter();
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/SecurityConfiguration.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/SecurityConfiguration.java
new file mode 100644
index 0000000000..73963b5b52
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/SecurityConfiguration.java
@@ -0,0 +1,127 @@
+package com.gateway.config;
+
+import com.gateway.security.*;
+import com.gateway.security.jwt.*;
+
+import io.github.jhipster.security.*;
+
+import org.springframework.beans.factory.BeanInitializationException;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import org.springframework.web.filter.CorsFilter;
+
+import javax.annotation.PostConstruct;
+
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
+public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
+
+ private final AuthenticationManagerBuilder authenticationManagerBuilder;
+
+ private final UserDetailsService userDetailsService;
+
+ private final TokenProvider tokenProvider;
+
+ private final CorsFilter corsFilter;
+
+ public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, UserDetailsService userDetailsService,
+ TokenProvider tokenProvider,
+ CorsFilter corsFilter) {
+
+ this.authenticationManagerBuilder = authenticationManagerBuilder;
+ this.userDetailsService = userDetailsService;
+ this.tokenProvider = tokenProvider;
+ this.corsFilter = corsFilter;
+ }
+
+ @PostConstruct
+ public void init() {
+ try {
+ authenticationManagerBuilder
+ .userDetailsService(userDetailsService)
+ .passwordEncoder(passwordEncoder());
+ } catch (Exception e) {
+ throw new BeanInitializationException("Security configuration failed", e);
+ }
+ }
+
+ @Bean
+ public Http401UnauthorizedEntryPoint http401UnauthorizedEntryPoint() {
+ return new Http401UnauthorizedEntryPoint();
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new BCryptPasswordEncoder();
+ }
+
+ @Override
+ public void configure(WebSecurity web) throws Exception {
+ web.ignoring()
+ .antMatchers(HttpMethod.OPTIONS, "/**")
+ .antMatchers("/app/**/*.{js,html}")
+ .antMatchers("/bower_components/**")
+ .antMatchers("/i18n/**")
+ .antMatchers("/content/**")
+ .antMatchers("/swagger-ui/index.html")
+ .antMatchers("/test/**")
+ .antMatchers("/h2-console/**");
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
+ .exceptionHandling()
+ .authenticationEntryPoint(http401UnauthorizedEntryPoint())
+ .and()
+ .csrf()
+ .disable()
+ .headers()
+ .frameOptions()
+ .disable()
+ .and()
+ .sessionManagement()
+ .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+ .and()
+ .authorizeRequests()
+ .antMatchers("/api/register").permitAll()
+ .antMatchers("/api/activate").permitAll()
+ .antMatchers("/api/authenticate").permitAll()
+ .antMatchers("/api/account/reset_password/init").permitAll()
+ .antMatchers("/api/account/reset_password/finish").permitAll()
+ .antMatchers("/api/profile-info").permitAll()
+ .antMatchers("/api/**").authenticated()
+ .antMatchers("/management/health").permitAll()
+ .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
+ .antMatchers("/v2/api-docs/**").permitAll()
+ .antMatchers("/swagger-resources/configuration/ui").permitAll()
+ .antMatchers("/swagger-ui/index.html").hasAuthority(AuthoritiesConstants.ADMIN)
+ .and()
+ .apply(securityConfigurerAdapter());
+
+ }
+
+ private JWTConfigurer securityConfigurerAdapter() {
+ return new JWTConfigurer(tokenProvider);
+ }
+
+ @Bean
+ public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
+ return new SecurityEvaluationContextExtension();
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/ThymeleafConfiguration.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/ThymeleafConfiguration.java
new file mode 100644
index 0000000000..a39a0363c8
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/ThymeleafConfiguration.java
@@ -0,0 +1,26 @@
+package com.gateway.config;
+
+import org.apache.commons.lang3.CharEncoding;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.*;
+import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
+
+@Configuration
+public class ThymeleafConfiguration {
+
+ @SuppressWarnings("unused")
+ private final Logger log = LoggerFactory.getLogger(ThymeleafConfiguration.class);
+
+ @Bean
+ @Description("Thymeleaf template resolver serving HTML 5 emails")
+ public ClassLoaderTemplateResolver emailTemplateResolver() {
+ ClassLoaderTemplateResolver emailTemplateResolver = new ClassLoaderTemplateResolver();
+ emailTemplateResolver.setPrefix("mails/");
+ emailTemplateResolver.setSuffix(".html");
+ emailTemplateResolver.setTemplateMode("HTML5");
+ emailTemplateResolver.setCharacterEncoding(CharEncoding.UTF_8);
+ emailTemplateResolver.setOrder(1);
+ return emailTemplateResolver;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/WebConfigurer.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/WebConfigurer.java
new file mode 100644
index 0000000000..1b780a8caf
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/WebConfigurer.java
@@ -0,0 +1,195 @@
+package com.gateway.config;
+
+import io.github.jhipster.config.JHipsterConstants;
+import io.github.jhipster.config.JHipsterProperties;
+import io.github.jhipster.web.filter.CachingHttpHeadersFilter;
+
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.servlet.InstrumentedFilter;
+import com.codahale.metrics.servlets.MetricsServlet;
+import com.hazelcast.core.HazelcastInstance;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.embedded.*;
+import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
+import io.undertow.UndertowOptions;
+import org.springframework.boot.web.servlet.ServletContextInitializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+import java.io.File;
+import java.nio.file.Paths;
+import java.util.*;
+import javax.servlet.*;
+
+/**
+ * Configuration of web application with Servlet 3.0 APIs.
+ */
+@Configuration
+public class WebConfigurer implements ServletContextInitializer, EmbeddedServletContainerCustomizer {
+
+ private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);
+
+ private final Environment env;
+
+ private final JHipsterProperties jHipsterProperties;
+
+ private final HazelcastInstance hazelcastInstance;
+
+ private MetricRegistry metricRegistry;
+
+ public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties, HazelcastInstance hazelcastInstance) {
+
+ this.env = env;
+ this.jHipsterProperties = jHipsterProperties;
+ this.hazelcastInstance = hazelcastInstance;
+ }
+
+ @Override
+ public void onStartup(ServletContext servletContext) throws ServletException {
+ if (env.getActiveProfiles().length != 0) {
+ log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles());
+ }
+ EnumSet disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
+ initMetrics(servletContext, disps);
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
+ initCachingHttpHeadersFilter(servletContext, disps);
+ }
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
+ initH2Console(servletContext);
+ }
+ log.info("Web application fully configured");
+ }
+
+ /**
+ * Customize the Servlet engine: Mime types, the document root, the cache.
+ */
+ @Override
+ public void customize(ConfigurableEmbeddedServletContainer container) {
+ MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
+ // IE issue, see https://github.com/jhipster/generator-jhipster/pull/711
+ mappings.add("html", "text/html;charset=utf-8");
+ // CloudFoundry issue, see https://github.com/cloudfoundry/gorouter/issues/64
+ mappings.add("json", "text/html;charset=utf-8");
+ container.setMimeMappings(mappings);
+ // When running in an IDE or with ./mvnw spring-boot:run, set location of the static web assets.
+ setLocationForStaticAssets(container);
+
+ /*
+ * Enable HTTP/2 for Undertow - https://twitter.com/ankinson/status/829256167700492288
+ * HTTP/2 requires HTTPS, so HTTP requests will fallback to HTTP/1.1.
+ * See the JHipsterProperties class and your application-*.yml configuration files
+ * for more information.
+ */
+ if (jHipsterProperties.getHttp().getVersion().equals(JHipsterProperties.Http.Version.V_2_0) &&
+ container instanceof UndertowEmbeddedServletContainerFactory) {
+
+ ((UndertowEmbeddedServletContainerFactory) container)
+ .addBuilderCustomizers(builder ->
+ builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true));
+ }
+ }
+
+ private void setLocationForStaticAssets(ConfigurableEmbeddedServletContainer container) {
+ File root;
+ String prefixPath = resolvePathPrefix();
+ if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
+ root = new File(prefixPath + "target/www/");
+ } else {
+ root = new File(prefixPath + "src/main/webapp/");
+ }
+ if (root.exists() && root.isDirectory()) {
+ container.setDocumentRoot(root);
+ }
+ }
+
+ /**
+ * Resolve path prefix to static resources.
+ */
+ private String resolvePathPrefix() {
+ String fullExecutablePath = this.getClass().getResource("").getPath();
+ String rootPath = Paths.get(".").toUri().normalize().getPath();
+ String extractedPath = fullExecutablePath.replace(rootPath, "");
+ int extractionEndIndex = extractedPath.indexOf("target/");
+ if(extractionEndIndex <= 0) {
+ return "";
+ }
+ return extractedPath.substring(0, extractionEndIndex);
+ }
+
+ /**
+ * Initializes the caching HTTP Headers Filter.
+ */
+ private void initCachingHttpHeadersFilter(ServletContext servletContext,
+ EnumSet disps) {
+ log.debug("Registering Caching HTTP Headers Filter");
+ FilterRegistration.Dynamic cachingHttpHeadersFilter =
+ servletContext.addFilter("cachingHttpHeadersFilter",
+ new CachingHttpHeadersFilter(jHipsterProperties));
+
+ cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/content/*");
+ cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/app/*");
+ cachingHttpHeadersFilter.setAsyncSupported(true);
+ }
+
+ /**
+ * Initializes Metrics.
+ */
+ private void initMetrics(ServletContext servletContext, EnumSet disps) {
+ log.debug("Initializing Metrics registries");
+ servletContext.setAttribute(InstrumentedFilter.REGISTRY_ATTRIBUTE,
+ metricRegistry);
+ servletContext.setAttribute(MetricsServlet.METRICS_REGISTRY,
+ metricRegistry);
+
+ log.debug("Registering Metrics Filter");
+ FilterRegistration.Dynamic metricsFilter = servletContext.addFilter("webappMetricsFilter",
+ new InstrumentedFilter());
+
+ metricsFilter.addMappingForUrlPatterns(disps, true, "/*");
+ metricsFilter.setAsyncSupported(true);
+
+ log.debug("Registering Metrics Servlet");
+ ServletRegistration.Dynamic metricsAdminServlet =
+ servletContext.addServlet("metricsServlet", new MetricsServlet());
+
+ metricsAdminServlet.addMapping("/management/metrics/*");
+ metricsAdminServlet.setAsyncSupported(true);
+ metricsAdminServlet.setLoadOnStartup(2);
+ }
+
+ @Bean
+ public CorsFilter corsFilter() {
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ CorsConfiguration config = jHipsterProperties.getCors();
+ if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
+ log.debug("Registering CORS filter");
+ source.registerCorsConfiguration("/api/**", config);
+ source.registerCorsConfiguration("/v2/api-docs", config);
+ source.registerCorsConfiguration("/*/api/**", config);
+ }
+ return new CorsFilter(source);
+ }
+
+ /**
+ * Initializes H2 console.
+ */
+ private void initH2Console(ServletContext servletContext) {
+ log.debug("Initialize H2 console");
+ ServletRegistration.Dynamic h2ConsoleServlet = servletContext.addServlet("H2Console", new org.h2.server.web.WebServlet());
+ h2ConsoleServlet.addMapping("/h2-console/*");
+ h2ConsoleServlet.setInitParameter("-properties", "src/main/resources/");
+ h2ConsoleServlet.setLoadOnStartup(1);
+ }
+
+ @Autowired(required = false)
+ public void setMetricRegistry(MetricRegistry metricRegistry) {
+ this.metricRegistry = metricRegistry;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/apidoc/GatewaySwaggerResourcesProvider.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/apidoc/GatewaySwaggerResourcesProvider.java
new file mode 100644
index 0000000000..1ef6c7e00b
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/apidoc/GatewaySwaggerResourcesProvider.java
@@ -0,0 +1,63 @@
+package com.gateway.config.apidoc;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.*;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.cloud.netflix.zuul.filters.Route;
+import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+
+import springfox.documentation.swagger.web.SwaggerResource;
+import springfox.documentation.swagger.web.SwaggerResourcesProvider;
+
+/**
+ * Retrieves all registered microservices Swagger resources.
+ */
+@Component
+@Primary
+@Profile(JHipsterConstants.SPRING_PROFILE_SWAGGER)
+public class GatewaySwaggerResourcesProvider implements SwaggerResourcesProvider {
+
+ private final Logger log = LoggerFactory.getLogger(GatewaySwaggerResourcesProvider.class);
+
+ private final RouteLocator routeLocator;
+
+ private final DiscoveryClient discoveryClient;
+
+ public GatewaySwaggerResourcesProvider(RouteLocator routeLocator, DiscoveryClient discoveryClient) {
+ this.routeLocator = routeLocator;
+ this.discoveryClient = discoveryClient;
+ }
+
+ @Override
+ public List get() {
+ List resources = new ArrayList<>();
+
+ //Add the default swagger resource that correspond to the gateway's own swagger doc
+ resources.add(swaggerResource("default", "/v2/api-docs"));
+
+ //Add the registered microservices swagger docs as additional swagger resources
+ List routes = routeLocator.getRoutes();
+ routes.forEach(route -> {
+ resources.add(swaggerResource(route.getId(), route.getFullPath().replace("**", "v2/api-docs")));
+ });
+
+ return resources;
+ }
+
+ private SwaggerResource swaggerResource(String name, String location) {
+ SwaggerResource swaggerResource = new SwaggerResource();
+ swaggerResource.setName(name);
+ swaggerResource.setLocation(location);
+ swaggerResource.setSwaggerVersion("2.0");
+ return swaggerResource;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/audit/AuditEventConverter.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/audit/AuditEventConverter.java
new file mode 100644
index 0000000000..60189a42b4
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/audit/AuditEventConverter.java
@@ -0,0 +1,91 @@
+package com.gateway.config.audit;
+
+import com.gateway.domain.PersistentAuditEvent;
+
+import org.springframework.boot.actuate.audit.AuditEvent;
+import org.springframework.security.web.authentication.WebAuthenticationDetails;
+import org.springframework.stereotype.Component;
+
+import java.time.Instant;
+import java.time.ZoneId;
+import java.util.*;
+
+@Component
+public class AuditEventConverter {
+
+ /**
+ * Convert a list of PersistentAuditEvent to a list of AuditEvent
+ *
+ * @param persistentAuditEvents the list to convert
+ * @return the converted list.
+ */
+ public List convertToAuditEvent(Iterable persistentAuditEvents) {
+ if (persistentAuditEvents == null) {
+ return Collections.emptyList();
+ }
+ List auditEvents = new ArrayList<>();
+ for (PersistentAuditEvent persistentAuditEvent : persistentAuditEvents) {
+ auditEvents.add(convertToAuditEvent(persistentAuditEvent));
+ }
+ return auditEvents;
+ }
+
+ /**
+ * Convert a PersistentAuditEvent to an AuditEvent
+ *
+ * @param persistentAuditEvent the event to convert
+ * @return the converted list.
+ */
+ public AuditEvent convertToAuditEvent(PersistentAuditEvent persistentAuditEvent) {
+ Instant instant = persistentAuditEvent.getAuditEventDate().atZone(ZoneId.systemDefault()).toInstant();
+ return new AuditEvent(Date.from(instant), persistentAuditEvent.getPrincipal(),
+ persistentAuditEvent.getAuditEventType(), convertDataToObjects(persistentAuditEvent.getData()));
+ }
+
+ /**
+ * Internal conversion. This is needed to support the current SpringBoot actuator AuditEventRepository interface
+ *
+ * @param data the data to convert
+ * @return a map of String, Object
+ */
+ public Map convertDataToObjects(Map data) {
+ Map results = new HashMap<>();
+
+ if (data != null) {
+ for (Map.Entry entry : data.entrySet()) {
+ results.put(entry.getKey(), entry.getValue());
+ }
+ }
+ return results;
+ }
+
+ /**
+ * Internal conversion. This method will allow to save additional data.
+ * By default, it will save the object as string
+ *
+ * @param data the data to convert
+ * @return a map of String, String
+ */
+ public Map convertDataToStrings(Map data) {
+ Map results = new HashMap<>();
+
+ if (data != null) {
+ for (Map.Entry entry : data.entrySet()) {
+ Object object = entry.getValue();
+
+ // Extract the data that will be saved.
+ if (object instanceof WebAuthenticationDetails) {
+ WebAuthenticationDetails authenticationDetails = (WebAuthenticationDetails) object;
+ results.put("remoteAddress", authenticationDetails.getRemoteAddress());
+ results.put("sessionId", authenticationDetails.getSessionId());
+ } else if (object != null) {
+ results.put(entry.getKey(), object.toString());
+ } else {
+ results.put(entry.getKey(), "null");
+ }
+ }
+ }
+
+ return results;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/audit/package-info.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/audit/package-info.java
new file mode 100644
index 0000000000..91e4a657bf
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/audit/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Audit specific code.
+ */
+package com.gateway.config.audit;
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/cassandra/CassandraConfiguration.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/cassandra/CassandraConfiguration.java
new file mode 100644
index 0000000000..b528d8b96b
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/cassandra/CassandraConfiguration.java
@@ -0,0 +1,122 @@
+package com.gateway.config.cassandra;
+
+import io.github.jhipster.config.JHipsterConstants;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.cassandra.CassandraProperties;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.util.StringUtils;
+
+import com.codahale.metrics.MetricRegistry;
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.ProtocolVersion;
+import com.datastax.driver.core.QueryOptions;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SocketOptions;
+import com.datastax.driver.core.policies.LoadBalancingPolicy;
+import com.datastax.driver.core.policies.ReconnectionPolicy;
+import com.datastax.driver.core.policies.RetryPolicy;
+import com.datastax.driver.extras.codecs.jdk8.LocalDateCodec;
+
+@Configuration
+@ConditionalOnProperty("jhipster.gateway.rate-limiting.enabled")
+@EnableConfigurationProperties(CassandraProperties.class)
+@Profile({JHipsterConstants.SPRING_PROFILE_DEVELOPMENT, JHipsterConstants.SPRING_PROFILE_PRODUCTION})
+public class CassandraConfiguration {
+
+ @Value("${spring.data.cassandra.protocolVersion:V4}")
+ private ProtocolVersion protocolVersion;
+
+ @Autowired(required = false)
+ MetricRegistry metricRegistry;
+
+ private final Logger log = LoggerFactory.getLogger(CassandraConfiguration.class);
+
+ @Bean
+ public Cluster cluster(CassandraProperties properties) {
+ Cluster.Builder builder = Cluster.builder()
+ .withClusterName(properties.getClusterName())
+ .withProtocolVersion(protocolVersion)
+ .withPort(getPort(properties));
+
+ if (properties.getUsername() != null) {
+ builder.withCredentials(properties.getUsername(), properties.getPassword());
+ }
+ if (properties.getCompression() != null) {
+ builder.withCompression(properties.getCompression());
+ }
+ if (properties.getLoadBalancingPolicy() != null) {
+ LoadBalancingPolicy policy = instantiate(properties.getLoadBalancingPolicy());
+ builder.withLoadBalancingPolicy(policy);
+ }
+ builder.withQueryOptions(getQueryOptions(properties));
+ if (properties.getReconnectionPolicy() != null) {
+ ReconnectionPolicy policy = instantiate(properties.getReconnectionPolicy());
+ builder.withReconnectionPolicy(policy);
+ }
+ if (properties.getRetryPolicy() != null) {
+ RetryPolicy policy = instantiate(properties.getRetryPolicy());
+ builder.withRetryPolicy(policy);
+ }
+ builder.withSocketOptions(getSocketOptions(properties));
+ if (properties.isSsl()) {
+ builder.withSSL();
+ }
+ String points = properties.getContactPoints();
+ builder.addContactPoints(StringUtils.commaDelimitedListToStringArray(points));
+
+ Cluster cluster = builder.build();
+
+ cluster.getConfiguration().getCodecRegistry()
+ .register(LocalDateCodec.instance)
+ .register(CustomZonedDateTimeCodec.instance);
+
+ if (metricRegistry != null) {
+ cluster.init();
+ metricRegistry.registerAll(cluster.getMetrics().getRegistry());
+ }
+
+ return cluster;
+ }
+
+ protected int getPort(CassandraProperties properties) {
+ return properties.getPort();
+ }
+
+ public static T instantiate(Class type) {
+ return BeanUtils.instantiate(type);
+ }
+
+ private QueryOptions getQueryOptions(CassandraProperties properties) {
+ QueryOptions options = new QueryOptions();
+ if (properties.getConsistencyLevel() != null) {
+ options.setConsistencyLevel(properties.getConsistencyLevel());
+ }
+ if (properties.getSerialConsistencyLevel() != null) {
+ options.setSerialConsistencyLevel(properties.getSerialConsistencyLevel());
+ }
+ options.setFetchSize(properties.getFetchSize());
+ return options;
+ }
+
+ private SocketOptions getSocketOptions(CassandraProperties properties) {
+ SocketOptions options = new SocketOptions();
+ options.setConnectTimeoutMillis(properties.getConnectTimeoutMillis());
+ options.setReadTimeoutMillis(properties.getReadTimeoutMillis());
+ return options;
+ }
+
+ @Bean(destroyMethod = "close")
+ public Session session(CassandraProperties properties, Cluster cluster) {
+ log.debug("Configuring Cassandra session");
+ return StringUtils.hasText(properties.getKeyspaceName()) ? cluster.connect(properties.getKeyspaceName()) : cluster.connect();
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/cassandra/CustomZonedDateTimeCodec.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/cassandra/CustomZonedDateTimeCodec.java
new file mode 100644
index 0000000000..5cdab7ac5b
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/cassandra/CustomZonedDateTimeCodec.java
@@ -0,0 +1,93 @@
+package com.gateway.config.cassandra;
+
+import com.datastax.driver.core.*;
+import com.datastax.driver.core.exceptions.InvalidTypeException;
+
+import java.nio.ByteBuffer;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.DateTimeParseException;
+
+import static com.datastax.driver.core.ParseUtils.isLongLiteral;
+import static com.datastax.driver.core.ParseUtils.quote;
+import static java.time.temporal.ChronoField.*;
+
+public class CustomZonedDateTimeCodec extends TypeCodec {
+
+ public static final CustomZonedDateTimeCodec instance = new CustomZonedDateTimeCodec();
+
+ private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
+ .parseCaseSensitive()
+ .parseStrict()
+ .append(DateTimeFormatter.ISO_LOCAL_DATE)
+ .optionalStart()
+ .appendLiteral('T')
+ .appendValue(HOUR_OF_DAY, 2)
+ .appendLiteral(':')
+ .appendValue(MINUTE_OF_HOUR, 2)
+ .optionalEnd()
+ .optionalStart()
+ .appendLiteral(':')
+ .appendValue(SECOND_OF_MINUTE, 2)
+ .optionalEnd()
+ .optionalStart()
+ .appendFraction(NANO_OF_SECOND, 0, 9, true)
+ .optionalEnd()
+ .optionalStart()
+ .appendZoneOrOffsetId()
+ .optionalEnd()
+ .toFormatter()
+ .withZone(ZoneOffset.UTC);
+
+ private CustomZonedDateTimeCodec() {
+ super(DataType.timestamp(), ZonedDateTime.class);
+ }
+
+ @Override
+ public ByteBuffer serialize(ZonedDateTime value, ProtocolVersion protocolVersion) {
+ if (value == null) {
+ return null;
+ }
+ long millis = value.toInstant().toEpochMilli();
+ return bigint().serializeNoBoxing(millis, protocolVersion);
+ }
+
+ @Override
+ public ZonedDateTime deserialize(ByteBuffer bytes, ProtocolVersion protocolVersion) {
+ if (bytes == null || bytes.remaining() == 0) {
+ return null;
+ }
+ long millis = bigint().deserializeNoBoxing(bytes, protocolVersion);
+ return Instant.ofEpochMilli(millis).atZone(ZoneOffset.UTC);
+ }
+
+ @Override
+ public String format(ZonedDateTime value) {
+ return quote(FORMATTER.format(value));
+ }
+
+ @Override
+ public ZonedDateTime parse(String value) {
+ // strip enclosing single quotes, if any
+ if (ParseUtils.isQuoted(value)) {
+ value = ParseUtils.unquote(value);
+ }
+ if (isLongLiteral(value)) {
+ try {
+ long millis = Long.parseLong(value);
+ return ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), ZoneOffset.UTC);
+ } catch (NumberFormatException e) {
+ throw new InvalidTypeException(String.format("Cannot parse timestamp value from \"%s\"", value));
+ }
+ }
+ try {
+ return ZonedDateTime.from(FORMATTER.parse(value));
+ } catch (DateTimeParseException e) {
+ throw new InvalidTypeException(String.format("Cannot parse timestamp value from \"%s\"", value));
+ }
+ }
+
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/cassandra/package-info.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/cassandra/package-info.java
new file mode 100644
index 0000000000..a77f49c447
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/cassandra/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Cassandra specific configuration.
+ */
+package com.gateway.config.cassandra;
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/package-info.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/package-info.java
new file mode 100644
index 0000000000..00f6440bfb
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/config/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Spring Framework configuration files.
+ */
+package com.gateway.config;
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/AbstractAuditingEntity.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/AbstractAuditingEntity.java
new file mode 100644
index 0000000000..1c270ab70e
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/AbstractAuditingEntity.java
@@ -0,0 +1,80 @@
+package com.gateway.domain;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.hibernate.envers.Audited;
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedBy;
+import org.springframework.data.annotation.LastModifiedDate;
+
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+import java.time.ZonedDateTime;
+import javax.persistence.Column;
+import javax.persistence.EntityListeners;
+import javax.persistence.MappedSuperclass;
+
+/**
+ * Base abstract class for entities which will hold definitions for created, last modified by and created,
+ * last modified by date.
+ */
+@MappedSuperclass
+@Audited
+@EntityListeners(AuditingEntityListener.class)
+public abstract class AbstractAuditingEntity implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @CreatedBy
+ @Column(name = "created_by", nullable = false, length = 50, updatable = false)
+ @JsonIgnore
+ private String createdBy;
+
+ @CreatedDate
+ @Column(name = "created_date", nullable = false)
+ @JsonIgnore
+ private ZonedDateTime createdDate = ZonedDateTime.now();
+
+ @LastModifiedBy
+ @Column(name = "last_modified_by", length = 50)
+ @JsonIgnore
+ private String lastModifiedBy;
+
+ @LastModifiedDate
+ @Column(name = "last_modified_date")
+ @JsonIgnore
+ private ZonedDateTime lastModifiedDate = ZonedDateTime.now();
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public ZonedDateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ public void setCreatedDate(ZonedDateTime createdDate) {
+ this.createdDate = createdDate;
+ }
+
+ public String getLastModifiedBy() {
+ return lastModifiedBy;
+ }
+
+ public void setLastModifiedBy(String lastModifiedBy) {
+ this.lastModifiedBy = lastModifiedBy;
+ }
+
+ public ZonedDateTime getLastModifiedDate() {
+ return lastModifiedDate;
+ }
+
+ public void setLastModifiedDate(ZonedDateTime lastModifiedDate) {
+ this.lastModifiedDate = lastModifiedDate;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/Authority.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/Authority.java
new file mode 100644
index 0000000000..ede3ced0d2
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/Authority.java
@@ -0,0 +1,66 @@
+package com.gateway.domain;
+
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Column;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+
+/**
+ * An authority (a security role) used by Spring Security.
+ */
+@Entity
+@Table(name = "jhi_authority")
+@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
+public class Authority implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @NotNull
+ @Size(min = 0, max = 50)
+ @Id
+ @Column(length = 50)
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Authority authority = (Authority) o;
+
+ if (name != null ? !name.equals(authority.name) : authority.name != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return name != null ? name.hashCode() : 0;
+ }
+
+ @Override
+ public String toString() {
+ return "Authority{" +
+ "name='" + name + '\'' +
+ "}";
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/PersistentAuditEvent.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/PersistentAuditEvent.java
new file mode 100644
index 0000000000..4bc123af1e
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/PersistentAuditEvent.java
@@ -0,0 +1,78 @@
+package com.gateway.domain;
+
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import javax.persistence.*;
+import javax.validation.constraints.NotNull;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Persist AuditEvent managed by the Spring Boot actuator
+ * @see org.springframework.boot.actuate.audit.AuditEvent
+ */
+@Entity
+@Table(name = "jhi_persistent_audit_event")
+public class PersistentAuditEvent implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "event_id")
+ private Long id;
+
+ @NotNull
+ @Column(nullable = false)
+ private String principal;
+
+ @Column(name = "event_date")
+ private LocalDateTime auditEventDate;
+ @Column(name = "event_type")
+ private String auditEventType;
+
+ @ElementCollection
+ @MapKeyColumn(name = "name")
+ @Column(name = "value")
+ @CollectionTable(name = "jhi_persistent_audit_evt_data", joinColumns=@JoinColumn(name="event_id"))
+ private Map data = new HashMap<>();
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getPrincipal() {
+ return principal;
+ }
+
+ public void setPrincipal(String principal) {
+ this.principal = principal;
+ }
+
+ public LocalDateTime getAuditEventDate() {
+ return auditEventDate;
+ }
+
+ public void setAuditEventDate(LocalDateTime auditEventDate) {
+ this.auditEventDate = auditEventDate;
+ }
+
+ public String getAuditEventType() {
+ return auditEventType;
+ }
+
+ public void setAuditEventType(String auditEventType) {
+ this.auditEventType = auditEventType;
+ }
+
+ public Map getData() {
+ return data;
+ }
+
+ public void setData(Map data) {
+ this.data = data;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/User.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/User.java
new file mode 100644
index 0000000000..1dfab5f93c
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/User.java
@@ -0,0 +1,235 @@
+package com.gateway.domain;
+
+import com.gateway.config.Constants;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.hibernate.annotations.BatchSize;
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+import org.hibernate.validator.constraints.Email;
+
+import javax.persistence.*;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import java.time.ZonedDateTime;
+
+/**
+ * A user.
+ */
+@Entity
+@Table(name = "jhi_user")
+@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
+public class User extends AbstractAuditingEntity implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @NotNull
+ @Pattern(regexp = Constants.LOGIN_REGEX)
+ @Size(min = 1, max = 50)
+ @Column(length = 50, unique = true, nullable = false)
+ private String login;
+
+ @JsonIgnore
+ @NotNull
+ @Size(min = 60, max = 60)
+ @Column(name = "password_hash",length = 60)
+ private String password;
+
+ @Size(max = 50)
+ @Column(name = "first_name", length = 50)
+ private String firstName;
+
+ @Size(max = 50)
+ @Column(name = "last_name", length = 50)
+ private String lastName;
+
+ @Email
+ @Size(max = 100)
+ @Column(length = 100, unique = true)
+ private String email;
+
+ @NotNull
+ @Column(nullable = false)
+ private boolean activated = false;
+
+ @Size(min = 2, max = 5)
+ @Column(name = "lang_key", length = 5)
+ private String langKey;
+
+ @Size(max = 256)
+ @Column(name = "image_url", length = 256)
+ private String imageUrl;
+
+ @Size(max = 20)
+ @Column(name = "activation_key", length = 20)
+ @JsonIgnore
+ private String activationKey;
+
+ @Size(max = 20)
+ @Column(name = "reset_key", length = 20)
+ private String resetKey;
+
+ @Column(name = "reset_date")
+ private ZonedDateTime resetDate = null;
+
+ @JsonIgnore
+ @ManyToMany
+ @JoinTable(
+ name = "jhi_user_authority",
+ joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
+ inverseJoinColumns = {@JoinColumn(name = "authority_name", referencedColumnName = "name")})
+ @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
+ @BatchSize(size = 20)
+ private Set authorities = new HashSet<>();
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getLogin() {
+ return login;
+ }
+
+ //Lowercase the login before saving it in database
+ public void setLogin(String login) {
+ this.login = login.toLowerCase(Locale.ENGLISH);
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getImageUrl() {
+ return imageUrl;
+ }
+
+ public void setImageUrl(String imageUrl) {
+ this.imageUrl = imageUrl;
+ }
+
+ public boolean getActivated() {
+ return activated;
+ }
+
+ public void setActivated(boolean activated) {
+ this.activated = activated;
+ }
+
+ public String getActivationKey() {
+ return activationKey;
+ }
+
+ public void setActivationKey(String activationKey) {
+ this.activationKey = activationKey;
+ }
+
+ public String getResetKey() {
+ return resetKey;
+ }
+
+ public void setResetKey(String resetKey) {
+ this.resetKey = resetKey;
+ }
+
+ public ZonedDateTime getResetDate() {
+ return resetDate;
+ }
+
+ public void setResetDate(ZonedDateTime resetDate) {
+ this.resetDate = resetDate;
+ }
+
+ public String getLangKey() {
+ return langKey;
+ }
+
+ public void setLangKey(String langKey) {
+ this.langKey = langKey;
+ }
+
+ public Set getAuthorities() {
+ return authorities;
+ }
+
+ public void setAuthorities(Set authorities) {
+ this.authorities = authorities;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ User user = (User) o;
+
+ if (!login.equals(user.login)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return login.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "login='" + login + '\'' +
+ ", firstName='" + firstName + '\'' +
+ ", lastName='" + lastName + '\'' +
+ ", email='" + email + '\'' +
+ ", imageUrl='" + imageUrl + '\'' +
+ ", activated='" + activated + '\'' +
+ ", langKey='" + langKey + '\'' +
+ ", activationKey='" + activationKey + '\'' +
+ "}";
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/package-info.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/package-info.java
new file mode 100644
index 0000000000..d56162dc07
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/domain/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * JPA domain objects.
+ */
+package com.gateway.domain;
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/TokenRelayFilter.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/TokenRelayFilter.java
new file mode 100644
index 0000000000..ae057b8b00
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/TokenRelayFilter.java
@@ -0,0 +1,36 @@
+package com.gateway.gateway;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+import org.springframework.stereotype.Component;
+
+import java.util.Set;
+
+@Component
+public class TokenRelayFilter extends ZuulFilter {
+ @Override
+ public Object run() {
+ RequestContext ctx = RequestContext.getCurrentContext();
+
+ Set headers = (Set) ctx.get("ignoredHeaders");
+ // We need our JWT tokens relayed to resource servers
+ headers.remove("authorization");
+
+ return null;
+ }
+
+ @Override
+ public boolean shouldFilter() {
+ return true;
+ }
+
+ @Override
+ public String filterType() {
+ return "pre";
+ }
+
+ @Override
+ public int filterOrder() {
+ return 10000;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/accesscontrol/AccessControlFilter.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/accesscontrol/AccessControlFilter.java
new file mode 100644
index 0000000000..b2d9800c4d
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/accesscontrol/AccessControlFilter.java
@@ -0,0 +1,100 @@
+package com.gateway.gateway.accesscontrol;
+
+import io.github.jhipster.config.JHipsterProperties;
+
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.netflix.zuul.filters.Route;
+import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
+import org.springframework.http.HttpStatus;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+
+/**
+ * Zuul filter for restricting access to backend micro-services endpoints.
+ */
+public class AccessControlFilter extends ZuulFilter {
+
+ private final Logger log = LoggerFactory.getLogger(AccessControlFilter.class);
+
+ private final RouteLocator routeLocator;
+
+ private final JHipsterProperties jHipsterProperties;
+
+ public AccessControlFilter(RouteLocator routeLocator, JHipsterProperties jHipsterProperties) {
+ this.routeLocator = routeLocator;
+ this.jHipsterProperties = jHipsterProperties;
+ }
+
+ @Override
+ public String filterType() {
+ return "pre";
+ }
+
+ @Override
+ public int filterOrder() {
+ return 0;
+ }
+
+ /**
+ * Filter requests on endpoints that are not in the list of authorized microservices endpoints.
+ */
+ @Override
+ public boolean shouldFilter() {
+ String requestUri = RequestContext.getCurrentContext().getRequest().getRequestURI();
+
+ // If the request Uri does not start with the path of the authorized endpoints, we block the request
+ for (Route route : routeLocator.getRoutes()) {
+ String serviceUrl = route.getFullPath();
+ String serviceName = route.getId();
+
+ // If this route correspond to the current request URI
+ // We do a substring to remove the "**" at the end of the route URL
+ if (requestUri.startsWith(serviceUrl.substring(0, serviceUrl.length() - 2))) {
+ return !isAuthorizedRequest(serviceUrl, serviceName, requestUri);
+ }
+ }
+ return true;
+ }
+
+ private boolean isAuthorizedRequest(String serviceUrl, String serviceName, String requestUri) {
+ Map> authorizedMicroservicesEndpoints = jHipsterProperties.getGateway()
+ .getAuthorizedMicroservicesEndpoints();
+
+ // If the authorized endpoints list was left empty for this route, all access are allowed
+ if (authorizedMicroservicesEndpoints.get(serviceName) == null) {
+ log.debug("Access Control: allowing access for {}, as no access control policy has been set up for " +
+ "service: {}", requestUri, serviceName);
+ return true;
+ } else {
+ List authorizedEndpoints = authorizedMicroservicesEndpoints.get(serviceName);
+
+ // Go over the authorized endpoints to control that the request URI matches it
+ for (String endpoint : authorizedEndpoints) {
+ // We do a substring to remove the "**/" at the end of the route URL
+ String gatewayEndpoint = serviceUrl.substring(0, serviceUrl.length() - 3) + endpoint;
+ if (requestUri.startsWith(gatewayEndpoint)) {
+ log.debug("Access Control: allowing access for {}, as it matches the following authorized " +
+ "microservice endpoint: {}", requestUri, gatewayEndpoint);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Object run() {
+ RequestContext ctx = RequestContext.getCurrentContext();
+ ctx.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
+ if (ctx.getResponseBody() == null && !ctx.getResponseGZipped()) {
+ ctx.setSendZuulResponse(false);
+ }
+ log.debug("Access Control: filtered unauthorized access on endpoint {}", ctx.getRequest().getRequestURI());
+ return null;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/ratelimiting/RateLimitingFilter.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/ratelimiting/RateLimitingFilter.java
new file mode 100644
index 0000000000..e065491b07
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/ratelimiting/RateLimitingFilter.java
@@ -0,0 +1,103 @@
+package com.gateway.gateway.ratelimiting;
+
+import com.gateway.security.SecurityUtils;
+
+import io.github.jhipster.config.JHipsterProperties;
+
+import java.util.Calendar;
+import java.util.Date;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+
+/**
+ * Zuul filter for limiting the number of HTTP calls per client.
+ */
+public class RateLimitingFilter extends ZuulFilter {
+
+ private final Logger log = LoggerFactory.getLogger(RateLimitingFilter.class);
+
+ private static final String TIME_PERIOD = "hour";
+
+ private long rateLimit = 100000L;
+
+ private final RateLimitingRepository rateLimitingRepository;
+
+ public RateLimitingFilter(RateLimitingRepository rateLimitingRepository, JHipsterProperties jHipsterProperties) {
+ this.rateLimitingRepository = rateLimitingRepository;
+ this.rateLimit = jHipsterProperties.getGateway().getRateLimiting().getLimit();
+ }
+
+ @Override
+ public String filterType() {
+ return "pre";
+ }
+
+ @Override
+ public int filterOrder() {
+ return 10;
+ }
+
+ @Override
+ public boolean shouldFilter() {
+ // specific APIs can be filtered out using
+ // if (RequestContext.getCurrentContext().getRequest().getRequestURI().startsWith("/api")) { ... }
+ return true;
+ }
+
+ @Override
+ public Object run() {
+ String id = getId(RequestContext.getCurrentContext().getRequest());
+ Date date = getPeriod();
+
+ // check current rate limit
+ // default limit per user is 100,000 API calls per hour
+ Long count = rateLimitingRepository.getCounter(id, TIME_PERIOD, date);
+ log.debug("Rate limiting for user {} at {} - {}", id, date, count);
+ if (count > rateLimit) {
+ apiLimitExceeded();
+ } else {
+ // count calls per hour
+ rateLimitingRepository.incrementCounter(id, TIME_PERIOD, date);
+ }
+ return null;
+ }
+
+ private void apiLimitExceeded() {
+ RequestContext ctx = RequestContext.getCurrentContext();
+ ctx.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
+ if (ctx.getResponseBody() == null) {
+ ctx.setResponseBody("API rate limit exceeded");
+ ctx.setSendZuulResponse(false);
+ }
+ }
+
+ /**
+ * The ID that will identify the limit: the user login or the user IP address.
+ */
+ private String getId(HttpServletRequest httpServletRequest) {
+ String login = SecurityUtils.getCurrentUserLogin();
+ if (login != null) {
+ return login;
+ } else {
+ return httpServletRequest.getRemoteAddr();
+ }
+ }
+
+ /**
+ * The period for which the rate is calculated.
+ */
+ private Date getPeriod() {
+ Calendar calendar = Calendar.getInstance();
+ calendar.clear(Calendar.MILLISECOND);
+ calendar.clear(Calendar.SECOND);
+ calendar.clear(Calendar.MINUTE);
+ return calendar.getTime();
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/ratelimiting/RateLimitingRepository.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/ratelimiting/RateLimitingRepository.java
new file mode 100644
index 0000000000..9c710f1b46
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/ratelimiting/RateLimitingRepository.java
@@ -0,0 +1,51 @@
+package com.gateway.gateway.ratelimiting;
+
+import java.util.Date;
+
+import com.datastax.driver.core.*;
+
+/**
+ * Repository storing data used by the gateway's rate limiting filter.
+ */
+public class RateLimitingRepository {
+
+ private final Session session;
+
+ private PreparedStatement rateLimitingIncrement;
+
+ private PreparedStatement rateLimitingCount;
+
+ public RateLimitingRepository(Session session) {
+ this.session = session;
+ this.rateLimitingIncrement = session.prepare(
+ "UPDATE gateway_ratelimiting\n" +
+ " SET value = value + 1\n" +
+ " WHERE id = :id AND time_unit = :time_unit AND time = :time");
+
+ this.rateLimitingCount = session.prepare(
+ "SELECT value\n" +
+ " FROM gateway_ratelimiting\n" +
+ " WHERE id = :id AND time_unit = :time_unit AND time = :time"
+ );
+ }
+
+ public void incrementCounter(String id, String timeUnit, Date time) {
+ BoundStatement stmt = rateLimitingIncrement.bind();
+ stmt.setString("id", id);
+ stmt.setString("time_unit", timeUnit);
+ stmt.setTimestamp("time", time);
+ session.executeAsync(stmt);
+ }
+
+ public long getCounter(String id, String timeUnit, Date time) {
+ BoundStatement stmt = rateLimitingCount.bind();
+ stmt.setString("id", id);
+ stmt.setString("time_unit", timeUnit);
+ stmt.setTimestamp("time", time);
+ ResultSet rs = session.execute(stmt);
+ if (rs.isExhausted()) {
+ return 0;
+ }
+ return rs.one().getLong(0);
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/responserewriting/SwaggerBasePathRewritingFilter.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/responserewriting/SwaggerBasePathRewritingFilter.java
new file mode 100644
index 0000000000..43b1ec4f5a
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/gateway/responserewriting/SwaggerBasePathRewritingFilter.java
@@ -0,0 +1,78 @@
+package com.gateway.gateway.responserewriting;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.netflix.zuul.context.RequestContext;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter;
+import springfox.documentation.swagger2.web.Swagger2Controller;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.LinkedHashMap;
+import java.util.zip.GZIPInputStream;
+
+/**
+ * Zuul filter to rewrite micro-services Swagger URL Base Path.
+ */
+public class SwaggerBasePathRewritingFilter extends SendResponseFilter {
+
+ private final Logger log = LoggerFactory.getLogger(SwaggerBasePathRewritingFilter.class);
+
+ private ObjectMapper mapper = new ObjectMapper();
+
+ @Override
+ public String filterType() {
+ return "post";
+ }
+
+ @Override
+ public int filterOrder() {
+ return 100;
+ }
+
+ /**
+ * Filter requests to micro-services Swagger docs.
+ */
+ @Override
+ public boolean shouldFilter() {
+ return RequestContext.getCurrentContext().getRequest().getRequestURI().endsWith(Swagger2Controller.DEFAULT_URL);
+ }
+
+ @Override
+ public Object run() {
+ RequestContext context = RequestContext.getCurrentContext();
+
+ if (!context.getResponseGZipped()) {
+ context.getResponse().setCharacterEncoding("UTF-8");
+ }
+
+ String rewrittenResponse = rewriteBasePath(context);
+ context.setResponseBody(rewrittenResponse);
+ return null;
+ }
+
+ private String rewriteBasePath(RequestContext context) {
+ InputStream responseDataStream = context.getResponseDataStream();
+ String requestUri = RequestContext.getCurrentContext().getRequest().getRequestURI();
+ try {
+ if (context.getResponseGZipped()) {
+ responseDataStream = new GZIPInputStream(context.getResponseDataStream());
+ }
+ String response = IOUtils.toString(responseDataStream, StandardCharsets.UTF_8);
+ if (response != null) {
+ LinkedHashMap map = this.mapper.readValue(response, LinkedHashMap.class);
+
+ String basePath = requestUri.replace(Swagger2Controller.DEFAULT_URL,"");
+ map.put("basePath",basePath);
+ log.debug("Swagger-docs: rewritten Base URL with correct micro-service route: {}", basePath);
+ return mapper.writeValueAsString(map);
+ }
+ } catch (IOException e) {
+ log.error("Swagger-docs filter error", e);
+ }
+ return null;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/AuthorityRepository.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/AuthorityRepository.java
new file mode 100644
index 0000000000..553c8913b6
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/AuthorityRepository.java
@@ -0,0 +1,11 @@
+package com.gateway.repository;
+
+import com.gateway.domain.Authority;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * Spring Data JPA repository for the Authority entity.
+ */
+public interface AuthorityRepository extends JpaRepository {
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/CustomAuditEventRepository.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/CustomAuditEventRepository.java
new file mode 100644
index 0000000000..6eb893f095
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/CustomAuditEventRepository.java
@@ -0,0 +1,81 @@
+package com.gateway.repository;
+
+import com.gateway.config.Constants;
+import com.gateway.config.audit.AuditEventConverter;
+import com.gateway.domain.PersistentAuditEvent;
+
+import org.springframework.boot.actuate.audit.AuditEvent;
+import org.springframework.boot.actuate.audit.AuditEventRepository;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * An implementation of Spring Boot's AuditEventRepository.
+ */
+@Repository
+public class CustomAuditEventRepository implements AuditEventRepository {
+
+ private static final String AUTHORIZATION_FAILURE = "AUTHORIZATION_FAILURE";
+
+ private final PersistenceAuditEventRepository persistenceAuditEventRepository;
+
+ private final AuditEventConverter auditEventConverter;
+
+ public CustomAuditEventRepository(PersistenceAuditEventRepository persistenceAuditEventRepository,
+ AuditEventConverter auditEventConverter) {
+
+ this.persistenceAuditEventRepository = persistenceAuditEventRepository;
+ this.auditEventConverter = auditEventConverter;
+ }
+
+ @Override
+ public List find(Date after) {
+ Iterable persistentAuditEvents =
+ persistenceAuditEventRepository.findByAuditEventDateAfter(LocalDateTime.from(after.toInstant()));
+ return auditEventConverter.convertToAuditEvent(persistentAuditEvents);
+ }
+
+ @Override
+ public List find(String principal, Date after) {
+ Iterable persistentAuditEvents;
+ if (principal == null && after == null) {
+ persistentAuditEvents = persistenceAuditEventRepository.findAll();
+ } else if (after == null) {
+ persistentAuditEvents = persistenceAuditEventRepository.findByPrincipal(principal);
+ } else {
+ persistentAuditEvents =
+ persistenceAuditEventRepository.findByPrincipalAndAuditEventDateAfter(principal, LocalDateTime.from(after.toInstant()));
+ }
+ return auditEventConverter.convertToAuditEvent(persistentAuditEvents);
+ }
+
+ @Override
+ public List find(String principal, Date after, String type) {
+ Iterable persistentAuditEvents =
+ persistenceAuditEventRepository.findByPrincipalAndAuditEventDateAfterAndAuditEventType(principal, LocalDateTime.from(after.toInstant()), type);
+ return auditEventConverter.convertToAuditEvent(persistentAuditEvents);
+ }
+
+ @Override
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
+ public void add(AuditEvent event) {
+ if (!AUTHORIZATION_FAILURE.equals(event.getType()) &&
+ !Constants.ANONYMOUS_USER.equals(event.getPrincipal())) {
+
+ PersistentAuditEvent persistentAuditEvent = new PersistentAuditEvent();
+ persistentAuditEvent.setPrincipal(event.getPrincipal());
+ persistentAuditEvent.setAuditEventType(event.getType());
+ Instant instant = Instant.ofEpochMilli(event.getTimestamp().getTime());
+ persistentAuditEvent.setAuditEventDate(LocalDateTime.ofInstant(instant, ZoneId.systemDefault()));
+ persistentAuditEvent.setData(auditEventConverter.convertDataToStrings(event.getData()));
+ persistenceAuditEventRepository.save(persistentAuditEvent);
+ }
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/PersistenceAuditEventRepository.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/PersistenceAuditEventRepository.java
new file mode 100644
index 0000000000..7c6ba05d54
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/PersistenceAuditEventRepository.java
@@ -0,0 +1,26 @@
+package com.gateway.repository;
+
+import com.gateway.domain.PersistentAuditEvent;
+
+import java.time.LocalDateTime;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+import java.util.List;
+
+/**
+ * Spring Data JPA repository for the PersistentAuditEvent entity.
+ */
+public interface PersistenceAuditEventRepository extends JpaRepository {
+
+ List findByPrincipal(String principal);
+
+ List findByAuditEventDateAfter(LocalDateTime after);
+
+ List findByPrincipalAndAuditEventDateAfter(String principal, LocalDateTime after);
+
+ List findByPrincipalAndAuditEventDateAfterAndAuditEventType(String principle, LocalDateTime after, String type);
+
+ Page findAllByAuditEventDateBetween(LocalDateTime fromDate, LocalDateTime toDate, Pageable pageable);
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/UserRepository.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/UserRepository.java
new file mode 100644
index 0000000000..41b10f2ecf
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/UserRepository.java
@@ -0,0 +1,37 @@
+package com.gateway.repository;
+
+import com.gateway.domain.User;
+
+import java.time.ZonedDateTime;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.EntityGraph;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Spring Data JPA repository for the User entity.
+ */
+public interface UserRepository extends JpaRepository {
+
+ Optional findOneByActivationKey(String activationKey);
+
+ List findAllByActivatedIsFalseAndCreatedDateBefore(ZonedDateTime dateTime);
+
+ Optional findOneByResetKey(String resetKey);
+
+ Optional findOneByEmail(String email);
+
+ Optional findOneByLogin(String login);
+
+ @EntityGraph(attributePaths = "authorities")
+ User findOneWithAuthoritiesById(Long id);
+
+ @EntityGraph(attributePaths = "authorities")
+ Optional findOneWithAuthoritiesByLogin(String login);
+
+ Page findAllByLoginNot(Pageable pageable, String login);
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/package-info.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/package-info.java
new file mode 100644
index 0000000000..f15a3e98c6
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/repository/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Spring Data JPA repositories.
+ */
+package com.gateway.repository;
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/AuthoritiesConstants.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/AuthoritiesConstants.java
new file mode 100644
index 0000000000..bdf81f928b
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/AuthoritiesConstants.java
@@ -0,0 +1,16 @@
+package com.gateway.security;
+
+/**
+ * Constants for Spring Security authorities.
+ */
+public final class AuthoritiesConstants {
+
+ public static final String ADMIN = "ROLE_ADMIN";
+
+ public static final String USER = "ROLE_USER";
+
+ public static final String ANONYMOUS = "ROLE_ANONYMOUS";
+
+ private AuthoritiesConstants() {
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/DomainUserDetailsService.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/DomainUserDetailsService.java
new file mode 100644
index 0000000000..e175d83cb9
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/DomainUserDetailsService.java
@@ -0,0 +1,51 @@
+package com.gateway.security;
+
+import com.gateway.domain.User;
+import com.gateway.repository.UserRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Authenticate a user from the database.
+ */
+@Component("userDetailsService")
+public class DomainUserDetailsService implements UserDetailsService {
+
+ private final Logger log = LoggerFactory.getLogger(DomainUserDetailsService.class);
+
+ private final UserRepository userRepository;
+
+ public DomainUserDetailsService(UserRepository userRepository) {
+ this.userRepository = userRepository;
+ }
+
+ @Override
+ @Transactional
+ public UserDetails loadUserByUsername(final String login) {
+ log.debug("Authenticating {}", login);
+ String lowercaseLogin = login.toLowerCase(Locale.ENGLISH);
+ Optional userFromDatabase = userRepository.findOneWithAuthoritiesByLogin(lowercaseLogin);
+ return userFromDatabase.map(user -> {
+ if (!user.getActivated()) {
+ throw new UserNotActivatedException("User " + lowercaseLogin + " was not activated");
+ }
+ List grantedAuthorities = user.getAuthorities().stream()
+ .map(authority -> new SimpleGrantedAuthority(authority.getName()))
+ .collect(Collectors.toList());
+ return new org.springframework.security.core.userdetails.User(lowercaseLogin,
+ user.getPassword(),
+ grantedAuthorities);
+ }).orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the " +
+ "database"));
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/SecurityUtils.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/SecurityUtils.java
new file mode 100644
index 0000000000..5fed368fe3
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/SecurityUtils.java
@@ -0,0 +1,68 @@
+package com.gateway.security;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+
+/**
+ * Utility class for Spring Security.
+ */
+public final class SecurityUtils {
+
+ private SecurityUtils() {
+ }
+
+ /**
+ * Get the login of the current user.
+ *
+ * @return the login of the current user
+ */
+ public static String getCurrentUserLogin() {
+ SecurityContext securityContext = SecurityContextHolder.getContext();
+ Authentication authentication = securityContext.getAuthentication();
+ String userName = null;
+ if (authentication != null) {
+ if (authentication.getPrincipal() instanceof UserDetails) {
+ UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
+ userName = springSecurityUser.getUsername();
+ } else if (authentication.getPrincipal() instanceof String) {
+ userName = (String) authentication.getPrincipal();
+ }
+ }
+ return userName;
+ }
+
+ /**
+ * Check if a user is authenticated.
+ *
+ * @return true if the user is authenticated, false otherwise
+ */
+ public static boolean isAuthenticated() {
+ SecurityContext securityContext = SecurityContextHolder.getContext();
+ Authentication authentication = securityContext.getAuthentication();
+ if (authentication != null) {
+ return authentication.getAuthorities().stream()
+ .noneMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(AuthoritiesConstants.ANONYMOUS));
+ }
+ return false;
+ }
+
+ /**
+ * If the current user has a specific authority (security role).
+ *
+ * The name of this method comes from the isUserInRole() method in the Servlet API
+ *
+ * @param authority the authority to check
+ * @return true if the current user has the authority, false otherwise
+ */
+ public static boolean isCurrentUserInRole(String authority) {
+ SecurityContext securityContext = SecurityContextHolder.getContext();
+ Authentication authentication = securityContext.getAuthentication();
+ if (authentication != null) {
+ return authentication.getAuthorities().stream()
+ .anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(authority));
+ }
+ return false;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/SpringSecurityAuditorAware.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/SpringSecurityAuditorAware.java
new file mode 100644
index 0000000000..f1dd81f129
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/SpringSecurityAuditorAware.java
@@ -0,0 +1,19 @@
+package com.gateway.security;
+
+import com.gateway.config.Constants;
+
+import org.springframework.data.domain.AuditorAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * Implementation of AuditorAware based on Spring Security.
+ */
+@Component
+public class SpringSecurityAuditorAware implements AuditorAware {
+
+ @Override
+ public String getCurrentAuditor() {
+ String userName = SecurityUtils.getCurrentUserLogin();
+ return userName != null ? userName : Constants.SYSTEM_ACCOUNT;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/UserNotActivatedException.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/UserNotActivatedException.java
new file mode 100644
index 0000000000..d8bd57ccfe
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/UserNotActivatedException.java
@@ -0,0 +1,19 @@
+package com.gateway.security;
+
+import org.springframework.security.core.AuthenticationException;
+
+/**
+ * This exception is thrown in case of a not activated user trying to authenticate.
+ */
+public class UserNotActivatedException extends AuthenticationException {
+
+ private static final long serialVersionUID = 1L;
+
+ public UserNotActivatedException(String message) {
+ super(message);
+ }
+
+ public UserNotActivatedException(String message, Throwable t) {
+ super(message, t);
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/jwt/JWTConfigurer.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/jwt/JWTConfigurer.java
new file mode 100644
index 0000000000..a673e98b3e
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/jwt/JWTConfigurer.java
@@ -0,0 +1,23 @@
+package com.gateway.security.jwt;
+
+import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.web.DefaultSecurityFilterChain;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+public class JWTConfigurer extends SecurityConfigurerAdapter {
+
+ public static final String AUTHORIZATION_HEADER = "Authorization";
+
+ private TokenProvider tokenProvider;
+
+ public JWTConfigurer(TokenProvider tokenProvider) {
+ this.tokenProvider = tokenProvider;
+ }
+
+ @Override
+ public void configure(HttpSecurity http) throws Exception {
+ JWTFilter customFilter = new JWTFilter(tokenProvider);
+ http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/jwt/JWTFilter.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/jwt/JWTFilter.java
new file mode 100644
index 0000000000..58462ce4a8
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/jwt/JWTFilter.java
@@ -0,0 +1,58 @@
+package com.gateway.security.jwt;
+
+import java.io.IOException;
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.util.StringUtils;
+import org.springframework.web.filter.GenericFilterBean;
+
+import io.jsonwebtoken.ExpiredJwtException;
+
+/**
+ * Filters incoming requests and installs a Spring Security principal if a header corresponding to a valid user is
+ * found.
+ */
+public class JWTFilter extends GenericFilterBean {
+
+ private final Logger log = LoggerFactory.getLogger(JWTFilter.class);
+
+ private TokenProvider tokenProvider;
+
+ public JWTFilter(TokenProvider tokenProvider) {
+ this.tokenProvider = tokenProvider;
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+ throws IOException, ServletException {
+ try {
+ HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
+ String jwt = resolveToken(httpServletRequest);
+ if (StringUtils.hasText(jwt) && this.tokenProvider.validateToken(jwt)) {
+ Authentication authentication = this.tokenProvider.getAuthentication(jwt);
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ }
+ filterChain.doFilter(servletRequest, servletResponse);
+ } catch (ExpiredJwtException eje) {
+ log.info("Security exception for user {} - {}",
+ eje.getClaims().getSubject(), eje.getMessage());
+
+ log.trace("Security exception trace: {}", eje);
+ ((HttpServletResponse) servletResponse).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ }
+ }
+
+ private String resolveToken(HttpServletRequest request){
+ String bearerToken = request.getHeader(JWTConfigurer.AUTHORIZATION_HEADER);
+ if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
+ return bearerToken.substring(7, bearerToken.length());
+ }
+ return null;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/jwt/TokenProvider.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/jwt/TokenProvider.java
new file mode 100644
index 0000000000..5ffb55f33e
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/jwt/TokenProvider.java
@@ -0,0 +1,109 @@
+package com.gateway.security.jwt;
+
+import io.github.jhipster.config.JHipsterProperties;
+
+import java.util.*;
+import java.util.stream.Collectors;
+import javax.annotation.PostConstruct;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.stereotype.Component;
+
+import io.jsonwebtoken.*;
+
+@Component
+public class TokenProvider {
+
+ private final Logger log = LoggerFactory.getLogger(TokenProvider.class);
+
+ private static final String AUTHORITIES_KEY = "auth";
+
+ private String secretKey;
+
+ private long tokenValidityInMilliseconds;
+
+ private long tokenValidityInMillisecondsForRememberMe;
+
+ private final JHipsterProperties jHipsterProperties;
+
+ public TokenProvider(JHipsterProperties jHipsterProperties) {
+ this.jHipsterProperties = jHipsterProperties;
+ }
+
+ @PostConstruct
+ public void init() {
+ this.secretKey =
+ jHipsterProperties.getSecurity().getAuthentication().getJwt().getSecret();
+
+ this.tokenValidityInMilliseconds =
+ 1000 * jHipsterProperties.getSecurity().getAuthentication().getJwt().getTokenValidityInSeconds();
+ this.tokenValidityInMillisecondsForRememberMe =
+ 1000 * jHipsterProperties.getSecurity().getAuthentication().getJwt().getTokenValidityInSecondsForRememberMe();
+ }
+
+ public String createToken(Authentication authentication, Boolean rememberMe) {
+ String authorities = authentication.getAuthorities().stream()
+ .map(GrantedAuthority::getAuthority)
+ .collect(Collectors.joining(","));
+
+ long now = (new Date()).getTime();
+ Date validity;
+ if (rememberMe) {
+ validity = new Date(now + this.tokenValidityInMillisecondsForRememberMe);
+ } else {
+ validity = new Date(now + this.tokenValidityInMilliseconds);
+ }
+
+ return Jwts.builder()
+ .setSubject(authentication.getName())
+ .claim(AUTHORITIES_KEY, authorities)
+ .signWith(SignatureAlgorithm.HS512, secretKey)
+ .setExpiration(validity)
+ .compact();
+ }
+
+ public Authentication getAuthentication(String token) {
+ Claims claims = Jwts.parser()
+ .setSigningKey(secretKey)
+ .parseClaimsJws(token)
+ .getBody();
+
+ Collection extends GrantedAuthority> authorities =
+ Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(","))
+ .map(SimpleGrantedAuthority::new)
+ .collect(Collectors.toList());
+
+ User principal = new User(claims.getSubject(), "", authorities);
+
+ return new UsernamePasswordAuthenticationToken(principal, "", authorities);
+ }
+
+ public boolean validateToken(String authToken) {
+ try {
+ Jwts.parser().setSigningKey(secretKey).parseClaimsJws(authToken);
+ return true;
+ } catch (SignatureException e) {
+ log.info("Invalid JWT signature.");
+ log.trace("Invalid JWT signature trace: {}", e);
+ } catch (MalformedJwtException e) {
+ log.info("Invalid JWT token.");
+ log.trace("Invalid JWT token trace: {}", e);
+ } catch (ExpiredJwtException e) {
+ log.info("Expired JWT token.");
+ log.trace("Expired JWT token trace: {}", e);
+ } catch (UnsupportedJwtException e) {
+ log.info("Unsupported JWT token.");
+ log.trace("Unsupported JWT token trace: {}", e);
+ } catch (IllegalArgumentException e) {
+ log.info("JWT token compact of handler are invalid.");
+ log.trace("JWT token compact of handler are invalid trace: {}", e);
+ }
+ return false;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/package-info.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/package-info.java
new file mode 100644
index 0000000000..d834be18bf
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Spring Security configuration.
+ */
+package com.gateway.security;
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/AuditEventService.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/AuditEventService.java
new file mode 100644
index 0000000000..64c63a7938
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/AuditEventService.java
@@ -0,0 +1,50 @@
+package com.gateway.service;
+
+import com.gateway.config.audit.AuditEventConverter;
+import com.gateway.repository.PersistenceAuditEventRepository;
+import java.time.LocalDateTime;
+import org.springframework.boot.actuate.audit.AuditEvent;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Optional;
+
+/**
+ * Service for managing audit events.
+ *
+ * This is the default implementation to support SpringBoot Actuator AuditEventRepository
+ *
+ */
+@Service
+@Transactional
+public class AuditEventService {
+
+ private final PersistenceAuditEventRepository persistenceAuditEventRepository;
+
+ private final AuditEventConverter auditEventConverter;
+
+ public AuditEventService(
+ PersistenceAuditEventRepository persistenceAuditEventRepository,
+ AuditEventConverter auditEventConverter) {
+
+ this.persistenceAuditEventRepository = persistenceAuditEventRepository;
+ this.auditEventConverter = auditEventConverter;
+ }
+
+ public Page findAll(Pageable pageable) {
+ return persistenceAuditEventRepository.findAll(pageable)
+ .map(auditEventConverter::convertToAuditEvent);
+ }
+
+ public Page findByDates(LocalDateTime fromDate, LocalDateTime toDate, Pageable pageable) {
+ return persistenceAuditEventRepository.findAllByAuditEventDateBetween(fromDate, toDate, pageable)
+ .map(auditEventConverter::convertToAuditEvent);
+ }
+
+ public Optional find(Long id) {
+ return Optional.ofNullable(persistenceAuditEventRepository.findOne(id)).map
+ (auditEventConverter::convertToAuditEvent);
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/MailService.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/MailService.java
new file mode 100644
index 0000000000..5191b69d0d
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/MailService.java
@@ -0,0 +1,108 @@
+package com.gateway.service;
+
+import com.gateway.domain.User;
+
+import io.github.jhipster.config.JHipsterProperties;
+
+import org.apache.commons.lang3.CharEncoding;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.MessageSource;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.MimeMessageHelper;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.thymeleaf.context.Context;
+import org.thymeleaf.spring4.SpringTemplateEngine;
+
+import javax.mail.internet.MimeMessage;
+import java.util.Locale;
+
+/**
+ * Service for sending e-mails.
+ *
+ * We use the @Async annotation to send e-mails asynchronously.
+ *
+ */
+@Service
+public class MailService {
+
+ private final Logger log = LoggerFactory.getLogger(MailService.class);
+
+ private static final String USER = "user";
+
+ private static final String BASE_URL = "baseUrl";
+
+ private final JHipsterProperties jHipsterProperties;
+
+ private final JavaMailSender javaMailSender;
+
+ private final MessageSource messageSource;
+
+ private final SpringTemplateEngine templateEngine;
+
+ public MailService(JHipsterProperties jHipsterProperties, JavaMailSender javaMailSender,
+ MessageSource messageSource, SpringTemplateEngine templateEngine) {
+
+ this.jHipsterProperties = jHipsterProperties;
+ this.javaMailSender = javaMailSender;
+ this.messageSource = messageSource;
+ this.templateEngine = templateEngine;
+ }
+
+ @Async
+ public void sendEmail(String to, String subject, String content, boolean isMultipart, boolean isHtml) {
+ log.debug("Send e-mail[multipart '{}' and html '{}'] to '{}' with subject '{}' and content={}",
+ isMultipart, isHtml, to, subject, content);
+
+ // Prepare message using a Spring helper
+ MimeMessage mimeMessage = javaMailSender.createMimeMessage();
+ try {
+ MimeMessageHelper message = new MimeMessageHelper(mimeMessage, isMultipart, CharEncoding.UTF_8);
+ message.setTo(to);
+ message.setFrom(jHipsterProperties.getMail().getFrom());
+ message.setSubject(subject);
+ message.setText(content, isHtml);
+ javaMailSender.send(mimeMessage);
+ log.debug("Sent e-mail to User '{}'", to);
+ } catch (Exception e) {
+ log.warn("E-mail could not be sent to user '{}'", to, e);
+ }
+ }
+
+ @Async
+ public void sendActivationEmail(User user) {
+ log.debug("Sending activation e-mail to '{}'", user.getEmail());
+ Locale locale = Locale.forLanguageTag(user.getLangKey());
+ Context context = new Context(locale);
+ context.setVariable(USER, user);
+ context.setVariable(BASE_URL, jHipsterProperties.getMail().getBaseUrl());
+ String content = templateEngine.process("activationEmail", context);
+ String subject = messageSource.getMessage("email.activation.title", null, locale);
+ sendEmail(user.getEmail(), subject, content, false, true);
+ }
+
+ @Async
+ public void sendCreationEmail(User user) {
+ log.debug("Sending creation e-mail to '{}'", user.getEmail());
+ Locale locale = Locale.forLanguageTag(user.getLangKey());
+ Context context = new Context(locale);
+ context.setVariable(USER, user);
+ context.setVariable(BASE_URL, jHipsterProperties.getMail().getBaseUrl());
+ String content = templateEngine.process("creationEmail", context);
+ String subject = messageSource.getMessage("email.activation.title", null, locale);
+ sendEmail(user.getEmail(), subject, content, false, true);
+ }
+
+ @Async
+ public void sendPasswordResetMail(User user) {
+ log.debug("Sending password reset e-mail to '{}'", user.getEmail());
+ Locale locale = Locale.forLanguageTag(user.getLangKey());
+ Context context = new Context(locale);
+ context.setVariable(USER, user);
+ context.setVariable(BASE_URL, jHipsterProperties.getMail().getBaseUrl());
+ String content = templateEngine.process("passwordResetEmail", context);
+ String subject = messageSource.getMessage("email.reset.title", null, locale);
+ sendEmail(user.getEmail(), subject, content, false, true);
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/UserService.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/UserService.java
new file mode 100644
index 0000000000..a95136bca4
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/UserService.java
@@ -0,0 +1,228 @@
+package com.gateway.service;
+
+import com.gateway.domain.Authority;
+import com.gateway.domain.User;
+import com.gateway.repository.AuthorityRepository;
+import com.gateway.config.Constants;
+import com.gateway.repository.UserRepository;
+import com.gateway.security.AuthoritiesConstants;
+import com.gateway.security.SecurityUtils;
+import com.gateway.service.util.RandomUtil;
+import com.gateway.service.dto.UserDTO;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.ZonedDateTime;
+import java.util.*;
+
+/**
+ * Service class for managing users.
+ */
+@Service
+@Transactional
+public class UserService {
+
+ private final Logger log = LoggerFactory.getLogger(UserService.class);
+
+ private final UserRepository userRepository;
+
+ private final PasswordEncoder passwordEncoder;
+
+ private final AuthorityRepository authorityRepository;
+
+ public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, AuthorityRepository authorityRepository) {
+ this.userRepository = userRepository;
+ this.passwordEncoder = passwordEncoder;
+ this.authorityRepository = authorityRepository;
+ }
+
+ public Optional activateRegistration(String key) {
+ log.debug("Activating user for activation key {}", key);
+ return userRepository.findOneByActivationKey(key)
+ .map(user -> {
+ // activate given user for the registration key.
+ user.setActivated(true);
+ user.setActivationKey(null);
+ log.debug("Activated user: {}", user);
+ return user;
+ });
+ }
+
+ public Optional completePasswordReset(String newPassword, String key) {
+ log.debug("Reset user password for reset key {}", key);
+
+ return userRepository.findOneByResetKey(key)
+ .filter(user -> {
+ ZonedDateTime oneDayAgo = ZonedDateTime.now().minusHours(24);
+ return user.getResetDate().isAfter(oneDayAgo);
+ })
+ .map(user -> {
+ user.setPassword(passwordEncoder.encode(newPassword));
+ user.setResetKey(null);
+ user.setResetDate(null);
+ return user;
+ });
+ }
+
+ public Optional requestPasswordReset(String mail) {
+ return userRepository.findOneByEmail(mail)
+ .filter(User::getActivated)
+ .map(user -> {
+ user.setResetKey(RandomUtil.generateResetKey());
+ user.setResetDate(ZonedDateTime.now());
+ return user;
+ });
+ }
+
+ public User createUser(String login, String password, String firstName, String lastName, String email,
+ String imageUrl, String langKey) {
+
+ User newUser = new User();
+ Authority authority = authorityRepository.findOne(AuthoritiesConstants.USER);
+ Set authorities = new HashSet<>();
+ String encryptedPassword = passwordEncoder.encode(password);
+ newUser.setLogin(login);
+ // new user gets initially a generated password
+ newUser.setPassword(encryptedPassword);
+ newUser.setFirstName(firstName);
+ newUser.setLastName(lastName);
+ newUser.setEmail(email);
+ newUser.setImageUrl(imageUrl);
+ newUser.setLangKey(langKey);
+ // new user is not active
+ newUser.setActivated(false);
+ // new user gets registration key
+ newUser.setActivationKey(RandomUtil.generateActivationKey());
+ authorities.add(authority);
+ newUser.setAuthorities(authorities);
+ userRepository.save(newUser);
+ log.debug("Created Information for User: {}", newUser);
+ return newUser;
+ }
+
+ public User createUser(UserDTO userDTO) {
+ User user = new User();
+ user.setLogin(userDTO.getLogin());
+ user.setFirstName(userDTO.getFirstName());
+ user.setLastName(userDTO.getLastName());
+ user.setEmail(userDTO.getEmail());
+ user.setImageUrl(userDTO.getImageUrl());
+ if (userDTO.getLangKey() == null) {
+ user.setLangKey("en"); // default language
+ } else {
+ user.setLangKey(userDTO.getLangKey());
+ }
+ if (userDTO.getAuthorities() != null) {
+ Set authorities = new HashSet<>();
+ userDTO.getAuthorities().forEach(
+ authority -> authorities.add(authorityRepository.findOne(authority))
+ );
+ user.setAuthorities(authorities);
+ }
+ String encryptedPassword = passwordEncoder.encode(RandomUtil.generatePassword());
+ user.setPassword(encryptedPassword);
+ user.setResetKey(RandomUtil.generateResetKey());
+ user.setResetDate(ZonedDateTime.now());
+ user.setActivated(true);
+ userRepository.save(user);
+ log.debug("Created Information for User: {}", user);
+ return user;
+ }
+
+ /**
+ * Update basic information (first name, last name, email, language) for the current user.
+ */
+ public void updateUser(String firstName, String lastName, String email, String langKey) {
+ userRepository.findOneByLogin(SecurityUtils.getCurrentUserLogin()).ifPresent(user -> {
+ user.setFirstName(firstName);
+ user.setLastName(lastName);
+ user.setEmail(email);
+ user.setLangKey(langKey);
+ log.debug("Changed Information for User: {}", user);
+ });
+ }
+
+ /**
+ * Update all information for a specific user, and return the modified user.
+ */
+ public Optional updateUser(UserDTO userDTO) {
+ return Optional.of(userRepository
+ .findOne(userDTO.getId()))
+ .map(user -> {
+ user.setLogin(userDTO.getLogin());
+ user.setFirstName(userDTO.getFirstName());
+ user.setLastName(userDTO.getLastName());
+ user.setEmail(userDTO.getEmail());
+ user.setImageUrl(userDTO.getImageUrl());
+ user.setActivated(userDTO.isActivated());
+ user.setLangKey(userDTO.getLangKey());
+ Set managedAuthorities = user.getAuthorities();
+ managedAuthorities.clear();
+ userDTO.getAuthorities().stream()
+ .map(authorityRepository::findOne)
+ .forEach(managedAuthorities::add);
+ log.debug("Changed Information for User: {}", user);
+ return user;
+ })
+ .map(UserDTO::new);
+ }
+
+ public void deleteUser(String login) {
+ userRepository.findOneByLogin(login).ifPresent(user -> {
+ userRepository.delete(user);
+ log.debug("Deleted User: {}", user);
+ });
+ }
+
+ public void changePassword(String password) {
+ userRepository.findOneByLogin(SecurityUtils.getCurrentUserLogin()).ifPresent(user -> {
+ String encryptedPassword = passwordEncoder.encode(password);
+ user.setPassword(encryptedPassword);
+ log.debug("Changed password for User: {}", user);
+ });
+ }
+
+ @Transactional(readOnly = true)
+ public Page getAllManagedUsers(Pageable pageable) {
+ return userRepository.findAllByLoginNot(pageable, Constants.ANONYMOUS_USER).map(UserDTO::new);
+ }
+
+ @Transactional(readOnly = true)
+ public Optional getUserWithAuthoritiesByLogin(String login) {
+ return userRepository.findOneWithAuthoritiesByLogin(login);
+ }
+
+ @Transactional(readOnly = true)
+ public User getUserWithAuthorities(Long id) {
+ return userRepository.findOneWithAuthoritiesById(id);
+ }
+
+ @Transactional(readOnly = true)
+ public User getUserWithAuthorities() {
+ return userRepository.findOneWithAuthoritiesByLogin(SecurityUtils.getCurrentUserLogin()).orElse(null);
+ }
+
+
+ /**
+ * Not activated users should be automatically deleted after 3 days.
+ *
+ * This is scheduled to get fired everyday, at 01:00 (am).
+ *
+ */
+ @Scheduled(cron = "0 0 1 * * ?")
+ public void removeNotActivatedUsers() {
+ ZonedDateTime now = ZonedDateTime.now();
+ List users = userRepository.findAllByActivatedIsFalseAndCreatedDateBefore(now.minusDays(3));
+ for (User user : users) {
+ log.debug("Deleting not activated user {}", user.getLogin());
+ userRepository.delete(user);
+ }
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/dto/UserDTO.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/dto/UserDTO.java
new file mode 100644
index 0000000000..7acf62b299
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/dto/UserDTO.java
@@ -0,0 +1,167 @@
+package com.gateway.service.dto;
+
+import com.gateway.config.Constants;
+
+import com.gateway.domain.Authority;
+import com.gateway.domain.User;
+
+import org.hibernate.validator.constraints.Email;
+
+import javax.validation.constraints.*;
+import java.time.ZonedDateTime;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * A DTO representing a user, with his authorities.
+ */
+public class UserDTO {
+
+ private Long id;
+
+ @Pattern(regexp = Constants.LOGIN_REGEX)
+ @Size(min = 1, max = 50)
+ private String login;
+
+ @Size(max = 50)
+ private String firstName;
+
+ @Size(max = 50)
+ private String lastName;
+
+ @Email
+ @Size(min = 5, max = 100)
+ private String email;
+
+ @Size(max = 256)
+ private String imageUrl;
+
+ private boolean activated = false;
+
+ @Size(min = 2, max = 5)
+ private String langKey;
+
+ private String createdBy;
+
+ private ZonedDateTime createdDate;
+
+ private String lastModifiedBy;
+
+ private ZonedDateTime lastModifiedDate;
+
+ private Set authorities;
+
+ public UserDTO() {
+ // Empty constructor needed for MapStruct.
+ }
+
+ public UserDTO(User user) {
+ this(user.getId(), user.getLogin(), user.getFirstName(), user.getLastName(),
+ user.getEmail(), user.getActivated(), user.getImageUrl(), user.getLangKey(),
+ user.getCreatedBy(), user.getCreatedDate(), user.getLastModifiedBy(), user.getLastModifiedDate(),
+ user.getAuthorities().stream().map(Authority::getName)
+ .collect(Collectors.toSet()));
+ }
+
+ public UserDTO(Long id, String login, String firstName, String lastName,
+ String email, boolean activated, String imageUrl, String langKey,
+ String createdBy, ZonedDateTime createdDate, String lastModifiedBy, ZonedDateTime lastModifiedDate,
+ Set authorities) {
+
+ this.id = id;
+ this.login = login;
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.email = email;
+ this.activated = activated;
+ this.imageUrl = imageUrl;
+ this.langKey = langKey;
+ this.createdBy = createdBy;
+ this.createdDate = createdDate;
+ this.lastModifiedBy = lastModifiedBy;
+ this.lastModifiedDate = lastModifiedDate;
+ this.authorities = authorities;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getLogin() {
+ return login;
+ }
+
+ public void setLogin(String login) {
+ this.login = login;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public String getImageUrl() {
+ return imageUrl;
+ }
+
+ public boolean isActivated() {
+ return activated;
+ }
+
+ public String getLangKey() {
+ return langKey;
+ }
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public ZonedDateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ public String getLastModifiedBy() {
+ return lastModifiedBy;
+ }
+
+ public ZonedDateTime getLastModifiedDate() {
+ return lastModifiedDate;
+ }
+
+ public void setLastModifiedDate(ZonedDateTime lastModifiedDate) {
+ this.lastModifiedDate = lastModifiedDate;
+ }
+
+ public Set getAuthorities() {
+ return authorities;
+ }
+
+ @Override
+ public String toString() {
+ return "UserDTO{" +
+ "login='" + login + '\'' +
+ ", firstName='" + firstName + '\'' +
+ ", lastName='" + lastName + '\'' +
+ ", email='" + email + '\'' +
+ ", imageUrl='" + imageUrl + '\'' +
+ ", activated=" + activated +
+ ", langKey='" + langKey + '\'' +
+ ", createdBy=" + createdBy +
+ ", createdDate=" + createdDate +
+ ", lastModifiedBy='" + lastModifiedBy + '\'' +
+ ", lastModifiedDate=" + lastModifiedDate +
+ ", authorities=" + authorities +
+ "}";
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/dto/package-info.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/dto/package-info.java
new file mode 100644
index 0000000000..e8c13430ca
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/dto/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Data Transfer Objects.
+ */
+package com.gateway.service.dto;
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/mapper/UserMapper.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/mapper/UserMapper.java
new file mode 100644
index 0000000000..d2bf0170c4
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/mapper/UserMapper.java
@@ -0,0 +1,55 @@
+package com.gateway.service.mapper;
+
+import com.gateway.domain.Authority;
+import com.gateway.domain.User;
+import com.gateway.service.dto.UserDTO;
+import org.mapstruct.*;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Mapper for the entity User and its DTO UserDTO.
+ */
+@Mapper(componentModel = "spring", uses = {})
+public interface UserMapper {
+
+ UserDTO userToUserDTO(User user);
+
+ List usersToUserDTOs(List users);
+
+ @Mapping(target = "createdBy", ignore = true)
+ @Mapping(target = "createdDate", ignore = true)
+ @Mapping(target = "lastModifiedBy", ignore = true)
+ @Mapping(target = "lastModifiedDate", ignore = true)
+ @Mapping(target = "activationKey", ignore = true)
+ @Mapping(target = "resetKey", ignore = true)
+ @Mapping(target = "resetDate", ignore = true)
+ @Mapping(target = "password", ignore = true)
+ User userDTOToUser(UserDTO userDTO);
+
+ List userDTOsToUsers(List userDTOs);
+
+ default User userFromId(Long id) {
+ if (id == null) {
+ return null;
+ }
+ User user = new User();
+ user.setId(id);
+ return user;
+ }
+
+ default Set stringsFromAuthorities (Set authorities) {
+ return authorities.stream().map(Authority::getName)
+ .collect(Collectors.toSet());
+ }
+
+ default Set authoritiesFromStrings(Set strings) {
+ return strings.stream().map(string -> {
+ Authority auth = new Authority();
+ auth.setName(string);
+ return auth;
+ }).collect(Collectors.toSet());
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/mapper/package-info.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/mapper/package-info.java
new file mode 100644
index 0000000000..7f1db9976c
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/mapper/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * MapStruct mappers for mapping domain objects and Data Transfer Objects.
+ */
+package com.gateway.service.mapper;
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/package-info.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/package-info.java
new file mode 100644
index 0000000000..05b7074c1b
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Service layer beans.
+ */
+package com.gateway.service;
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/util/RandomUtil.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/util/RandomUtil.java
new file mode 100644
index 0000000000..ec2db0f6b0
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/service/util/RandomUtil.java
@@ -0,0 +1,41 @@
+package com.gateway.service.util;
+
+import org.apache.commons.lang3.RandomStringUtils;
+
+/**
+ * Utility class for generating random Strings.
+ */
+public final class RandomUtil {
+
+ private static final int DEF_COUNT = 20;
+
+ private RandomUtil() {
+ }
+
+ /**
+ * Generate a password.
+ *
+ * @return the generated password
+ */
+ public static String generatePassword() {
+ return RandomStringUtils.randomAlphanumeric(DEF_COUNT);
+ }
+
+ /**
+ * Generate an activation key.
+ *
+ * @return the generated activation key
+ */
+ public static String generateActivationKey() {
+ return RandomStringUtils.randomNumeric(DEF_COUNT);
+ }
+
+ /**
+ * Generate a reset key.
+ *
+ * @return the generated reset key
+ */
+ public static String generateResetKey() {
+ return RandomStringUtils.randomNumeric(DEF_COUNT);
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/web/rest/AccountResource.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/web/rest/AccountResource.java
new file mode 100644
index 0000000000..1e71217a5d
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/web/rest/AccountResource.java
@@ -0,0 +1,202 @@
+package com.gateway.web.rest;
+
+import com.codahale.metrics.annotation.Timed;
+
+import com.gateway.domain.User;
+import com.gateway.repository.UserRepository;
+import com.gateway.security.SecurityUtils;
+import com.gateway.service.MailService;
+import com.gateway.service.UserService;
+import com.gateway.service.dto.UserDTO;
+import com.gateway.web.rest.vm.KeyAndPasswordVM;
+import com.gateway.web.rest.vm.ManagedUserVM;
+import com.gateway.web.rest.util.HeaderUtil;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import java.util.*;
+
+/**
+ * REST controller for managing the current user's account.
+ */
+@RestController
+@RequestMapping("/api")
+public class AccountResource {
+
+ private final Logger log = LoggerFactory.getLogger(AccountResource.class);
+
+ private final UserRepository userRepository;
+
+ private final UserService userService;
+
+ private final MailService mailService;
+
+ public AccountResource(UserRepository userRepository, UserService userService,
+ MailService mailService) {
+
+ this.userRepository = userRepository;
+ this.userService = userService;
+ this.mailService = mailService;
+ }
+
+ /**
+ * POST /register : register the user.
+ *
+ * @param managedUserVM the managed user View Model
+ * @return the ResponseEntity with status 201 (Created) if the user is registered or 400 (Bad Request) if the login or e-mail is already in use
+ */
+ @PostMapping(path = "/register",
+ produces={MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE})
+ @Timed
+ public ResponseEntity registerAccount(@Valid @RequestBody ManagedUserVM managedUserVM) {
+
+ HttpHeaders textPlainHeaders = new HttpHeaders();
+ textPlainHeaders.setContentType(MediaType.TEXT_PLAIN);
+
+ return userRepository.findOneByLogin(managedUserVM.getLogin().toLowerCase())
+ .map(user -> new ResponseEntity<>("login already in use", textPlainHeaders, HttpStatus.BAD_REQUEST))
+ .orElseGet(() -> userRepository.findOneByEmail(managedUserVM.getEmail())
+ .map(user -> new ResponseEntity<>("e-mail address already in use", textPlainHeaders, HttpStatus.BAD_REQUEST))
+ .orElseGet(() -> {
+ User user = userService
+ .createUser(managedUserVM.getLogin(), managedUserVM.getPassword(),
+ managedUserVM.getFirstName(), managedUserVM.getLastName(),
+ managedUserVM.getEmail().toLowerCase(), managedUserVM.getImageUrl(), managedUserVM.getLangKey());
+
+ mailService.sendActivationEmail(user);
+ return new ResponseEntity<>(HttpStatus.CREATED);
+ })
+ );
+ }
+
+ /**
+ * GET /activate : activate the registered user.
+ *
+ * @param key the activation key
+ * @return the ResponseEntity with status 200 (OK) and the activated user in body, or status 500 (Internal Server Error) if the user couldn't be activated
+ */
+ @GetMapping("/activate")
+ @Timed
+ public ResponseEntity activateAccount(@RequestParam(value = "key") String key) {
+ return userService.activateRegistration(key)
+ .map(user -> new ResponseEntity(HttpStatus.OK))
+ .orElse(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
+ }
+
+ /**
+ * GET /authenticate : check if the user is authenticated, and return its login.
+ *
+ * @param request the HTTP request
+ * @return the login if the user is authenticated
+ */
+ @GetMapping("/authenticate")
+ @Timed
+ public String isAuthenticated(HttpServletRequest request) {
+ log.debug("REST request to check if the current user is authenticated");
+ return request.getRemoteUser();
+ }
+
+ /**
+ * GET /account : get the current user.
+ *
+ * @return the ResponseEntity with status 200 (OK) and the current user in body, or status 500 (Internal Server Error) if the user couldn't be returned
+ */
+ @GetMapping("/account")
+ @Timed
+ public ResponseEntity getAccount() {
+ return Optional.ofNullable(userService.getUserWithAuthorities())
+ .map(user -> new ResponseEntity<>(new UserDTO(user), HttpStatus.OK))
+ .orElse(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
+ }
+
+ /**
+ * POST /account : update the current user information.
+ *
+ * @param userDTO the current user information
+ * @return the ResponseEntity with status 200 (OK), or status 400 (Bad Request) or 500 (Internal Server Error) if the user couldn't be updated
+ */
+ @PostMapping("/account")
+ @Timed
+ public ResponseEntity saveAccount(@Valid @RequestBody UserDTO userDTO) {
+ Optional existingUser = userRepository.findOneByEmail(userDTO.getEmail());
+ if (existingUser.isPresent() && (!existingUser.get().getLogin().equalsIgnoreCase(userDTO.getLogin()))) {
+ return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert("user-management", "emailexists", "Email already in use")).body(null);
+ }
+ return userRepository
+ .findOneByLogin(SecurityUtils.getCurrentUserLogin())
+ .map(u -> {
+ userService.updateUser(userDTO.getFirstName(), userDTO.getLastName(), userDTO.getEmail(),
+ userDTO.getLangKey());
+ return new ResponseEntity(HttpStatus.OK);
+ })
+ .orElseGet(() -> new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
+ }
+
+ /**
+ * POST /account/change_password : changes the current user's password
+ *
+ * @param password the new password
+ * @return the ResponseEntity with status 200 (OK), or status 400 (Bad Request) if the new password is not strong enough
+ */
+ @PostMapping(path = "/account/change_password",
+ produces = MediaType.TEXT_PLAIN_VALUE)
+ @Timed
+ public ResponseEntity changePassword(@RequestBody String password) {
+ if (!checkPasswordLength(password)) {
+ return new ResponseEntity<>("Incorrect password", HttpStatus.BAD_REQUEST);
+ }
+ userService.changePassword(password);
+ return new ResponseEntity<>(HttpStatus.OK);
+ }
+
+ /**
+ * POST /account/reset_password/init : Send an e-mail to reset the password of the user
+ *
+ * @param mail the mail of the user
+ * @return the ResponseEntity with status 200 (OK) if the e-mail was sent, or status 400 (Bad Request) if the e-mail address is not registered
+ */
+ @PostMapping(path = "/account/reset_password/init",
+ produces = MediaType.TEXT_PLAIN_VALUE)
+ @Timed
+ public ResponseEntity requestPasswordReset(@RequestBody String mail) {
+ return userService.requestPasswordReset(mail)
+ .map(user -> {
+ mailService.sendPasswordResetMail(user);
+ return new ResponseEntity<>("e-mail was sent", HttpStatus.OK);
+ }).orElse(new ResponseEntity<>("e-mail address not registered", HttpStatus.BAD_REQUEST));
+ }
+
+ /**
+ * POST /account/reset_password/finish : Finish to reset the password of the user
+ *
+ * @param keyAndPassword the generated key and the new password
+ * @return the ResponseEntity with status 200 (OK) if the password has been reset,
+ * or status 400 (Bad Request) or 500 (Internal Server Error) if the password could not be reset
+ */
+ @PostMapping(path = "/account/reset_password/finish",
+ produces = MediaType.TEXT_PLAIN_VALUE)
+ @Timed
+ public ResponseEntity finishPasswordReset(@RequestBody KeyAndPasswordVM keyAndPassword) {
+ if (!checkPasswordLength(keyAndPassword.getNewPassword())) {
+ return new ResponseEntity<>("Incorrect password", HttpStatus.BAD_REQUEST);
+ }
+ return userService.completePasswordReset(keyAndPassword.getNewPassword(), keyAndPassword.getKey())
+ .map(user -> new ResponseEntity(HttpStatus.OK))
+ .orElse(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
+ }
+
+ private boolean checkPasswordLength(String password) {
+ return !StringUtils.isEmpty(password) &&
+ password.length() >= ManagedUserVM.PASSWORD_MIN_LENGTH &&
+ password.length() <= ManagedUserVM.PASSWORD_MAX_LENGTH;
+ }
+}
diff --git a/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/web/rest/AuditResource.java b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/web/rest/AuditResource.java
new file mode 100644
index 0000000000..f61d1ebcb9
--- /dev/null
+++ b/jhipster/jhipster-microservice/gateway-app/src/main/java/com/gateway/web/rest/AuditResource.java
@@ -0,0 +1,76 @@
+package com.gateway.web.rest;
+
+import com.gateway.service.AuditEventService;
+import com.gateway.web.rest.util.PaginationUtil;
+
+import io.github.jhipster.web.util.ResponseUtil;
+import io.swagger.annotations.ApiParam;
+import org.springframework.boot.actuate.audit.AuditEvent;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.net.URISyntaxException;
+import java.time.LocalDate;
+import java.util.List;
+
+/**
+ * REST controller for getting the audit events.
+ */
+@RestController
+@RequestMapping("/management/audits")
+public class AuditResource {
+
+ private final AuditEventService auditEventService;
+
+ public AuditResource(AuditEventService auditEventService) {
+ this.auditEventService = auditEventService;
+ }
+
+ /**
+ * GET /audits : get a page of AuditEvents.
+ *
+ * @param pageable the pagination information
+ * @return the ResponseEntity with status 200 (OK) and the list of AuditEvents in body
+ */
+ @GetMapping
+ public ResponseEntity> getAll(@ApiParam Pageable pageable) {
+ Page page = auditEventService.findAll(pageable);
+ HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/management/audits");
+ return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
+ }
+
+ /**
+ * GET /audits : get a page of AuditEvents between the fromDate and toDate.
+ *
+ * @param fromDate the start of the time period of AuditEvents to get
+ * @param toDate the end of the time period of AuditEvents to get
+ * @param pageable the pagination information
+ * @return the ResponseEntity with status 200 (OK) and the list of AuditEvents in body
+ */
+
+ @GetMapping(params = {"fromDate", "toDate"})
+ public ResponseEntity> getByDates(
+ @RequestParam(value = "fromDate") LocalDate fromDate,
+ @RequestParam(value = "toDate") LocalDate toDate,
+ @ApiParam Pageable pageable) {
+
+ Page