-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #70 from EMResearch/sut-mongo
reservation API
- Loading branch information
Showing
121 changed files
with
7,020 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
|
||
allprojects { | ||
ext { | ||
EVOMASTER_VERSION = "1.6.2-SNAPSHOT" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
web: java -Dserver.port=$PORT $JAVA_OPTS -jar build/libs/reservations-api.jar |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Reservations API | ||
|
||
Simple API built with SpringBoot and MongoDB database. | ||
|
||
## Documentation | ||
|
||
Documentation can be found [here](https://cg-reservations-api.herokuapp.com/documentation) | ||
|
||
## How to run | ||
|
||
### Application | ||
|
||
1. Clone the repository by executing commands: | ||
|
||
``` | ||
cd <yourRepoDirectory> | ||
git clone https://github.com/cyrilgavala/reservations-api.git . | ||
``` | ||
|
||
2. Open the project with your preferable IDE. | ||
If you use IntelliJ IDEA, it will offer you a **SpringBoot** runner configuration. | ||
3. Update the runner by adding environment variable ```DATABASE_URL``` containing | ||
URL to your MongoDB database and ```JWT_SECRET``` with 512-bit secret. | ||
4. Run the runner configuration. | ||
|
||
### Tests | ||
|
||
1. To run tests you need to pass step 2. from previous instructions and run command: | ||
|
||
```./gradlew test``` | ||
|
||
It will also execute ```jacocoTestReport``` gradle task, which will generate | ||
test report on path ```reservation-api/build/reports/jacoco/test/html/index.html```. | ||
2. To run whether you pass 95% test coverage check, simply run command: | ||
|
||
```./gradlew jacocoTestCoverageVerification``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
plugins { | ||
id 'org.springframework.boot' version '2.7.0' | ||
id 'io.spring.dependency-management' version '1.0.11.RELEASE' | ||
id 'java' | ||
id 'jacoco' | ||
} | ||
|
||
group = 'sk.cyrilgavala' | ||
sourceCompatibility = '11' | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
/* Annotation processors */ | ||
annotationProcessor group: 'org.projectlombok', name: 'lombok-mapstruct-binding', version: '0.1.0' | ||
annotationProcessor group: 'org.mapstruct', name: 'mapstruct-processor', version: mapStructVersion | ||
annotationProcessor group: 'org.projectlombok', name: 'lombok', version: lombokVersion | ||
|
||
/* Implementation dependencies */ | ||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-mongodb', version: springBootVersion | ||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion | ||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation', version: springBootVersion | ||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: springBootVersion | ||
implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: jjwtVersion | ||
implementation group: 'io.jsonwebtoken', name: 'jjwt-impl', version: jjwtVersion | ||
implementation group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: jjwtVersion | ||
implementation group: 'org.mapstruct', name: 'mapstruct', version: mapStructVersion | ||
implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.2' | ||
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.8' | ||
|
||
/* Compile only dependencies */ | ||
compileOnly group: 'org.projectlombok', name: 'lombok', version: lombokVersion | ||
|
||
/* Test annotation processors */ | ||
testAnnotationProcessor group: 'org.projectlombok', name: 'lombok', version: lombokVersion | ||
testAnnotationProcessor group: 'org.mapstruct', name: 'mapstruct-processor', version: mapStructVersion | ||
|
||
/* Test implementation dependencies */ | ||
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion | ||
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion | ||
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: springBootVersion | ||
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-mongodb', version: springBootVersion | ||
testImplementation group: 'org.springframework.security', name: 'spring-security-test', version: springSecurityVersion | ||
|
||
/* Test compile only dependencies */ | ||
testCompileOnly group: 'org.projectlombok', name: 'lombok', version: lombokVersion | ||
|
||
} | ||
|
||
def jacocoExcludePackages = ["**/reservationsApi/ReservationsApi.class", | ||
"**/reservationsApi/config/**", | ||
"**/reservationsApi/exception/*", | ||
"**/reservationsApi/model/*", | ||
"**/reservationsApi/security/*", | ||
"**/reservationsApi/web/advise/*", | ||
"**/reservationsApi/web/interceptor/*", | ||
"**/reservationsApi/web/request/*", | ||
"**/reservationsApi/web/response/*"] | ||
|
||
test { | ||
useJUnitPlatform() | ||
finalizedBy jacocoTestReport | ||
} | ||
|
||
jacoco { | ||
toolVersion "0.8.8" | ||
} | ||
|
||
jacocoTestReport { | ||
dependsOn test | ||
reports { | ||
xml.required = false | ||
csv.required = false | ||
} | ||
afterEvaluate { | ||
classDirectories.setFrom(files(classDirectories.files.collect { | ||
fileTree(dir: it, exclude: jacocoExcludePackages) | ||
})) | ||
} | ||
} | ||
|
||
jacocoTestCoverageVerification { | ||
violationRules { | ||
rule { | ||
limit { | ||
minimum = 0.95 | ||
} | ||
} | ||
} | ||
afterEvaluate { | ||
classDirectories.setFrom(files(classDirectories.files.collect { | ||
fileTree(dir: it, exclude: jacocoExcludePackages) | ||
})) | ||
} | ||
} | ||
|
||
check.dependsOn jacocoTestCoverageVerification | ||
|
||
|
||
tasks.named("bootJar") { | ||
archiveClassifier = 'sut' | ||
} | ||
|
||
tasks.named("jar") { | ||
archiveClassifier = 'plain' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
springBootVersion=2.7.0 | ||
springSecurityVersion=5.6.3 | ||
lombokVersion=1.18.24 | ||
mapStructVersion=1.4.2.Final | ||
swaggerVersion=3.0.0 | ||
jjwtVersion=0.11.5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
rootProject.name = 'reservations-api' |
28 changes: 28 additions & 0 deletions
28
...s/rest/reservations-api/src/main/java/sk/cyrilgavala/reservationsApi/ReservationsApi.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package sk.cyrilgavala.reservationsApi; | ||
|
||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.context.annotation.ComponentScan; | ||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; | ||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | ||
import org.springframework.transaction.annotation.EnableTransactionManagement; | ||
|
||
import java.util.TimeZone; | ||
|
||
@SpringBootApplication | ||
@EnableWebSecurity | ||
@EnableMongoRepositories(basePackages = "sk.cyrilgavala.reservationsApi.repository") | ||
@EnableTransactionManagement | ||
@ComponentScan({"sk.cyrilgavala.reservationsApi.config", | ||
"sk.cyrilgavala.reservationsApi.mapper", | ||
"sk.cyrilgavala.reservationsApi.security", | ||
"sk.cyrilgavala.reservationsApi.service", | ||
"sk.cyrilgavala.reservationsApi.web"}) | ||
public class ReservationsApi { | ||
|
||
public static void main(String[] args) { | ||
TimeZone.setDefault(TimeZone.getTimeZone("UTC")); | ||
SpringApplication.run(ReservationsApi.class, args); | ||
} | ||
|
||
} |
39 changes: 39 additions & 0 deletions
39
...ations-api/src/main/java/sk/cyrilgavala/reservationsApi/config/DatabaseConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package sk.cyrilgavala.reservationsApi.config; | ||
|
||
import com.mongodb.ConnectionString; | ||
import com.mongodb.MongoClientSettings; | ||
import com.mongodb.client.MongoClient; | ||
import com.mongodb.client.MongoClients; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.data.mongodb.MongoDatabaseFactory; | ||
import org.springframework.data.mongodb.MongoTransactionManager; | ||
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration; | ||
|
||
@Configuration | ||
public class DatabaseConfiguration extends AbstractMongoClientConfiguration { | ||
|
||
@Value("${databaseUrl}") | ||
private String databaseUrl; | ||
|
||
@Bean | ||
MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) { | ||
return new MongoTransactionManager(dbFactory); | ||
} | ||
|
||
@Override | ||
protected String getDatabaseName() { | ||
return "reservations-api"; | ||
} | ||
|
||
@Override | ||
public MongoClient mongoClient() { | ||
ConnectionString connectionString = new ConnectionString(databaseUrl); | ||
MongoClientSettings mongoClientSettings = MongoClientSettings.builder() | ||
.applyConnectionString(connectionString) | ||
.build(); | ||
return MongoClients.create(mongoClientSettings); | ||
} | ||
|
||
} |
23 changes: 23 additions & 0 deletions
23
...vations-api/src/main/java/sk/cyrilgavala/reservationsApi/config/OpenApiConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package sk.cyrilgavala.reservationsApi.config; | ||
|
||
import io.swagger.v3.oas.models.Components; | ||
import io.swagger.v3.oas.models.OpenAPI; | ||
import io.swagger.v3.oas.models.info.Info; | ||
import io.swagger.v3.oas.models.security.SecurityScheme; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Configuration | ||
public class OpenApiConfiguration { | ||
|
||
@Bean | ||
public OpenAPI springShopOpenAPI() { | ||
return new OpenAPI() | ||
.components( | ||
new Components().addSecuritySchemes("bearer-key", | ||
new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT"))) | ||
.info(new Info().title("Reservations API") | ||
.description("Simple API for implementing basic reservation system.") | ||
.version("v1.0.0")); | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
...ations-api/src/main/java/sk/cyrilgavala/reservationsApi/config/SecurityConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package sk.cyrilgavala.reservationsApi.config; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.http.HttpMethod; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; | ||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
import org.springframework.security.config.http.SessionCreationPolicy; | ||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
import org.springframework.security.crypto.password.PasswordEncoder; | ||
import org.springframework.security.web.SecurityFilterChain; | ||
import org.springframework.security.web.authentication.HttpStatusEntryPoint; | ||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
import sk.cyrilgavala.reservationsApi.security.TokenAuthenticationFilter; | ||
|
||
@RequiredArgsConstructor | ||
@Configuration | ||
public class SecurityConfiguration { | ||
|
||
public static final String ADMIN = "ADMIN"; | ||
public static final String USER = "USER"; | ||
private final TokenAuthenticationFilter tokenAuthenticationFilter; | ||
|
||
@Bean | ||
AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { | ||
return authenticationConfiguration.getAuthenticationManager(); | ||
} | ||
|
||
@Bean | ||
public PasswordEncoder passwordEncoder() { | ||
return new BCryptPasswordEncoder(10); | ||
} | ||
|
||
@Bean | ||
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { | ||
http.authorizeRequests() | ||
.antMatchers(HttpMethod.GET, "/api/reservation/**").hasAnyAuthority(ADMIN, USER) | ||
.antMatchers(HttpMethod.POST, "/api/reservation").hasAnyAuthority(ADMIN, USER) | ||
.antMatchers(HttpMethod.PUT, "/api/reservation").hasAnyAuthority(ADMIN, USER) | ||
.antMatchers(HttpMethod.DELETE, "/api/reservation/**").hasAnyAuthority(ADMIN, USER) | ||
.antMatchers(HttpMethod.GET, "/api/reservation").hasAuthority(ADMIN) | ||
.antMatchers("/api/user/**").permitAll() | ||
.antMatchers("/", "/error", "/documentation", "/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs", "/v3/api-docs/**").permitAll() | ||
.anyRequest().authenticated(); | ||
http.addFilterBefore(tokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); | ||
http.exceptionHandling(e -> e.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))); | ||
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); | ||
http.cors().and().csrf().disable(); | ||
return http.build(); | ||
} | ||
|
||
} |
31 changes: 31 additions & 0 deletions
31
...eservations-api/src/main/java/sk/cyrilgavala/reservationsApi/config/WebConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package sk.cyrilgavala.reservationsApi.config; | ||
|
||
import com.fasterxml.jackson.databind.SerializationFeature; | ||
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; | ||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.http.converter.HttpMessageConverter; | ||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; | ||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; | ||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||
|
||
import java.util.List; | ||
import java.util.TimeZone; | ||
|
||
@Configuration | ||
public class WebConfiguration implements WebMvcConfigurer { | ||
|
||
@Override | ||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { | ||
WebMvcConfigurer.super.configureMessageConverters(converters); | ||
|
||
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); | ||
builder.modules(new JavaTimeModule(), new Jdk8Module()); | ||
builder.timeZone(TimeZone.getTimeZone("UTC")); | ||
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); | ||
|
||
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); | ||
converter.setObjectMapper(builder.build()); | ||
} | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
...ns-api/src/main/java/sk/cyrilgavala/reservationsApi/exception/DuplicateUserException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package sk.cyrilgavala.reservationsApi.exception; | ||
|
||
public class DuplicateUserException extends RuntimeException { | ||
|
||
private static final long serialVersionUID = 9197342664218222132L; | ||
|
||
public DuplicateUserException(String message) { | ||
super(message); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
...ions-api/src/main/java/sk/cyrilgavala/reservationsApi/exception/ReservationException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package sk.cyrilgavala.reservationsApi.exception; | ||
|
||
public class ReservationException extends RuntimeException { | ||
|
||
private static final long serialVersionUID = 4033799885256608552L; | ||
|
||
public ReservationException(String message) { | ||
super(message); | ||
} | ||
} |
Oops, something went wrong.