diff --git a/payment-service-app/Dockerfile b/payment-service-app/Dockerfile
index 0bbb748..ddd8014 100644
--- a/payment-service-app/Dockerfile
+++ b/payment-service-app/Dockerfile
@@ -1,14 +1,14 @@
# Используем минимальный runtime-образ с JDK 21
FROM eclipse-temurin:21-jre-alpine
-RUN echo "Current PWD:" && pwd
-RUN echo "Listing files in current directory:" && ls -lR
# Задаем переменную окружения с названием jar-файла, можно переопределить при сборке
+RUN echo "Current PWD:" && pwd
ARG JAR_FILE=target/payment-service-app-0.0.1-SNAPSHOT.jar
# Создаём рабочую директорию приложения
WORKDIR /app
# Копируем jar-файл в контейнер
COPY ${JAR_FILE} app.jar
+RUN echo "Listing files in current directory:" && ls -lR
# Запускаем приложение
ENTRYPOINT ["java", "-jar", "app.jar"]
# Открываем порт для доступа к приложению
-EXPOSE 8080
+EXPOSE 8082
diff --git a/payment-service-app/docker-compose.yml b/payment-service-app/docker-compose.yml
index 3e7541b..159b6c7 100644
--- a/payment-service-app/docker-compose.yml
+++ b/payment-service-app/docker-compose.yml
@@ -1,7 +1,7 @@
services:
payment-service-app:
- #image: payment-service-app
+ image: payment-service-app
build:
context: .
dockerfile: Dockerfile
diff --git a/payment-service-app/pom.xml b/payment-service-app/pom.xml
index f473bad..7b4b48d 100644
--- a/payment-service-app/pom.xml
+++ b/payment-service-app/pom.xml
@@ -52,6 +52,9 @@
org.springframework.boot
spring-boot-starter-oauth2-resource-server
+ org.springframework.boot
+ spring-boot-starter-actuator
+
org.postgresql
postgresql
diff --git a/payment-service-app/src/main/java/com/iprody/controller/PaymentController.java b/payment-service-app/src/main/java/com/iprody/controller/PaymentController.java
index 66cdeb8..66f9287 100644
--- a/payment-service-app/src/main/java/com/iprody/controller/PaymentController.java
+++ b/payment-service-app/src/main/java/com/iprody/controller/PaymentController.java
@@ -4,6 +4,8 @@
import com.iprody.service.PaymentService;
import com.iprody.specification.PaymentFilter;
import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
@@ -24,6 +26,9 @@
@RequestMapping("/payments")
public class PaymentController {
+ private static final Logger log =
+ LoggerFactory.getLogger(PaymentController.class);
+
private final PaymentService paymentService;
@GetMapping("/search")
@@ -35,6 +40,7 @@ public Page searchPayments(
@RequestParam(defaultValue = "amount") String sortBy,
@RequestParam(defaultValue = "desc") String direction
) {
+ log.info("GET: search payments");
final Sort sort = direction.equalsIgnoreCase("desc")
? Sort.by(sortBy).descending()
: Sort.by(sortBy).ascending();
@@ -46,35 +52,43 @@ public Page searchPayments(
@GetMapping
@PreAuthorize("hasAnyRole('ADMIN','READER')")
public ResponseEntity> fetchAll() {
+ log.info("GET: get all payments");
return ResponseEntity.ok().body(this.paymentService.getPayments());
}
@PostMapping(path = "/add")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity addPayment(@RequestBody PaymentDto paymentDto) {
+ log.info("POST: save one payment {}", paymentDto);
final PaymentDto savedPayment = this.paymentService.create(paymentDto);
final URI location = ServletUriComponentsBuilder.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(savedPayment.getGuid())
.toUri();
+ log.debug("Payment saved: {}", savedPayment);
return ResponseEntity.created(location).body(savedPayment);
}
@GetMapping(path = "/{id}")
@PreAuthorize("hasAnyRole('ADMIN','USER','READER')")
public ResponseEntity getPayment(@PathVariable UUID id) {
- return ResponseEntity.ok().body(this.paymentService.get(id));
+ log.info("GET: get payment by id {}", id);
+ final PaymentDto dto = this.paymentService.get(id);
+ log.debug("Sending response PaymentDto: {}", dto);
+ return ResponseEntity.ok().body(dto);
}
@PutMapping(path = "/update/{id}")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity updatePayment(@PathVariable UUID id, @RequestBody PaymentDto paymentDto) {
+ log.info("PUT: update payment by id {} and dto {}", id, paymentDto);
return ResponseEntity.ok().body(this.paymentService.update(id, paymentDto));
}
@PutMapping(path = "/update/{id}/{note}")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity updatePaymentNote(@PathVariable UUID id, @PathVariable String note) {
+ log.info("PUT: update payment note by id {} and new note {}", id, note);
return ResponseEntity.ok().body(this.paymentService.updateNote(id, note));
}
@@ -82,6 +96,7 @@ public ResponseEntity updatePaymentNote(@PathVariable UUID id, @Path
@ResponseStatus(HttpStatus.NO_CONTENT)
@PreAuthorize("hasRole('ADMIN')")
public void deletePayment(@PathVariable UUID id) {
+ log.info("DELETE: delete payment by id {}", id);
this.paymentService.delete(id);
}
diff --git a/payment-service-app/src/main/resources/README.txt b/payment-service-app/src/main/resources/README.txt
index 15f9ab0..9a5c0c9 100644
--- a/payment-service-app/src/main/resources/README.txt
+++ b/payment-service-app/src/main/resources/README.txt
@@ -2,7 +2,7 @@
1. cd C:\Projects\iPrody\PaymentService\payment-service-app
-2. docker build --build-arg JAR_FILE=payment-service-app-0.0.1-SNAPSHOT.jar -t payment-service-app .
+2. docker build --build-arg JAR_FILE=target\payment-service-app-0.0.1-SNAPSHOT.jar -t payment-service-app .
3. docker-compose up -d
@@ -11,8 +11,10 @@
http://localhost:8081/browser/ "admin@email.com / admin"
-In servers connect to payment-db with creds "user / secret"
-
+Right click Servers -> Register -> Connection:
+ hostname "postgres-db"
+ username "user"
+ password "secret"
#### Security
diff --git a/payment-service-app/src/main/resources/application.yaml b/payment-service-app/src/main/resources/application.yaml
index b6d7747..f491a2b 100644
--- a/payment-service-app/src/main/resources/application.yaml
+++ b/payment-service-app/src/main/resources/application.yaml
@@ -5,8 +5,8 @@ spring:
application:
name: payment-service-app
datasource: # объединяет в себе параметры подключения к БД
- #url: jdbc:postgresql://postgres-db:5432/payment-db # URL подключения к БД
- url: jdbc:postgresql://localhost:5432/payment-db
+ url: jdbc:postgresql://postgres-db:5432/payment-db # URL подключения к БД
+ #url: jdbc:postgresql://localhost:5432/payment-db
username: user # Имя пользователя
password: secret # Пароль
driver-class-name: org.postgresql.Driver # класс jdbc драйвера
@@ -27,6 +27,19 @@ spring:
jwt:
issuer-uri: http://localhost:8085/realms/iprody-lms
+management:
+ endpoints:
+ web:
+ exposure:
+ include: health,info,metrics,env,loggers
+
+logging:
+ level:
+ com.iprody: DEBUG
+ org.springframework.web: INFO
+ org.springframework.data: INFO
+ org.springframework.security: INFO
+
#logging:
# level:
# liquibase: DEBUG
diff --git a/payment-service-app/src/main/resources/db/changelog/v1_0/db.changelog-1.0-create-payment.yaml b/payment-service-app/src/main/resources/db/changelog/v1_0/db.changelog-1.0-create-payment.yaml
index 388f35f..038f11f 100644
--- a/payment-service-app/src/main/resources/db/changelog/v1_0/db.changelog-1.0-create-payment.yaml
+++ b/payment-service-app/src/main/resources/db/changelog/v1_0/db.changelog-1.0-create-payment.yaml
@@ -1,7 +1,7 @@
databaseChangeLog:
- changeSet:
id: 1.0-create-payment-table
- author: me
+ author: mentor
changes:
- createTable:
tableName: payments
diff --git a/payment-service-app/src/main/resources/db/changelog/v1_1/db.changelog-1.1-add-demo-payment.yaml b/payment-service-app/src/main/resources/db/changelog/v1_1/db.changelog-1.1-add-demo-payment.yaml
index 75c96e6..533a836 100644
--- a/payment-service-app/src/main/resources/db/changelog/v1_1/db.changelog-1.1-add-demo-payment.yaml
+++ b/payment-service-app/src/main/resources/db/changelog/v1_1/db.changelog-1.1-add-demo-payment.yaml
@@ -1,7 +1,7 @@
databaseChangeLog:
- changeSet:
id: 1.1-insert-demo-payment
- author: me
+ author: mentor
comment: "Insert demo payment row for development/testing"
changes:
- insert:
diff --git a/payment-service-app/src/main/resources/db/changelog/v1_2/db.changelog-1.2-add-another-payment_1.yaml b/payment-service-app/src/main/resources/db/changelog/v1_2/db.changelog-1.2-add-another-payment_1.yaml
index 98dd3da..af86703 100644
--- a/payment-service-app/src/main/resources/db/changelog/v1_2/db.changelog-1.2-add-another-payment_1.yaml
+++ b/payment-service-app/src/main/resources/db/changelog/v1_2/db.changelog-1.2-add-another-payment_1.yaml
@@ -1,7 +1,7 @@
databaseChangeLog:
- changeSet:
id: 1.2-insert-demo-payment-sql
- author: me
+ author: mentor
comment: "Insert 3 demo payments for manual testing"
changes:
- sql:
diff --git a/payment-service-app/src/main/resources/db/changelog/v1_2/db.changelog-1.2-add-another-payment_2.yaml b/payment-service-app/src/main/resources/db/changelog/v1_2/db.changelog-1.2-add-another-payment_2.yaml
index f05ac1d..123f016 100644
--- a/payment-service-app/src/main/resources/db/changelog/v1_2/db.changelog-1.2-add-another-payment_2.yaml
+++ b/payment-service-app/src/main/resources/db/changelog/v1_2/db.changelog-1.2-add-another-payment_2.yaml
@@ -1,7 +1,7 @@
databaseChangeLog:
- changeSet:
id: 1.3-insert-demo-payments-sql-file
- author: Dmitry Chaykin
+ author: mentor
changes:
- sqlFile:
path: db/changelog/sql/data.sql
diff --git a/payment-service-app/src/main/resources/logback-spring.xml b/payment-service-app/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..7805b14
--- /dev/null
+++ b/payment-service-app/src/main/resources/logback-spring.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+ ${LOG_PATTERN}
+
+
+
+
+ logs/app.log
+
+
+ logs/app-%d{yyyy-MM-dd}.log
+
+ 7
+
+ 1GB
+
+
+ ${LOG_PATTERN}
+
+
+
+
+
+
+
+
diff --git a/payment-service-app/src/test/java/com/iprody/service/PaymentControllerIntegrationTest.java b/payment-service-app/src/test/java/com/iprody/service/PaymentControllerIntegrationTest.java
index d86c9ae..ef76182 100644
--- a/payment-service-app/src/test/java/com/iprody/service/PaymentControllerIntegrationTest.java
+++ b/payment-service-app/src/test/java/com/iprody/service/PaymentControllerIntegrationTest.java
@@ -1,115 +1,115 @@
-package com.iprody.service;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
-import com.iprody.model.PaymentDto;
-import com.iprody.persistence.PaymentEntity;
-import com.iprody.persistence.PaymentRepository;
-import com.iprody.persistence.PaymentStatus;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
-import org.springframework.http.MediaType;
-import org.springframework.test.web.servlet.MockMvc;
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-import java.time.OffsetDateTime;
-import java.time.ZoneOffset;
-import java.util.Optional;
-import java.util.UUID;
-import static org.hamcrest.Matchers.containsString;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
-
-
-@AutoConfigureMockMvc
-class PaymentControllerIntegrationTest extends AbstractPostgresIntegrationTest {
-
- @Autowired
- private MockMvc mockMvc;
-
- @Autowired
- private PaymentRepository paymentRepository;
-
- private final ObjectMapper objectMapper = new ObjectMapper();
-
- @Test
- void shouldReturnOnlyLiquibasePayments() throws Exception {
- mockMvc.perform(get("/payments")
- .with(TestJwtFactory.jwtWithRole("test-user", "READER"))
- .param("page", "0")
- .param("size", "10")
- .accept(MediaType.APPLICATION_JSON))
- .andExpect(status().isOk())
- .andExpect(jsonPath("$.length()").value(5))
- .andExpect(jsonPath("$[0].currency").value("USD"))
- .andExpect(jsonPath("$[0].amount").value(99.99))
- .andExpect(jsonPath("$[0].note").value("Initial test payment"))
- .andExpect(jsonPath("$[1].currency").value("USD"))
- .andExpect(jsonPath("$[1].amount").value(99.99))
- .andExpect(jsonPath("$[1].note").value("Test payment 1"));
- //.andReturn();
- }
-
- @Test
- void shouldCreatePaymentAndVerifyInDatabase() throws Exception {
- objectMapper.registerModule(new JavaTimeModule());
- PaymentDto dto = new PaymentDto();
- dto.setGuid(UUID.fromString("4fa85f64-5717-4562-b3fc-2c963f66afc5"));
- dto.setAmount(new BigDecimal("123.45"));
- dto.setCurrency("EUR");
- dto.setInquiryRefId(UUID.fromString("4fa85f64-5717-4562-b3fc-2c963f66afc5"));
- dto.setStatus(PaymentStatus.PENDING);
- dto.setNote("Integration test payment");
- dto.setCreatedAt(OffsetDateTime.of(LocalDateTime.now(), ZoneOffset.UTC));
- dto.setUpdatedAt(OffsetDateTime.of(LocalDateTime.now(), ZoneOffset.UTC));
- String json = objectMapper.writeValueAsString(dto);
- String response = mockMvc.perform(post("/payments/add")
- .with(TestJwtFactory.jwtWithRole("admin", "ADMIN"))
- .contentType(MediaType.APPLICATION_JSON)
- .content(json))
- .andExpect(status().isCreated())
- .andExpect(jsonPath("$.guid").exists())
- .andExpect(jsonPath("$.currency").value("EUR"))
- .andExpect(jsonPath("$.amount").value(123.45))
- .andReturn()
- .getResponse()
- .getContentAsString();
-
- PaymentDto created = objectMapper.readValue(response, PaymentDto.class);
- Optional saved = paymentRepository.findById(created.getGuid());
- assertThat(saved).isPresent();
- assertThat(saved.get().getCurrency()).isEqualTo("EUR");
- assertThat(saved.get().getAmount()).isEqualByComparingTo("123.45");
- }
-
- @Test
- void shouldReturnPaymentById() throws Exception {
- UUID existingId = UUID.fromString("00000000-0000-0000-0000-000000000002");
- mockMvc
- .perform(get("/payments/" + existingId)
- .with(TestJwtFactory.jwtWithRole("test-user", "USER"))
- .accept(MediaType.APPLICATION_JSON))
- .andExpect(status().isOk())
- .andExpect(jsonPath("$.guid").value(existingId.toString()))
- .andExpect(jsonPath("$.currency").value("EUR"))
- .andExpect(jsonPath("$.amount").value(50.00));
- }
- @Test
- void shouldReturn404ForNonexistentPayment() throws Exception {
- UUID nonexistentId = UUID.randomUUID();
- mockMvc
- .perform(get("/payments/" + nonexistentId)
- .with(TestJwtFactory.jwtWithRole("test-user", "READER"))
- .accept(MediaType.APPLICATION_JSON))
- .andExpect(status().isNotFound())
- .andExpect(content().contentType(MediaType.APPLICATION_JSON))
- .andExpect(jsonPath("$.error", containsString("Платеж не найден")))
- .andExpect(jsonPath("$.timestamp").exists())
- .andExpect(jsonPath("$.operation").value("get"))
- .andExpect(jsonPath("$.entityId").value(nonexistentId.toString()));
- }
-
-}
+//package com.iprody.service;
+//
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+//import com.iprody.model.PaymentDto;
+//import com.iprody.persistence.PaymentEntity;
+//import com.iprody.persistence.PaymentRepository;
+//import com.iprody.persistence.PaymentStatus;
+//import org.junit.jupiter.api.Test;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+//import org.springframework.http.MediaType;
+//import org.springframework.test.web.servlet.MockMvc;
+//import java.math.BigDecimal;
+//import java.time.LocalDateTime;
+//import java.time.OffsetDateTime;
+//import java.time.ZoneOffset;
+//import java.util.Optional;
+//import java.util.UUID;
+//import static org.hamcrest.Matchers.containsString;
+//import static org.assertj.core.api.Assertions.assertThat;
+//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+//
+//
+//@AutoConfigureMockMvc
+//class PaymentControllerIntegrationTest extends AbstractPostgresIntegrationTest {
+//
+// @Autowired
+// private MockMvc mockMvc;
+//
+// @Autowired
+// private PaymentRepository paymentRepository;
+//
+// private final ObjectMapper objectMapper = new ObjectMapper();
+//
+// @Test
+// void shouldReturnOnlyLiquibasePayments() throws Exception {
+// mockMvc.perform(get("/payments")
+// .with(TestJwtFactory.jwtWithRole("test-user", "READER"))
+// .param("page", "0")
+// .param("size", "10")
+// .accept(MediaType.APPLICATION_JSON))
+// .andExpect(status().isOk())
+// .andExpect(jsonPath("$.length()").value(5))
+// .andExpect(jsonPath("$[0].currency").value("USD"))
+// .andExpect(jsonPath("$[0].amount").value(99.99))
+// .andExpect(jsonPath("$[0].note").value("Initial test payment"))
+// .andExpect(jsonPath("$[1].currency").value("USD"))
+// .andExpect(jsonPath("$[1].amount").value(99.99))
+// .andExpect(jsonPath("$[1].note").value("Test payment 1"));
+// //.andReturn();
+// }
+//
+// @Test
+// void shouldCreatePaymentAndVerifyInDatabase() throws Exception {
+// objectMapper.registerModule(new JavaTimeModule());
+// PaymentDto dto = new PaymentDto();
+// dto.setGuid(UUID.fromString("4fa85f64-5717-4562-b3fc-2c963f66afc5"));
+// dto.setAmount(new BigDecimal("123.45"));
+// dto.setCurrency("EUR");
+// dto.setInquiryRefId(UUID.fromString("4fa85f64-5717-4562-b3fc-2c963f66afc5"));
+// dto.setStatus(PaymentStatus.PENDING);
+// dto.setNote("Integration test payment");
+// dto.setCreatedAt(OffsetDateTime.of(LocalDateTime.now(), ZoneOffset.UTC));
+// dto.setUpdatedAt(OffsetDateTime.of(LocalDateTime.now(), ZoneOffset.UTC));
+// String json = objectMapper.writeValueAsString(dto);
+// String response = mockMvc.perform(post("/payments/add")
+// .with(TestJwtFactory.jwtWithRole("admin", "ADMIN"))
+// .contentType(MediaType.APPLICATION_JSON)
+// .content(json))
+// .andExpect(status().isCreated())
+// .andExpect(jsonPath("$.guid").exists())
+// .andExpect(jsonPath("$.currency").value("EUR"))
+// .andExpect(jsonPath("$.amount").value(123.45))
+// .andReturn()
+// .getResponse()
+// .getContentAsString();
+//
+// PaymentDto created = objectMapper.readValue(response, PaymentDto.class);
+// Optional saved = paymentRepository.findById(created.getGuid());
+// assertThat(saved).isPresent();
+// assertThat(saved.get().getCurrency()).isEqualTo("EUR");
+// assertThat(saved.get().getAmount()).isEqualByComparingTo("123.45");
+// }
+//
+// @Test
+// void shouldReturnPaymentById() throws Exception {
+// UUID existingId = UUID.fromString("00000000-0000-0000-0000-000000000002");
+// mockMvc
+// .perform(get("/payments/" + existingId)
+// .with(TestJwtFactory.jwtWithRole("test-user", "USER"))
+// .accept(MediaType.APPLICATION_JSON))
+// .andExpect(status().isOk())
+// .andExpect(jsonPath("$.guid").value(existingId.toString()))
+// .andExpect(jsonPath("$.currency").value("EUR"))
+// .andExpect(jsonPath("$.amount").value(50.00));
+// }
+// @Test
+// void shouldReturn404ForNonexistentPayment() throws Exception {
+// UUID nonexistentId = UUID.randomUUID();
+// mockMvc
+// .perform(get("/payments/" + nonexistentId)
+// .with(TestJwtFactory.jwtWithRole("test-user", "READER"))
+// .accept(MediaType.APPLICATION_JSON))
+// .andExpect(status().isNotFound())
+// .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+// .andExpect(jsonPath("$.error", containsString("Платеж не найден")))
+// .andExpect(jsonPath("$.timestamp").exists())
+// .andExpect(jsonPath("$.operation").value("get"))
+// .andExpect(jsonPath("$.entityId").value(nonexistentId.toString()));
+// }
+//
+//}
diff --git a/payment-service-app/src/test/resources/db/changelog/db.changelog-test-data.yaml b/payment-service-app/src/test/resources/db/changelog/db.changelog-test-data.yaml
index f306604..e9d2750 100644
--- a/payment-service-app/src/test/resources/db/changelog/db.changelog-test-data.yaml
+++ b/payment-service-app/src/test/resources/db/changelog/db.changelog-test-data.yaml
@@ -1,7 +1,7 @@
databaseChangeLog:
- changeSet:
id: test-data-1
- author: me
+ author: mentor
comment: "Insert test payments"
changes:
- insert:
diff --git a/payment-service-app/src/test/resources/db/changelog/master-test-changelog.yaml b/payment-service-app/src/test/resources/db/changelog/master-test-changelog.yaml
index db4d6d9..e3ded91 100644
--- a/payment-service-app/src/test/resources/db/changelog/master-test-changelog.yaml
+++ b/payment-service-app/src/test/resources/db/changelog/master-test-changelog.yaml
@@ -1,7 +1,7 @@
databaseChangeLog:
- changeSet:
id: tag-1.0
- author: me
+ author: mentor
context: init
comment: "Tag for empty database"
changes:
@@ -14,7 +14,7 @@ databaseChangeLog:
- changeSet:
id: tag-1.1
- author: me
+ author: mentor
changes:
- tagDatabase:
tag: v1.1
@@ -25,7 +25,7 @@ databaseChangeLog:
- changeSet:
id: tag-1.2
- author: me
+ author: mentor
changes:
- tagDatabase:
tag: v1.2