Skip to content

Commit

Permalink
Merge pull request #6 from Muryginds/muryginds
Browse files Browse the repository at this point in the history
Muryginds
  • Loading branch information
Muryginds authored Feb 26, 2024
2 parents 5fa7b06 + 91e2cb8 commit e3895a2
Show file tree
Hide file tree
Showing 213 changed files with 3,931 additions and 4,974 deletions.
41 changes: 22 additions & 19 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
plugins {
id 'java'
id 'application'
id 'war'
id "io.freefair.aspectj.post-compile-weaving" version "8.4" apply false
}

group = 'ru.ylab'
Expand All @@ -18,7 +16,6 @@ repositories {
}

ext {
isTest = System.properties['env'] == 'test'
password4jVersion = '1.7.3'
mapstructVersion = '1.5.5.Final'
mapstructProcessorVersion = '1.5.5.Final'
Expand All @@ -36,13 +33,11 @@ ext {
jakartaServletApiVersion = '6.1.0-M1'
jacksonVersion = '2.16.1'
hibernameValidatorVersion = '8.0.1.Final'
aspectjrtVersion = '1.9.21'
}

apply {
if (!isTest) {
apply plugin: 'io.freefair.aspectj.post-compile-weaving'
}
springVersion = '6.1.4'
snakeYamlVersion = '2.2'
springdocVersion = '2.3.0'
springSecurityVersion = '6.2.1'
jwttVersion = '0.12.5'
}

dependencies {
Expand All @@ -57,7 +52,21 @@ dependencies {
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${jacksonVersion}"
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jacksonVersion}"
implementation "org.hibernate.validator:hibernate-validator:${hibernameValidatorVersion}"
implementation "org.aspectj:aspectjrt:${aspectjrtVersion}"
implementation "org.springframework:spring-aspects:${springVersion}"
implementation "org.springframework:spring-aop:${springVersion}"
implementation "org.springframework:spring-context:${springVersion}"
implementation "org.springframework:spring-web:${springVersion}"
implementation "org.springframework:spring-webmvc:${springVersion}"
implementation "org.springframework.security:spring-security-web:${springSecurityVersion}"
implementation "org.springframework.security:spring-security-config:${springSecurityVersion}"
implementation "org.springframework:spring-jdbc:${springVersion}"
implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:${springdocVersion}"
implementation "org.yaml:snakeyaml:${snakeYamlVersion}"
implementation "io.jsonwebtoken:jjwt-api:${jwttVersion}"
implementation 'com.jayway.jsonpath:json-path:2.9.0'

runtimeOnly "io.jsonwebtoken:jjwt-impl:${jwttVersion}"
runtimeOnly "io.jsonwebtoken:jjwt-jackson:${jwttVersion}"

compileOnly "org.projectlombok:lombok:${lombokVersion}"
compileOnly "jakarta.servlet:jakarta.servlet-api:${jakartaServletApiVersion}"
Expand All @@ -69,6 +78,8 @@ dependencies {
testImplementation platform("org.junit:junit-bom:${junitVersion}")
testImplementation "org.junit.jupiter:junit-jupiter"
testImplementation "org.mockito:mockito-core:${mockitoCoreVersion}"
testImplementation "org.mockito:mockito-junit-jupiter:${mockitoCoreVersion}"
testImplementation "org.springframework:spring-test:${springVersion}"
testImplementation "org.testcontainers:postgresql:${testContainersPostgresVersion}"
testImplementation "jakarta.servlet:jakarta.servlet-api:${jakartaServletApiVersion}"

Expand All @@ -79,14 +90,6 @@ dependencies {
testAnnotationProcessor "org.projectlombok:lombok-mapstruct-binding:${lombokMapstructBindingVersion}"
}

application {
mainClassName = 'ru.ylab.Application'
}

run {
standardInput = System.in
}

tasks.war {
archiveFileName.set("monitoring-service.war")
}
Expand Down
Binary file added img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 7 additions & 16 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,11 @@ specific users.
- <a href ="https://github.com/Muryginds/ylab-01.2024/pull/3"> sprint 1</a> Entities, in-memory collections, console interface, javadoc, service tests
- <a href ="https://github.com/Muryginds/ylab-01.2024/pull/4"> sprint 2</a> Docker + postgres, liquibase migrations, repository tests
- <a href ="https://github.com/Muryginds/ylab-01.2024/pull/5"> sprint 3</a> Servlets + tomcat, jackson, validations, aspects, logging
- <a href ="https://github.com/Muryginds/ylab-01.2024/pull/6"> sprint 4</a> Spring + controllers, jwt auth, rest template, open api + swagger

#### API
```
POST: /api/v1/auth/login - authorization with {UserAuthorizationRequestDTO}
POST: /api/v1/auth/logout - logout
POST: /api/v1/accounts/registration - registrate new user with {UserRegistrationRequestDTO}
GET: /api/v1/users/me - currentUser
GET: /api/v1/submissions/all - get all submissions with {AllSubmissionsRequestDTO}
GET: /api/v1/submissions - get submission with {SubmissionRequestDTO}
POST: /api/v1/submissions - add new submission with {NewReadingsSubmissionRequestDTO}
GET: /api/v1/events/all - get all audition events with {AuditionEventsRequestDTO}
POST: /api/v1/meter-types - add new meter type with {NewMeterTypeRequestDTO}
![img.png](img.png)
```

#### Testing
Expand All @@ -48,11 +36,14 @@ POST: /api/v1/meter-types - add new meter type with {NewMeterTypeRequestDTO}
#### On Unix-like systems:

```bash
./gradlew run -q --console=plain
./gradlew clean war
docker compose up -d
```
#### On Windows:

```bash
gradlew.bat run -q --console=plain
gradlew.bat clean war
docker compose up -d
```
The Gradle wrapper will download the specified Gradle distribution, compile and run your Java application.
You need to have docker installed
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ru.ylab.annotation;
package io.ylab.annotation;

import ru.ylab.enumerated.AuditionEventType;
import io.ylab.enumerated.AuditionEventType;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package ru.ylab.annotation;
package io.ylab.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
62 changes: 62 additions & 0 deletions src/main/java/io/ylab/aspect/AuditableAspect.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package io.ylab.aspect;

import io.ylab.annotation.Auditable;
import io.ylab.dto.response.UserDto;
import io.ylab.entity.AuditionEvent;
import io.ylab.service.AuditionEventService;
import io.ylab.service.UserService;
import io.ylab.utils.CurrentUserUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class AuditableAspect {
private final AuditionEventService auditionEventService;
private final UserService userService;

@Pointcut("execution(io.ylab.dto.response.UserDto io.ylab.service.AccountService.registerUser(..))" +
"|| execution(io.ylab.dto.response.UserDto io.ylab.service.LoginService.authorize(..))")
public void unauthorizedUserMethodPointcut() {
}

@Pointcut("@annotation(io.ylab.annotation.Auditable) && execution(* *(..))")
public void auditableMethod() {
}

@AfterReturning("auditableMethod() && !unauthorizedUserMethodPointcut()")
public void auditableMethodAdvice(JoinPoint joinPoint) {
var methodName = joinPoint.getSignature().getName();
log.info("AUDITING " + methodName);
var type = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(Auditable.class).eventType();
var user = CurrentUserUtils.getCurrentUser();
var event = AuditionEvent.builder()
.user(user)
.eventType(type)
.message("Method '%s' was called".formatted(methodName))
.build();
auditionEventService.save(event);
}

@AfterReturning(value = "auditableMethod() && unauthorizedUserMethodPointcut()", returning = "userDto")
public void auditableRegisterUserAdvice(JoinPoint joinPoint, UserDto userDto) {
var methodName = joinPoint.getSignature().getName();
log.info("AUDITING " + methodName);
var type = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(Auditable.class).eventType();
var user = userService.getUserById(userDto.getId());
var event = AuditionEvent.builder()
.user(user)
.eventType(type)
.message("Method '%s' was called".formatted(methodName))
.build();
auditionEventService.save(event);
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package ru.ylab.aspect;
package io.ylab.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Slf4j
@Aspect
@Component
public class LoggableAspect {
@Pointcut("@annotation(ru.ylab.annotation.Loggable) && execution(* *(..))")
@Pointcut("@annotation(io.ylab.annotation.Loggable) && execution(* *(..))")
public void loggableMethod() {
}

Expand Down
22 changes: 22 additions & 0 deletions src/main/java/io/ylab/configuration/ApplicationConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.ylab.configuration;

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;

import java.util.Objects;

@Configuration
public class ApplicationConfig {

@Bean
public static PropertySourcesPlaceholderConfigurer yamlPropertiesConfigurer() {
var configurer = new PropertySourcesPlaceholderConfigurer();
var factoryBean = new YamlPropertiesFactoryBean();
factoryBean.setResources(new ClassPathResource("application.yaml"));
configurer.setProperties(Objects.requireNonNull(factoryBean.getObject()));
return configurer;
}
}
48 changes: 48 additions & 0 deletions src/main/java/io/ylab/configuration/DatabaseConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.ylab.configuration;

import io.ylab.configuration.property.DataSourceProperties;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;

import javax.sql.DataSource;

@Configuration
@RequiredArgsConstructor
public class DatabaseConfig {
private final DataSourceProperties properties;

@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(properties.getUrl());
dataSource.setUsername(properties.getUsername());
dataSource.setPassword(properties.getPassword());
dataSource.setDriverClassName(properties.getDriverClassName());
return dataSource;
}

@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}

@Bean
public DataSourceInitializer dataSourceInitializer(DataSource dataSource) {
var initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(databasePopulator());
return initializer;
}

private ResourceDatabasePopulator databasePopulator() {
var populator = new ResourceDatabasePopulator();
populator.addScript(new ClassPathResource(properties.getInitScript()));
return populator;
}
}
26 changes: 26 additions & 0 deletions src/main/java/io/ylab/configuration/LiquibaseConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.ylab.configuration;

import io.ylab.configuration.property.MigrationProperties;
import liquibase.integration.spring.SpringLiquibase;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
@RequiredArgsConstructor
public class LiquibaseConfig {
private final MigrationProperties migrationProperties;
private final DataSource dataSource;

@Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog(migrationProperties.getChangeLog());
liquibase.setDefaultSchema(migrationProperties.getDefaultSchema());
liquibase.setLiquibaseSchema(migrationProperties.getLiquibaseSchema());
return liquibase;
}
}
22 changes: 22 additions & 0 deletions src/main/java/io/ylab/configuration/MainWebAppInitializer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.ylab.configuration;

import org.springframework.lang.NonNull;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MainWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected @NonNull String[] getServletMappings() {
return new String[]{"/"};
}

@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}

@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {SecurityConfig.class, WebConfig.class};
}
}
Loading

0 comments on commit e3895a2

Please sign in to comment.