Merge remote-tracking branch 'origin/master'

This commit is contained in:
slavisa-baeldung 2017-05-08 10:27:49 +01:00
commit aada5952c3
1879 changed files with 254617 additions and 120 deletions

View File

@ -2,19 +2,19 @@ package com.baeldung.java.reflection;
public class Operations {
public double sum(int a, double b) {
public double publicSum(int a, double b) {
return a + b;
}
public static double multiply(float a, long b) {
public static double publicStaticMultiply(float a, long b) {
return a * b;
}
private boolean and(boolean a, boolean b) {
private boolean privateAnd(boolean a, boolean b) {
return a && b;
}
protected int max(int a, int b) {
protected int protectedMax(int a, int b) {
return a > b ? a : b;
}

View File

@ -0,0 +1,41 @@
package com.baeldung.java.doublebrace;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toSet;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class DoubleBraceTest {
@Test
public void whenInitializeSetWithoutDoubleBraces_containsElements() {
final Set<String> countries = new HashSet<String>();
countries.add("India");
countries.add("USSR");
countries.add("USA");
assertTrue(countries.contains("India"));
}
@Test
public void whenInitializeSetWithDoubleBraces_containsElements() {
final Set<String> countries = new HashSet<String>() {
{
add("India");
add("USSR");
add("USA");
}
};
assertTrue(countries.contains("India"));
}
@Test
public void whenInitializeUnmodifiableSetWithDoubleBrace_containsElements() {
final Set<String> countries = Collections.unmodifiableSet(Stream.of("India", "USSR", "USA").collect(toSet()));
assertTrue(countries.contains("India"));
}
}

View File

@ -16,7 +16,7 @@ public class OperationsUnitTest {
@Test(expected = IllegalAccessException.class)
public void givenObject_whenInvokePrivateMethod_thenFail() throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method andPrivateMethod = Operations.class.getDeclaredMethod("and", boolean.class, boolean.class);
Method andPrivateMethod = Operations.class.getDeclaredMethod("privateAnd", boolean.class, boolean.class);
Operations operationsInstance = new Operations();
Boolean result = (Boolean) andPrivateMethod.invoke(operationsInstance, true, false);
@ -26,7 +26,7 @@ public class OperationsUnitTest {
@Test
public void givenObject_whenInvokePrivateMethod_thenCorrect() throws Exception {
Method andPrivatedMethod = Operations.class.getDeclaredMethod("and", boolean.class, boolean.class);
Method andPrivatedMethod = Operations.class.getDeclaredMethod("privateAnd", boolean.class, boolean.class);
andPrivatedMethod.setAccessible(true);
Operations operationsInstance = new Operations();
@ -37,7 +37,7 @@ public class OperationsUnitTest {
@Test
public void givenObject_whenInvokePublicMethod_thenCorrect() throws Exception {
Method sumInstanceMethod = Operations.class.getMethod("sum", int.class, double.class);
Method sumInstanceMethod = Operations.class.getMethod("publicSum", int.class, double.class);
Operations operationsInstance = new Operations();
Double result = (Double) sumInstanceMethod.invoke(operationsInstance, 1, 3);
@ -47,7 +47,7 @@ public class OperationsUnitTest {
@Test
public void givenObject_whenInvokeStaticMethod_thenCorrect() throws Exception {
Method multiplyStaticMethod = Operations.class.getDeclaredMethod("multiply", float.class, long.class);
Method multiplyStaticMethod = Operations.class.getDeclaredMethod("publicStaticMultiply", float.class, long.class);
Double result = (Double) multiplyStaticMethod.invoke(null, 3.5f, 2);

View File

@ -16,17 +16,17 @@ public class MoreOperationsUnitTest {
@Test(expected = IllegalAccessException.class)
public void givenObject_whenInvokeProtectedMethod_thenFail() throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method maxProtectedMethod = Operations.class.getDeclaredMethod("max", int.class, int.class);
Method maxProtectedMethod = Operations.class.getDeclaredMethod("protectedMax", int.class, int.class);
Operations operationsInstance = new Operations();
Integer result = (Integer) maxProtectedMethod.invoke(operationsInstance, 2, 4);
System.out.println("result = " + result);
assertThat(result, equalTo(4));
}
@Test
public void givenObject_whenInvokeProtectedMethod_thenCorrect() throws Exception {
Method maxProtectedMethod = Operations.class.getDeclaredMethod("max", int.class, int.class);
Method maxProtectedMethod = Operations.class.getDeclaredMethod("protectedMax", int.class, int.class);
maxProtectedMethod.setAccessible(true);
Operations operationsInstance = new Operations();

View File

@ -8,25 +8,25 @@ import static org.junit.Assert.*;
public class ClassToInstanceMapTests {
@Test
public void createEmptyImmutableMap() {
public void whenOfCalled_thenCreateEmptyImmutableMap() {
ClassToInstanceMap<Action> map = ImmutableClassToInstanceMap.of();
assertTrue(map.isEmpty());
}
@Test
public void createEmptyMutableMap() {
public void whenCreateCalled_thenCreateEmptyMutableMap() {
ClassToInstanceMap<Action> map = MutableClassToInstanceMap.create();
assertTrue(map.isEmpty());
}
@Test
public void createSingleEntryMap() {
public void whenOfWithParameterCalled_thenCreateSingleEntryMap() {
ClassToInstanceMap<Action> map = ImmutableClassToInstanceMap.of(Save.class, new Save());
assertEquals(1, map.size());
}
@Test
public void createMapWithBuilder() {
public void whenBuilderUser_thenCreateMap() {
ClassToInstanceMap<Action> map = ImmutableClassToInstanceMap.<Action>builder()
.put(Save.class, new Save())
.put(Open.class, new Open())
@ -35,7 +35,7 @@ public class ClassToInstanceMapTests {
}
@Test
public void shouldReturnElement() {
public void givenClassToInstanceMap_whenGetCalled_returnUpperBoundElement() {
ClassToInstanceMap<Action> map = ImmutableClassToInstanceMap.of(Save.class, new Save());
Action action = map.get(Save.class);
assertTrue(action instanceof Save);
@ -45,7 +45,7 @@ public class ClassToInstanceMapTests {
}
@Test
public void shouldPutElement() {
public void givenClassToInstanceMap_whenPutCalled_returnPreviousElementUpperBound() {
ClassToInstanceMap<Action> map = MutableClassToInstanceMap.create();
map.put(Save.class, new Save());
// Put again to get previous value returned

View File

@ -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

View File

@ -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
}

View File

@ -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"
}
}

View File

@ -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/

View File

@ -0,0 +1,5 @@
{
"devDependencies": {
"generator-jhipster": "4.0.8"
}
}

View File

@ -0,0 +1,928 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>1.5.2.RELEASE</version>
<relativePath />
</parent>
<groupId>com.car.app</groupId>
<artifactId>carapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Carapp</name>
<prerequisites>
<maven>${maven.version}</maven>
</prerequisites>
<properties>
<argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
<assertj.version>3.6.2</assertj.version>
<awaitility.version>2.0.0</awaitility.version>
<commons-io.version>2.5</commons-io.version>
<commons-lang.version>3.5</commons-lang.version>
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
<hazelcast-hibernate52.version>1.2</hazelcast-hibernate52.version>
<hibernate.version>5.2.8.Final</hibernate.version>
<hikaricp.version>2.6.0</hikaricp.version>
<jacoco-maven-plugin.version>0.7.9</jacoco-maven-plugin.version>
<java.version>1.8</java.version>
<javassist.version>3.21.0-GA</javassist.version>
<jcache.version>1.0.0</jcache.version>
<jhipster.server.version>1.1.0</jhipster.server.version>
<jjwt.version>0.7.0</jjwt.version>
<liquibase-hibernate5.version>3.6</liquibase-hibernate5.version>
<liquibase-slf4j.version>2.0.0</liquibase-slf4j.version>
<logstash-logback-encoder.version>4.8</logstash-logback-encoder.version>
<m2e.apt.activation>jdt_apt</m2e.apt.activation>
<mapstruct.version>1.1.0.Final</mapstruct.version>
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
<maven-enforcer-plugin.version>1.4.1</maven-enforcer-plugin.version>
<maven-resources-plugin.version>3.0.1</maven-resources-plugin.version>
<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.version>3.0.0</maven.version>
<metrics-spring.version>3.1.3</metrics-spring.version>
<node.version>v6.10.0</node.version>
<!-- These remain empty unless the corresponding profile is active -->
<profile.no-liquibase />
<profile.swagger />
<!-- Sonar properties -->
<project.testresult.directory>${project.build.directory}/test-results</project.testresult.directory>
<prometheus-simpleclient.version>0.0.20</prometheus-simpleclient.version>
<run.addResources>false</run.addResources>
<scala-maven-plugin.version>3.2.2</scala-maven-plugin.version>
<scala.version>2.12.1</scala.version>
<sonar-maven-plugin.version>3.2</sonar-maven-plugin.version>
<sonar.exclusions>src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.*</sonar.exclusions>
<sonar.issue.ignore.multicriteria>S3437,UndocumentedApi,BoldAndItalicTagsCheck</sonar.issue.ignore.multicriteria>
<!-- Rule https://sonarqube.com/coding_rules#rule_key=Web%3ABoldAndItalicTagsCheck is ignored. Even if we agree that using the "i" tag is an awful practice, this is what is recommended by http://fontawesome.io/examples/ -->
<sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.resourceKey>src/main/webapp/app/**/*.*</sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.resourceKey>
<sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.ruleKey>Web:BoldAndItalicTagsCheck</sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.ruleKey>
<!-- Rule https://sonarqube.com/coding_rules#rule_key=squid%3AS3437 is ignored, as a JPA-managed field cannot be transient -->
<sonar.issue.ignore.multicriteria.S3437.resourceKey>src/main/java/**/*</sonar.issue.ignore.multicriteria.S3437.resourceKey>
<sonar.issue.ignore.multicriteria.S3437.ruleKey>squid:S3437</sonar.issue.ignore.multicriteria.S3437.ruleKey>
<!-- Rule http://sonarqube.com/coding_rules#rule_key=squid%3AUndocumentedApi is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names should be self-explanatory -->
<sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey>src/main/java/**/*</sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey>
<sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey>squid:UndocumentedApi</sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey>
<sonar.jacoco.itReportPath>${project.testresult.directory}/coverage/jacoco/jacoco-it.exec</sonar.jacoco.itReportPath>
<sonar.jacoco.reportPath>${project.testresult.directory}/coverage/jacoco/jacoco.exec</sonar.jacoco.reportPath>
<sonar.java.codeCoveragePlugin>jacoco</sonar.java.codeCoveragePlugin>
<sonar.javascript.jstestdriver.reportsPath>${project.testresult.directory}/karma</sonar.javascript.jstestdriver.reportsPath>
<!-- For Sonar < 6.2 -->
<sonar.javascript.lcov.reportPath>${project.testresult.directory}/coverage/report-lcov/lcov.info</sonar.javascript.lcov.reportPath>
<!-- For Sonar >= 6.2 -->
<sonar.javascript.lcov.reportPaths>${project.testresult.directory}/coverage/report-lcov/lcov.info</sonar.javascript.lcov.reportPaths>
<sonar.sources>${project.basedir}/src/main/</sonar.sources>
<sonar.surefire.reportsPath>${project.testresult.directory}/surefire-reports</sonar.surefire.reportsPath>
<sonar.tests>${project.basedir}/src/test/</sonar.tests>
<sortpom-maven-plugin.version>2.5.0</sortpom-maven-plugin.version>
<!-- Spring properties -->
<spring-cloud.version>Camden.SR5</spring-cloud.version>
<springfox.version>2.6.1</springfox.version>
<undertow.version>1.4.10.Final</undertow.version>
<validation-api.version>1.1.0.Final</validation-api.version>
<yarn.version>v0.21.3</yarn.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hppc</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-json-org</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-hibernate52</artifactId>
<version>${hazelcast-hibernate52.version}</version>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-spring</artifactId>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
<!-- parent POM declares this dependency in default (compile) scope -->
</dependency>
<dependency>
<groupId>com.mattbertolini</groupId>
<artifactId>liquibase-slf4j</artifactId>
<version>${liquibase-slf4j.version}</version>
</dependency>
<dependency>
<groupId>com.ryantenney.metrics</groupId>
<artifactId>metrics-spring</artifactId>
<version>${metrics-spring.version}</version>
<exclusions>
<exclusion>
<artifactId>metrics-annotation</artifactId>
<groupId>com.codahale.metrics</groupId>
</exclusion>
<exclusion>
<artifactId>metrics-core</artifactId>
<groupId>com.codahale.metrics</groupId>
</exclusion>
<exclusion>
<artifactId>metrics-healthchecks</artifactId>
<groupId>com.codahale.metrics</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<exclusions>
<exclusion>
<artifactId>tools</artifactId>
<groupId>com.sun</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-annotation</artifactId>
<version>${dropwizard-metrics.version}</version>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-json</artifactId>
<version>${dropwizard-metrics.version}</version>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-jvm</artifactId>
<version>${dropwizard-metrics.version}</version>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-servlet</artifactId>
<version>${dropwizard-metrics.version}</version>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-servlets</artifactId>
</dependency>
<dependency>
<groupId>io.github.jhipster</groupId>
<artifactId>jhipster</artifactId>
<version>${jhipster.server.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>${springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox.version}</version>
<exclusions>
<exclusion>
<artifactId>mapstruct</artifactId>
<groupId>org.mapstruct</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>${logstash-logback-encoder.version}</version>
<exclusions>
<exclusion>
<artifactId>logback-core</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
<exclusion>
<artifactId>logback-access</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>${awaitility.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-envers</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<exclusions>
<exclusion>
<artifactId>jetty-servlet</artifactId>
<groupId>org.eclipse.jetty</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader-tools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cloud-connectors</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<!-- netty's native is pulled, but is useless unless you explicitly add the native binary dependency.
Having it in the classpath without the binary can cause warnings -->
<exclusions>
<exclusion>
<artifactId>netty-transport-native-epoll</artifactId>
<groupId>io.netty</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-spectator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<!-- security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-data</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!-- jhipster-needle-maven-add-dependency -->
</dependencies>
<build>
<defaultGoal>spring-boot:run</defaultGoal>
<pluginManagement>
<plugins>
<!--
This plugin's configuration is used to store Eclipse m2e settings only.
It has no influence on the Maven build itself.
Remove when the m2e plugin can correctly bind to Maven lifecycle
-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<versionRange>${jacoco-maven-plugin.version}</versionRange>
<goals>
<goal>prepare-agent</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>com.github.ekryd.sortpom</groupId>
<artifactId>sortpom-maven-plugin</artifactId>
<version>${sortpom-maven-plugin.version}</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>sort</goal>
</goals>
</execution>
</executions>
<configuration>
<sortProperties>true</sortProperties>
<nrOfIndentSpace>4</nrOfIndentSpace>
<sortDependencies>groupId,artifactId</sortDependencies>
<sortPlugins>groupId,artifactId</sortPlugins>
<keepBlankLines>true</keepBlankLines>
<expandEmptyElements>false</expandEmptyElements>
</configuration>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker-maven-plugin.version}</version>
<configuration>
<imageName>carapp</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.war</include>
</resource>
</resources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>${maven-enforcer-plugin.version}</version>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
<configuration>
<rules>
<requireMavenVersion>
<message>You are running an older version of Maven. JHipster requires at least Maven ${maven.version}</message>
<version>[${maven.version},)</version>
</requireMavenVersion>
<requireJavaVersion>
<message>You are running an older version of Java. JHipster requires at least JDK ${java.version}</message>
<version>[${java.version}.0,)</version>
</requireJavaVersion>
</rules>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
<executions>
<execution>
<id>default-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>target/classes</outputDirectory>
<useDefaultDelimiters>false</useDefaultDelimiters>
<delimiters>
<delimiter>#</delimiter>
</delimiters>
<resources>
<resource>
<directory>src/main/resources/</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
<include>**/*.yml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources/</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*.xml</exclude>
<exclude>**/*.yml</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Force alphabetical order to have a reproducible build -->
<runOrder>alphabetical</runOrder>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-maven-plugin.version}</version>
<executions>
<execution>
<id>pre-unit-tests</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<destFile>${project.testresult.directory}/coverage/jacoco/jacoco.exec</destFile>
</configuration>
</execution>
<!-- Ensures that the code coverage report for unit tests is created after unit tests have been run -->
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.testresult.directory}/coverage/jacoco/jacoco.exec</dataFile>
<outputDirectory>${project.testresult.directory}/coverage/jacoco</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>${liquibase.version}</version>
<dependencies>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>${validation-api.version}</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>${javassist.version}</version>
</dependency>
<dependency>
<groupId>org.liquibase.ext</groupId>
<artifactId>liquibase-hibernate5</artifactId>
<version>${liquibase-hibernate5.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
<configuration>
<changeLogFile>src/main/resources/config/liquibase/master.xml</changeLogFile>
<diffChangeLogFile>src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml</diffChangeLogFile>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:file:./target/h2db/db/carapp</url>
<defaultSchemaName />
<username>carapp</username>
<password />
<referenceUrl>hibernate:spring:com.car.app.domain?dialect=org.hibernate.dialect.H2Dialect&amp;hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&amp;hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy</referenceUrl>
<verbose>true</verbose>
<logging>debug</logging>
</configuration>
</plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>${sonar-maven-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
<fork>true</fork>
<!--
Enable the line below to have remote debugging of your application on port 5005
<jvmArguments>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005</jvmArguments>
-->
</configuration>
</plugin>
<!-- jhipster-needle-maven-add-plugin -->
</plugins>
</build>
<profiles>
<profile>
<id>no-liquibase</id>
<properties>
<profile.no-liquibase>,no-liquibase</profile.no-liquibase>
</properties>
</profile>
<profile>
<id>swagger</id>
<properties>
<profile.swagger>,swagger</profile.swagger>
</properties>
</profile>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration />
</plugin>
</plugins>
</build>
<properties>
<!-- log configuration -->
<logback.loglevel>DEBUG</logback.loglevel>
<!-- default Spring profiles -->
<spring.profiles.active>dev${profile.no-liquibase}</spring.profiles.active>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<id>prod</id>
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
<filesets>
<fileset>
<directory>target/www/</directory>
</fileset>
</filesets>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration />
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<!-- log configuration -->
<logback.loglevel>INFO</logback.loglevel>
<!-- default Spring profiles -->
<spring.profiles.active>prod${profile.swagger}${profile.no-liquibase}</spring.profiles.active>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<!--
Profile for doing "continuous compilation" with the Scala Maven plugin.
It allows automatic compilation of Java classes as soon as they are saved.
To use it, run in 3 terminals:
- './mvnw -Pcc scala:cc' for continous compilation of your classes
- './mvnw -Pcc' for hot reload of Spring boot
- 'gulp' for hot reload of the HTML/JavaScript assets
Everything should hot reload automatically!
-->
<id>cc</id>
<build>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>${scala-maven-plugin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>add-source</goal>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>add-source</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<recompileMode>incremental</recompileMode>
<verbose>true</verbose>
<scalaVersion>${scala.version}</scalaVersion>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceDirectory>src/main/webapp/</warSourceDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
<fork>true</fork>
<addResources>true</addResources>
<!--
Enable the line below to have remote debugging of your application on port 5005
<jvmArguments>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005</jvmArguments>
-->
</configuration>
</plugin>
</plugins>
</build>
<properties>
<!-- log configuration -->
<logback.loglevel>DEBUG</logback.loglevel>
<!-- default Spring profiles -->
<spring.profiles.active>dev,swagger</spring.profiles.active>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<!--
Profile for monitoring the application with Graphite.
-->
<id>graphite</id>
<dependencies>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-graphite</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<!--
Profile for monitoring the application with Prometheus.
-->
<id>prometheus</id>
<dependencies>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
<version>${prometheus-simpleclient.version}</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_dropwizard</artifactId>
<version>${prometheus-simpleclient.version}</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_servlet</artifactId>
<version>${prometheus-simpleclient.version}</version>
</dependency>
</dependencies>
</profile>
<profile>
<!--
Profile for applying IDE-specific configuration.
At the moment it only configures MapStruct, which you need when working
with DTOs.
-->
<id>IDE</id>
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View File

@ -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

View File

@ -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/

View File

@ -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

View File

@ -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/

View File

@ -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/

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,7 @@
version: '2'
services:
carapp-sonar:
image: sonarqube:6.2-alpine
ports:
- 9000:9000
- 9092:9092

View File

@ -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);
}
}

View File

@ -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.
* <p>
* Spring profiles can be configured with a program arguments --spring.profiles.active=your-active-profile
* <p>
* You can find more information on how profiles work with JHipster on <a href="http://jhipster.github.io/profiles/">http://jhipster.github.io/profiles/</a>.
*/
@PostConstruct
public void initApplication() {
Collection<String> 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);
}
}

View File

@ -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;
}
}
}

View File

@ -0,0 +1,15 @@
package com.car.app.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Properties specific to JHipster.
*
* <p>
* Properties are configured in the application.yml file.
* </p>
*/
@ConfigurationProperties(prefix = "application", ignoreUnknownFields = false)
public class ApplicationProperties {
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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() {
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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 <code>spring.profiles.active</code> set in the environment or as command line argument.
* If the value is not available in <code>application.yml</code> then <code>dev</code> 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<String, Object> defProperties = new HashMap<>();
/*
* The default profile to use when no other profiles are defined
* This cannot be set in the <code>application.yml</code> 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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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.
}
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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<DispatcherType> 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<DispatcherType> 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;
}
}

View File

@ -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<AuditEvent> convertToAuditEvent(Iterable<PersistentAuditEvent> persistentAuditEvents) {
if (persistentAuditEvents == null) {
return Collections.emptyList();
}
List<AuditEvent> 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<String, Object> convertDataToObjects(Map<String, String> data) {
Map<String, Object> results = new HashMap<>();
if (data != null) {
for (Map.Entry<String, String> 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<String, String> convertDataToStrings(Map<String, Object> data) {
Map<String, String> results = new HashMap<>();
if (data != null) {
for (Map.Entry<String, Object> 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;
}
}

View File

@ -0,0 +1,4 @@
/**
* Audit specific code.
*/
package com.car.app.config.audit;

View File

@ -0,0 +1,4 @@
/**
* Spring Framework configuration files.
*/
package com.car.app.config;

View File

@ -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;
}
}

View File

@ -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 + "'" +
'}';
}
}

View File

@ -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<String, String> 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<String, String> getData() {
return data;
}
public void setData(Map<String, String> data) {
this.data = data;
}
}

View File

@ -0,0 +1,4 @@
/**
* JPA domain objects.
*/
package com.car.app.domain;

View File

@ -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<Car,Long> {
}

View File

@ -0,0 +1,4 @@
/**
* Spring Data JPA repositories.
*/
package com.car.app.repository;

View File

@ -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() {
}
}

View File

@ -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).
*
* <p>The name of this method comes from the isUserInRole() method in the Servlet API</p>
*
* @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;
}
}

View File

@ -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<String> {
@Override
public String getCurrentAuditor() {
String userName = SecurityUtils.getCurrentUserLogin();
return userName != null ? userName : Constants.SYSTEM_ACCOUNT;
}
}

View File

@ -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<DefaultSecurityFilterChain, HttpSecurity> {
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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,4 @@
/**
* Service layer beans.
*/
package com.car.app.service;

View File

@ -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<Car> 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<Car> 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<List<Car>> getAllCars(@ApiParam Pageable pageable) {
log.debug("REST request to get a page of Cars");
Page<Car> 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<Car> 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<Void> 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();
}
}

View File

@ -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<LoggerVM> 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()));
}
}

View File

@ -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<String> ribbonProfiles = new ArrayList<>(Arrays.asList(displayOnActiveProfiles));
List<String> 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;
}
}
}

View File

@ -0,0 +1,34 @@
package com.car.app.web.rest.errors;
/**
* Custom, parameterized exception, which can be translated on the client side.
* For example:
*
* <pre>
* throw new CustomParameterizedException(&quot;myCustomError&quot;, &quot;hello&quot;, &quot;world&quot;);
* </pre>
*
* Can be translated with:
*
* <pre>
* "error.myCustomError" : "The server says {{params[0]}} to {{params[1]}}"
* </pre>
*/
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);
}
}

View File

@ -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() {
}
}

View File

@ -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<FieldErrorVM> 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<FieldErrorVM> 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<FieldErrorVM> getFieldErrors() {
return fieldErrors;
}
}

View File

@ -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<FieldError> 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<FieldError> 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<ErrorVM> 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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,4 @@
/**
* Spring MVC REST controllers.
*/
package com.car.app.web.rest;

View File

@ -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;
}
}

View File

@ -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.
*
* <p>
* Pagination uses the same principles as the <a href="https://developer.github.com/v3/#pagination">Github API</a>,
* and follow <a href="http://tools.ietf.org/html/rfc5988">RFC 5988 (Link header)</a>.
*/
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();
}
}

View File

@ -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 + '\'' +
'}';
}
}

View File

@ -0,0 +1,4 @@
/**
* View Models used by Spring MVC REST controllers.
*/
package com.car.app.web.rest.vm;

View File

@ -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

View File

@ -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: <your-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:

View File

@ -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: <your-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:

View File

@ -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:

View File

@ -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

View File

@ -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#

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<property name="now" value="now()" dbms="h2"/>
<property name="now" value="now()" dbms="mysql"/>
<property name="autoIncrement" value="true"/>
<!--
JHipster core tables.
The initial schema has the '00000000000001' id, so that it is over-written if we re-generate it.
-->
<changeSet id="00000000000001" author="jhipster">
<createTable tableName="jhi_persistent_audit_event">
<column name="event_id" type="bigint" autoIncrement="${autoIncrement}">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="principal" type="varchar(50)">
<constraints nullable="false" />
</column>
<column name="event_date" type="timestamp"/>
<column name="event_type" type="varchar(255)"/>
</createTable>
<createTable tableName="jhi_persistent_audit_evt_data">
<column name="event_id" type="bigint">
<constraints nullable="false"/>
</column>
<column name="name" type="varchar(150)">
<constraints nullable="false"/>
</column>
<column name="value" type="varchar(255)"/>
</createTable>
<addPrimaryKey columnNames="event_id, name" tableName="jhi_persistent_audit_evt_data"/>
<createIndex indexName="idx_persistent_audit_event"
tableName="jhi_persistent_audit_event"
unique="false">
<column name="principal" type="varchar(50)"/>
<column name="event_date" type="timestamp"/>
</createIndex>
<createIndex indexName="idx_persistent_audit_evt_data"
tableName="jhi_persistent_audit_evt_data"
unique="false">
<column name="event_id" type="bigint"/>
</createIndex>
<addForeignKeyConstraint baseColumnNames="event_id"
baseTableName="jhi_persistent_audit_evt_data"
constraintName="fk_evt_pers_audit_evt_data"
referencedColumnNames="event_id"
referencedTableName="jhi_persistent_audit_event"/>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<property name="now" value="now()" dbms="h2"/>
<property name="now" value="now()" dbms="mysql"/>
<property name="autoIncrement" value="true"/>
<property name="floatType" value="float4" dbms="postgresql, h2"/>
<property name="floatType" value="float" dbms="mysql, oracle, mssql"/>
<!--
Added the entity Car.
-->
<changeSet id="20170503041524-1" author="jhipster">
<createTable tableName="car">
<column name="id" type="bigint" autoIncrement="${autoIncrement}">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="make" type="varchar(255)">
<constraints nullable="true" />
</column>
<column name="brand" type="varchar(255)">
<constraints nullable="true" />
</column>
<column name="price" type="double">
<constraints nullable="true" />
</column>
<!-- jhipster-needle-liquibase-add-column - JHipster will add columns here, do not remove-->
</createTable>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd">
<include file="classpath:config/liquibase/changelog/00000000000000_initial_schema.xml" relativeToChangelogFile="false"/>
<include file="classpath:config/liquibase/changelog/20170503041524_added_entity_Car.xml" relativeToChangelogFile="false"/>
<!-- jhipster-needle-liquibase-add-changelog - JHipster will add liquibase changelogs here -->
<!-- jhipster-needle-liquibase-add-constraints-changelog - JHipster will add liquibase constraints changelogs here -->
</databaseChangeLog>

View File

@ -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,

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<!-- The FILE and ASYNC appenders are here as examples for a production configuration -->
<!--
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>90</maxHistory>
</rollingPolicy>
<encoder>
<charset>utf-8</charset>
<Pattern>%d %-5level [%thread] %logger{0}: %msg%n</Pattern>
</encoder>
</appender>
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>512</queueSize>
<appender-ref ref="FILE"/>
</appender>
-->
<logger name="com.car.app" level="#logback.loglevel#"/>
<logger name="io.github.jhipster" level="DEBUG"/>
<logger name="javax.activation" level="WARN"/>
<logger name="javax.mail" level="WARN"/>
<logger name="javax.xml.bind" level="WARN"/>
<logger name="ch.qos.logback" level="WARN"/>
<logger name="com.codahale.metrics" level="WARN"/>
<logger name="com.netflix" level="WARN"/>
<logger name="com.netflix.discovery" level="INFO"/>
<logger name="com.ryantenney" level="WARN"/>
<logger name="com.sun" level="WARN"/>
<logger name="com.zaxxer" level="WARN"/>
<logger name="io.undertow" level="WARN"/>
<logger name="io.undertow.websockets.jsr" level="ERROR"/>
<logger name="org.apache" level="WARN"/>
<logger name="org.apache.catalina.startup.DigesterFactory" level="OFF"/>
<logger name="org.bson" level="WARN"/>
<logger name="org.hibernate.validator" level="WARN"/>
<logger name="org.hibernate" level="WARN"/>
<logger name="org.hibernate.ejb.HibernatePersistence" level="OFF"/>
<logger name="org.springframework" level="WARN"/>
<logger name="org.springframework.web" level="WARN"/>
<logger name="org.springframework.security" level="WARN"/>
<logger name="org.springframework.cache" level="WARN"/>
<logger name="org.thymeleaf" level="WARN"/>
<logger name="org.xnio" level="WARN"/>
<logger name="springfox" level="WARN"/>
<logger name="sun.rmi" level="WARN"/>
<logger name="liquibase" level="WARN"/>
<logger name="LiquibaseSchemaResolver" level="INFO"/>
<logger name="sun.net.www" level="INFO"/>
<logger name="sun.rmi.transport" level="WARN"/>
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
<root level="#logback.loglevel#">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>

View File

@ -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 CarResourceIntTest {
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<Car> 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<Car> 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<Car> 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<Car> 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<Car> carList = carRepository.findAll();
assertThat(carList).hasSize(databaseSizeBeforeDelete - 1);
}
@Test
@Transactional
public void equalsVerifier() throws Exception {
TestUtil.equalsVerifier(Car.class);
}
}

View File

@ -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<String> {
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());
}
}

View File

@ -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:

View File

@ -0,0 +1,4 @@
spring:
cloud:
config:
enabled: false

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<logger name="com.car.app" level="DEBUG"/>
<logger name="org.hibernate" level="WARN"/>
<logger name="org.hibernate.ejb.HibernatePersistence" level="OFF"/>
<logger name="org.apache.catalina.startup.DigesterFactory" level="OFF"/>
<root level="WARN">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -0,0 +1 @@
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip

View File

@ -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"
}
}

View File

@ -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/

Some files were not shown because too many files have changed in this diff Show More