diff --git a/api-gateway/Dockerfile b/api-gateway/Dockerfile new file mode 100644 index 0000000..3b78cf0 --- /dev/null +++ b/api-gateway/Dockerfile @@ -0,0 +1,6 @@ +FROM eclipse-temurin:21-jdk-alpine +LABEL authors="iakovlysenko" +VOLUME /tmp +ARG JAR_FILE=target/api-gateway-1.0-SNAPSHOT.jar +COPY ${JAR_FILE} app.jar +ENTRYPOINT ["java","-jar","/app.jar"] \ No newline at end of file diff --git a/api-gateway/pom.xml b/api-gateway/pom.xml new file mode 100644 index 0000000..ef025ff --- /dev/null +++ b/api-gateway/pom.xml @@ -0,0 +1,79 @@ + + + 4.0.0 + + ru.project.iakov + api-gateway + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 3.2.5 + + + + + 21 + 2023.0.1 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.2.5 + + + + repackage + + + + + + + maven-compiler-plugin + 3.11.0 + + 21 + 21 + + + org.projectlombok + lombok + 1.18.38 + + + + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + \ No newline at end of file diff --git a/api-gateway/src/main/java/ru/project/iakov/apigateway/ApiGatewayApplication.java b/api-gateway/src/main/java/ru/project/iakov/apigateway/ApiGatewayApplication.java new file mode 100644 index 0000000..29f365a --- /dev/null +++ b/api-gateway/src/main/java/ru/project/iakov/apigateway/ApiGatewayApplication.java @@ -0,0 +1,11 @@ +package ru.project.iakov.apigateway; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ApiGatewayApplication { + public static void main(String[] args) { + SpringApplication.run(ApiGatewayApplication.class, args); + } +} diff --git a/api-gateway/src/main/resources/application-docker.yml b/api-gateway/src/main/resources/application-docker.yml new file mode 100644 index 0000000..f038d5a --- /dev/null +++ b/api-gateway/src/main/resources/application-docker.yml @@ -0,0 +1,23 @@ +server: + port: 8080 + +spring: + application: + name: api-gateway + cloud: + gateway: + routes: + - id: user-service + uri: lb://user-service + predicates: + - Path=/users/** + - id: notification-service + uri: lb://notification-service + predicates: + - Path=/api/v1/email/** + config: + import: optional:configserver:http://config-server:8888 +eureka: + client: + service-url: + defaultZone: http://discovery-server:8761/eureka \ No newline at end of file diff --git a/api-gateway/src/main/resources/application.yml b/api-gateway/src/main/resources/application.yml new file mode 100644 index 0000000..bb2fe75 --- /dev/null +++ b/api-gateway/src/main/resources/application.yml @@ -0,0 +1,23 @@ +server: + port: 8082 +spring: + application: + name: api-gateway + cloud: + gateway: + routes: + - id: user-service + uri: lb://user-service + predicates: + - Path=/users/** + - id: notification-service + uri: lb://notification-service + predicates: + - Path=/api/v1/email/** + config: + import: optional:configserver:http://localhost:8888 + +eureka: + client: + service-url: + defaultZone: http://localhost:8761/eureka \ No newline at end of file diff --git a/api-gateway/target/classes/application.yml b/api-gateway/target/classes/application.yml new file mode 100644 index 0000000..bb2fe75 --- /dev/null +++ b/api-gateway/target/classes/application.yml @@ -0,0 +1,23 @@ +server: + port: 8082 +spring: + application: + name: api-gateway + cloud: + gateway: + routes: + - id: user-service + uri: lb://user-service + predicates: + - Path=/users/** + - id: notification-service + uri: lb://notification-service + predicates: + - Path=/api/v1/email/** + config: + import: optional:configserver:http://localhost:8888 + +eureka: + client: + service-url: + defaultZone: http://localhost:8761/eureka \ No newline at end of file diff --git a/api-gateway/target/classes/ru/project/iakov/apigateway/ApiGatewayApplication.class b/api-gateway/target/classes/ru/project/iakov/apigateway/ApiGatewayApplication.class new file mode 100644 index 0000000..64e4729 Binary files /dev/null and b/api-gateway/target/classes/ru/project/iakov/apigateway/ApiGatewayApplication.class differ diff --git a/config-repo/application.yml b/config-repo/application.yml new file mode 100644 index 0000000..8756ed0 --- /dev/null +++ b/config-repo/application.yml @@ -0,0 +1,10 @@ +eureka: + client: + register-with-eureka: true + fetch-registry: true + service-url: + defaultZone: http://discovery-server:8761/eureka/ + +spring: + application: + name: default \ No newline at end of file diff --git a/config-repo/config-server.yml b/config-repo/config-server.yml new file mode 100644 index 0000000..1bba46d --- /dev/null +++ b/config-repo/config-server.yml @@ -0,0 +1,6 @@ +server: + port: 8888 + +spring: + application: + name: config-server \ No newline at end of file diff --git a/config-repo/notification-service.yml b/config-repo/notification-service.yml new file mode 100644 index 0000000..faf13b1 --- /dev/null +++ b/config-repo/notification-service.yml @@ -0,0 +1,20 @@ +server: + port: 8082 + +spring: + application: + name: notification-service + mail: + host: smtp.mail.ru + port: 465 + username: ${EMAIL_USERNAME} + password: ${EMAIL_PASSWORD} + properties: + mail: + smtp: + auth: true + starttls: + enable: true + +kafka: + topic: user-events \ No newline at end of file diff --git a/config-repo/user-service.yml b/config-repo/user-service.yml new file mode 100644 index 0000000..ca8ba01 --- /dev/null +++ b/config-repo/user-service.yml @@ -0,0 +1,17 @@ +server: + port: 8081 + +spring: + application: + name: user-service + datasource: + url: jdbc:postgresql://postgres:5432/postgres + username: postgres + password: postgres + jpa: + hibernate: + ddl-auto: update + show-sql: true + properties: + hibernate: + format_sql: true \ No newline at end of file diff --git a/config-server/Dockerfile b/config-server/Dockerfile new file mode 100644 index 0000000..a2e8c68 --- /dev/null +++ b/config-server/Dockerfile @@ -0,0 +1,6 @@ +FROM eclipse-temurin:21-jdk-alpine +LABEL authors="iakovlysenko" +VOLUME /tmp +ARG JAR_FILE=target/config-server-1.0-SNAPSHOT.jar +COPY ${JAR_FILE} app.jar +ENTRYPOINT ["java","-jar","/app.jar"] \ No newline at end of file diff --git a/config-server/pom.xml b/config-server/pom.xml new file mode 100644 index 0000000..d777305 --- /dev/null +++ b/config-server/pom.xml @@ -0,0 +1,79 @@ + + + 4.0.0 + + ru.project.iakov + config-server + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 3.2.5 + + + + + 21 + 2023.0.1 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.2.5 + + + + repackage + + + + + + + maven-compiler-plugin + 3.11.0 + + 21 + 21 + + + org.projectlombok + lombok + 1.18.38 + + + + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + org.springframework.cloud + spring-cloud-config-server + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + \ No newline at end of file diff --git a/config-server/src/main/java/ru/project/iakov/configserver/ConfigServerApplication.java b/config-server/src/main/java/ru/project/iakov/configserver/ConfigServerApplication.java new file mode 100644 index 0000000..e93fcc0 --- /dev/null +++ b/config-server/src/main/java/ru/project/iakov/configserver/ConfigServerApplication.java @@ -0,0 +1,13 @@ +package ru.project.iakov.configserver; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; + +@SpringBootApplication +@EnableConfigServer +public class ConfigServerApplication { + public static void main(String[] args) { + SpringApplication.run(ConfigServerApplication.class, args); + } +} \ No newline at end of file diff --git a/config-server/src/main/resources/application-docker.yml b/config-server/src/main/resources/application-docker.yml new file mode 100644 index 0000000..d7768f3 --- /dev/null +++ b/config-server/src/main/resources/application-docker.yml @@ -0,0 +1,15 @@ +server: + port: 8888 + +spring: + cloud: + config: + server: + native: + search-locations: file:/config + + +eureka: + client: + service-url: + defaultZone: http://discovery-server:8761/eureka/ \ No newline at end of file diff --git a/config-server/src/main/resources/application.yml b/config-server/src/main/resources/application.yml new file mode 100644 index 0000000..6020c3a --- /dev/null +++ b/config-server/src/main/resources/application.yml @@ -0,0 +1,14 @@ +server: + port: 8888 +spring: + application: + name: config-server + cloud: + config: + server: + git: + uri: file:/config +eureka: + client: + service-url: + defaultZone: http://localhost:8761/eureka \ No newline at end of file diff --git a/config-server/target/classes/application.yml b/config-server/target/classes/application.yml new file mode 100644 index 0000000..6020c3a --- /dev/null +++ b/config-server/target/classes/application.yml @@ -0,0 +1,14 @@ +server: + port: 8888 +spring: + application: + name: config-server + cloud: + config: + server: + git: + uri: file:/config +eureka: + client: + service-url: + defaultZone: http://localhost:8761/eureka \ No newline at end of file diff --git a/config-server/target/classes/ru/project/iakov/configserver/ConfigServerApplication.class b/config-server/target/classes/ru/project/iakov/configserver/ConfigServerApplication.class new file mode 100644 index 0000000..8ab5ee1 Binary files /dev/null and b/config-server/target/classes/ru/project/iakov/configserver/ConfigServerApplication.class differ diff --git a/discovery-server/Dockerfile b/discovery-server/Dockerfile new file mode 100644 index 0000000..3d01bf0 --- /dev/null +++ b/discovery-server/Dockerfile @@ -0,0 +1,6 @@ +FROM eclipse-temurin:21-jdk-alpine +LABEL authors="iakovlysenko" +VOLUME /tmp +ARG JAR_FILE=target/discovery-server-1.0-SNAPSHOT.jar +COPY ${JAR_FILE} app.jar +ENTRYPOINT ["java","-jar","/app.jar"] \ No newline at end of file diff --git a/discovery-server/pom.xml b/discovery-server/pom.xml new file mode 100644 index 0000000..e6f040c --- /dev/null +++ b/discovery-server/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + + ru.project.iakov + discovery-server + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 3.2.5 + + + + + 21 + 2023.0.1 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.2.5 + + + + repackage + + + + + + + maven-compiler-plugin + 3.11.0 + + 21 + 21 + + + org.projectlombok + lombok + 1.18.38 + + + + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-server + + + \ No newline at end of file diff --git a/discovery-server/src/main/java/ru/project/iakov/discoveryserver/DiscoveryServerApplication.java b/discovery-server/src/main/java/ru/project/iakov/discoveryserver/DiscoveryServerApplication.java new file mode 100644 index 0000000..dd7c274 --- /dev/null +++ b/discovery-server/src/main/java/ru/project/iakov/discoveryserver/DiscoveryServerApplication.java @@ -0,0 +1,13 @@ +package ru.project.iakov.discoveryserver; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; + +@SpringBootApplication +@EnableEurekaServer +public class DiscoveryServerApplication { + public static void main(String[] args) { + SpringApplication.run(DiscoveryServerApplication.class, args); + } +} \ No newline at end of file diff --git a/discovery-server/src/main/resources/application-docker.yml b/discovery-server/src/main/resources/application-docker.yml new file mode 100644 index 0000000..40de21b --- /dev/null +++ b/discovery-server/src/main/resources/application-docker.yml @@ -0,0 +1,11 @@ +server: + port: 8761 + +spring: + application: + name: discovery-server + +eureka: + client: + register-with-eureka: false + fetch-registry: false \ No newline at end of file diff --git a/discovery-server/src/main/resources/application.yml b/discovery-server/src/main/resources/application.yml new file mode 100644 index 0000000..9652c74 --- /dev/null +++ b/discovery-server/src/main/resources/application.yml @@ -0,0 +1,9 @@ +server: + port: 8761 +spring: + application: + name: discovery-server +eureka: + client: + register-with-eureka: false + fetch-registry: false \ No newline at end of file diff --git a/discovery-server/target/classes/application.yml b/discovery-server/target/classes/application.yml new file mode 100644 index 0000000..9652c74 --- /dev/null +++ b/discovery-server/target/classes/application.yml @@ -0,0 +1,9 @@ +server: + port: 8761 +spring: + application: + name: discovery-server +eureka: + client: + register-with-eureka: false + fetch-registry: false \ No newline at end of file diff --git a/discovery-server/target/classes/ru/project/iakov/discoveryserver/DiscoveryServerApplication.class b/discovery-server/target/classes/ru/project/iakov/discoveryserver/DiscoveryServerApplication.class new file mode 100644 index 0000000..4b2b6cc Binary files /dev/null and b/discovery-server/target/classes/ru/project/iakov/discoveryserver/DiscoveryServerApplication.class differ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4a330a5 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,115 @@ +services: + + postgres: + image: postgres:15 + container_name: postgres + restart: unless-stopped + user: postgres + environment: + POSTGRES_DB: postgres + PGUSER: postgres + POSTGRES_PASSWORD: postgres + env_file: + - .env + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER $$POSTGRES_DB"] + interval: 10s + timeout: 5s + retries: 5 + + zookeeper: + image: confluentinc/cp-zookeeper:7.4.0 + container_name: zookeeper + environment: + ZOOKEEPER_CLIENT_PORT: 2181 + ports: + - "2181:2181" + + kafka: + image: confluentinc/cp-kafka:7.4.0 + container_name: kafka + depends_on: + - zookeeper + ports: + - "9092:9092" + environment: + KAFKA_BROKER_ID: 1 + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092 + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 + + discovery-server: + container_name: discovery-server + image: discovery-server:latest + build: + context: ./discovery-server + ports: + - "8761:8761" + + config-server: + image: config-server:latest + build: + context: ./config-server + ports: + - "8888:8888" + volumes: + - ./config-repo:/config + depends_on: + - discovery-server + environment: + - SPRING_PROFILES_ACTIVE=docker + + user-service: + image: user-service:latest + build: + context: ./user-service + ports: + - "8082:8082" + depends_on: + - discovery-server + - kafka + - postgres + - config-server + environment: + - SPRING_PROFILES_ACTIVE=docker + - EMAIL_USERNAME=${EMAIL_USERNAME} + - EMAIL_PASSWORD=${EMAIL_PASSWORD} + - DB_USERNAME=${DB_USERNAME} + - DB_PASSWORD=${DB_PASSWORD} + env_file: + - .env + + notification-service: + image: notification-service:latest + build: + context: ./notification-service + ports: + - "8081:8081" + depends_on: + - kafka + - config-server + environment: + - SPRING_PROFILES_ACTIVE=docker + - EMAIL_USERNAME=${EMAIL_USERNAME} + - EMAIL_PASSWORD=${EMAIL_PASSWORD} + env_file: + - .env + + api-gateway: + image: api-gateway:latest + build: + context: ./api-gateway + ports: + - "8080:8080" + depends_on: + - discovery-server + - config-server + environment: + - SPRING_PROFILES_ACTIVE=docker +volumes: + pgdata: + diff --git a/notification-service/Dockerfile b/notification-service/Dockerfile new file mode 100644 index 0000000..85e14b1 --- /dev/null +++ b/notification-service/Dockerfile @@ -0,0 +1,6 @@ +FROM eclipse-temurin:21-jdk-alpine +LABEL authors="iakovlysenko" +VOLUME /tmp +ARG JAR_FILE=target/notification-service-1.0-SNAPSHOT.jar +COPY ${JAR_FILE} app.jar +ENTRYPOINT ["java","-jar","/app.jar"] \ No newline at end of file diff --git a/notification-service/pom.xml b/notification-service/pom.xml index 3ee33e8..0580104 100644 --- a/notification-service/pom.xml +++ b/notification-service/pom.xml @@ -4,52 +4,111 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 ru.project.iakov - user-service + notification-service 1.0-SNAPSHOT - 24 - 24 + 21 + 21 UTF-8 + 2023.0.1 + + org.springframework.boot + spring-boot-starter-parent + 3.2.5 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.2.5 + + + + repackage + + + + + + + maven-compiler-plugin + 3.11.0 + + 21 + 21 + + + org.projectlombok + lombok + 1.18.38 + + + + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + org.projectlombok lombok 1.18.38 provided + + org.springframework.boot spring-boot-starter-web - 3.5.0 + + org.springframework.boot spring-boot-starter-test - 3.5.0 test + + org.springframework.kafka spring-kafka - 3.3.6 + + org.springframework.boot spring-boot-starter-mail - 3.4.6 + + - ru.project.iakov - user-service - 1.0-SNAPSHOT - compile + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + - ru.project.iakov - user-service - 1.0-SNAPSHOT - compile + org.springframework.cloud + spring-cloud-starter-config \ No newline at end of file diff --git a/notification-service/src/main/resources/application-docker.yml b/notification-service/src/main/resources/application-docker.yml new file mode 100644 index 0000000..8bef37d --- /dev/null +++ b/notification-service/src/main/resources/application-docker.yml @@ -0,0 +1,24 @@ +server: + port: 8081 + +spring: + application: + name: notification-service + + kafka: + bootstrap-servers: kafka:9092 + + mail: + host: smtp.mail.ru + port: 465 + username: ${EMAIL_USERNAME} + password: ${EMAIL_PASSWORD} + protocol: smtps + properties: + mail.smtp.auth: true + mail.smtp.starttls.enable: true + +eureka: + client: + service-url: + defaultZone: http://discovery-server:8761/eureka \ No newline at end of file diff --git a/notification-service/src/main/resources/application.yml b/notification-service/src/main/resources/application.yml index be161d0..c457813 100644 --- a/notification-service/src/main/resources/application.yml +++ b/notification-service/src/main/resources/application.yml @@ -1,4 +1,8 @@ spring: + application: + name: notification-service + config: + import: optional:configserver:http://localhost:8888 kafka: bootstrap-servers: localhost:9092 consumer: @@ -21,4 +25,8 @@ logging: root: INFO server: - port: 8081 \ No newline at end of file + port: 8081 +eureka: + client: + service-url: + defaultZone: http://localhost:8761/eureka \ No newline at end of file diff --git a/user-service/Dockerfile b/user-service/Dockerfile new file mode 100644 index 0000000..740935f --- /dev/null +++ b/user-service/Dockerfile @@ -0,0 +1,6 @@ +FROM eclipse-temurin:21-jdk-alpine +LABEL authors="iakovlysenko" +VOLUME /tmp +ARG JAR_FILE=target/user-service-1.0-SNAPSHOT.jar +COPY ${JAR_FILE} app.jar +ENTRYPOINT ["java","-jar","/app.jar"] \ No newline at end of file diff --git a/user-service/pom.xml b/user-service/pom.xml index 45a14a8..dd877c1 100644 --- a/user-service/pom.xml +++ b/user-service/pom.xml @@ -4,16 +4,15 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - ru.project.iakov + ru.project.iakov.homework2 user-service 1.0-SNAPSHOT - 21 21 UTF-8 + 2023.0.1 - org.springframework.boot spring-boot-starter-parent @@ -21,13 +20,61 @@ + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.2.5 + + + + repackage + + + + + + + maven-compiler-plugin + 3.11.0 + + 21 + 21 + + + org.projectlombok + lombok + 1.18.38 + + + + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + org.postgresql postgresql 42.7.5 + org.projectlombok lombok @@ -35,41 +82,62 @@ provided + org.springframework.boot spring-boot-starter-web - org.springframework.boot spring-boot-starter-data-jpa + org.springframework.boot spring-boot-starter-test test + org.springframework.kafka spring-kafka + org.springframework.boot spring-boot-starter-mail + org.springdoc springdoc-openapi-starter-webmvc-ui 2.5.0 + org.springframework.boot spring-boot-starter-hateoas + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.cloud + spring-cloud-starter-circuitbreaker-resilience4j + - + \ No newline at end of file diff --git a/user-service/src/main/java/ru/project/iakov/homework2/dto/UserDto.java b/user-service/src/main/java/ru/project/iakov/homework2/dto/UserDto.java index 7660dce..00156a2 100644 --- a/user-service/src/main/java/ru/project/iakov/homework2/dto/UserDto.java +++ b/user-service/src/main/java/ru/project/iakov/homework2/dto/UserDto.java @@ -1,6 +1,6 @@ package ru.project.iakov.homework2.dto; -import lombok.*; +import lombok.*; import java.time.LocalDateTime; @Data diff --git a/user-service/src/main/java/ru/project/iakov/homework2/service/KafkaProducerService.java b/user-service/src/main/java/ru/project/iakov/homework2/service/KafkaProducerService.java index 8671267..1ec5172 100644 --- a/user-service/src/main/java/ru/project/iakov/homework2/service/KafkaProducerService.java +++ b/user-service/src/main/java/ru/project/iakov/homework2/service/KafkaProducerService.java @@ -3,6 +3,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.kafka.core.KafkaTemplate; +import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker; import org.springframework.stereotype.Service; @Service @@ -13,8 +14,13 @@ public class KafkaProducerService { private final KafkaTemplate kafkaTemplate; private static final String TOPIC = "user-events"; + @CircuitBreaker(name = "kafkaProducer", fallbackMethod = "sendUserEventFallback") public void sendUserEvent(String message) { log.info("Отправка сообщения в Kafka: {}", message); kafkaTemplate.send(TOPIC, message); } + + public void sendUserEventFallback(String message, Throwable throwable) { + log.error("Ошибка отправки в Kafka: {}", throwable.getMessage()); + } } \ No newline at end of file diff --git a/user-service/src/main/resources/application-docker.yml b/user-service/src/main/resources/application-docker.yml new file mode 100644 index 0000000..e957962 --- /dev/null +++ b/user-service/src/main/resources/application-docker.yml @@ -0,0 +1,22 @@ +server: + port: 8082 + +spring: + application: + name: user-service + datasource: + url: jdbc:postgresql://postgres:5432/postgres + username: ${DB_USERNAME} + password: ${DB_PASSWORD} + jpa: + hibernate: + ddl-auto: update + show-sql: true + + kafka: + bootstrap-servers: kafka:9092 + +eureka: + client: + service-url: + defaultZone: http://discovery-server:8761/eureka \ No newline at end of file diff --git a/user-service/src/main/resources/application.yml b/user-service/src/main/resources/application.yml index 39d62b0..e93f89c 100644 --- a/user-service/src/main/resources/application.yml +++ b/user-service/src/main/resources/application.yml @@ -1,8 +1,12 @@ spring: + application: + name: user-service + config: + import: optional:configserver:http://configserver:8888 datasource: - url: jdbc:postgresql://localhost:5432/postgres - username: postgres - password: postgres + url: jdbc:postgresql://postgres:5432/postgres + username: ${DB_USERNAME} + password: ${DB_PASSWORD} jpa: hibernate: ddl-auto: update @@ -34,4 +38,8 @@ spring: key-serializer: org.apache.kafka.common.serialization.StringSerializer value-serializer: org.apache.kafka.common.serialization.StringSerializer server: - port: 8080 \ No newline at end of file + port: 8080 + eureka: + client: + service-url: + defaultZone: http://localhost:8761/eureka \ No newline at end of file diff --git a/user-service/src/main/resources/hibernate.cfg.xml b/user-service/src/main/resources/hibernate.cfg.xml deleted file mode 100644 index 1515a41..0000000 --- a/user-service/src/main/resources/hibernate.cfg.xml +++ /dev/null @@ -1,25 +0,0 @@ - \ No newline at end of file diff --git a/user-service/src/main/resources/log4j.properties b/user-service/src/main/resources/log4j.properties deleted file mode 100644 index 7aabc61..0000000 --- a/user-service/src/main/resources/log4j.properties +++ /dev/null @@ -1,7 +0,0 @@ -log4j.rootLogger=INFO, stdout -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.Target=System.out -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss} %-5p [%c] - %m%n -log4j.logger.org.hibernate.SQL=DEBUG -log4j.logger.org.hibernate.type.descriptor.sql.BasicBinder=TRACE \ No newline at end of file diff --git a/user-service/src/test/java/ru/project/iakov/homework2/controller/UserControllerTest.java b/user-service/src/test/java/ru/project/iakov/homework2/controller/UserControllerTest.java deleted file mode 100644 index 5fea5ee..0000000 --- a/user-service/src/test/java/ru/project/iakov/homework2/controller/UserControllerTest.java +++ /dev/null @@ -1,132 +0,0 @@ -package ru.project.iakov.homework2.controller; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import ru.project.iakov.homework2.dto.UserDto; -import ru.project.iakov.homework2.service.UserService; - -import java.time.LocalDateTime; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doThrow; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -@WebMvcTest(UserController.class) -class UserControllerTest { - - @Autowired - private MockMvc mockMvc; - - @MockBean - private UserService userService; - - @Autowired - private ObjectMapper objectMapper; - - @DisplayName("Пользователь найден по ID") - @Test - void getUserById_whenUserExist() throws Exception { - UserDto userDto = new UserDto(1L, "Ivan", "ivan@mail.ru", 30, LocalDateTime.now()); - given(userService.findById(1L)).willReturn(userDto); - - mockMvc.perform(get("/users/1")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.name").value("Ivan")) - .andExpect(jsonPath("$.email").value("ivan@mail.ru")); - } - - @DisplayName("Такого пользователя нет") - @Test - void getUserById_whenUserNotExist() throws Exception { - given(userService.findById(999L)).willThrow(new IllegalArgumentException()); - - mockMvc.perform(get("/users/999")) - .andExpect(result -> assertTrue(result.getResolvedException() instanceof IllegalArgumentException)); - } - - @DisplayName("Список пользователей") - @Test - void getAllUsers() throws Exception { - List users = List.of( - new UserDto(1L, "Ivan", "ivan@mail.ru", 30, LocalDateTime.now()), - new UserDto(2L, "Petr", "petr@mail.ru", 28, LocalDateTime.now()) - ); - given(userService.findAll()).willReturn(users); - - mockMvc.perform(get("/users")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.length()").value(2)); - } - - @DisplayName("Создание пользователя") - @Test - void createUser() throws Exception { - UserDto toCreate = new UserDto(null, "Ivan", "ivan@mail.ru", 30, LocalDateTime.now()); - UserDto created = new UserDto(10L, "Petr", "petr@mail.ru", 28, LocalDateTime.now()); - - given(userService.createUser(any(UserDto.class))).willReturn(created); - - mockMvc.perform(post("/users") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(toCreate))) - .andExpect(status().isCreated()) - .andExpect(jsonPath("$.id").value(10)); - } - - @DisplayName("Обновление пользователя") - @Test - void updateUser_whenUserExist() throws Exception { - UserDto update = new UserDto(null, "Ivan", "ivan@mail.ru", 30, LocalDateTime.now()); - UserDto updated = new UserDto(1L, "Petr", "petr@mail.ru", 28, LocalDateTime.now()); - - given(userService.updateUser(eq(1L), any(UserDto.class))).willReturn(updated); - - mockMvc.perform(put("/users/1") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(update))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.name").value("Petr")); - } - - @DisplayName("При обновлении пользователь не найден") - @Test - void updateUser_whenUserIsNotExist() throws Exception { - given(userService.updateUser(eq(999L), any(UserDto.class))) - .willThrow(new IllegalArgumentException()); - - mockMvc.perform(put("/users/999") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(new UserDto(1L, "Ivan", "ivan@mail.ru", 30, LocalDateTime.now())))) - .andExpect(result -> assertTrue(result.getResolvedException() instanceof IllegalArgumentException)); - } - - @DisplayName("Успешное удаление пользователя") - @Test - void deleteUserSuccess_whenUserExist() throws Exception { - doNothing().when(userService).deleteUser(1L); - - mockMvc.perform(delete("/users/1")) - .andExpect(status().isNoContent()); - } - - @DisplayName("При удалении пользователь не найден") - @Test - void deleteUser_whenUserIsNotExist() throws Exception { - doThrow(new IllegalArgumentException()).when(userService).deleteUser(999L); - - mockMvc.perform(delete("/users/999")) - .andExpect(result -> assertTrue(result.getResolvedException() instanceof IllegalArgumentException)); - } -} \ No newline at end of file