summaryrefslogtreecommitdiff
path: root/src/main/java/com/rinha/backend/service
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/rinha/backend/service')
-rw-r--r--src/main/java/com/rinha/backend/service/PaymentService.java116
-rw-r--r--src/main/java/com/rinha/backend/service/SummaryService.java41
2 files changed, 157 insertions, 0 deletions
diff --git a/src/main/java/com/rinha/backend/service/PaymentService.java b/src/main/java/com/rinha/backend/service/PaymentService.java
new file mode 100644
index 0000000..bd283c3
--- /dev/null
+++ b/src/main/java/com/rinha/backend/service/PaymentService.java
@@ -0,0 +1,116 @@
+package com.rinha.backend.service;
+
+import com.rinha.backend.model.PaymentModel;
+import com.rinha.backend.repository.PaymentRepository;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Service;
+
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import java.util.Random;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Service
+public class PaymentService {
+ private static String processorDefault = "http://payment-processor-default:8080/payments";
+ private static String processorFallback = "http://payment-processor-fallback:8080/payments";
+ private final HttpClient httpClient = HttpClient.newHttpClient();
+ private static final Random random = new Random();
+ private final ExecutorService dbExecutor = Executors.newFixedThreadPool(2);
+
+ private final BlockingQueue<PaymentModel> paymentQueue = new ArrayBlockingQueue<PaymentModel>(65536);
+ private final PaymentRepository paymentRepository;
+
+ public PaymentService(PaymentRepository paymentRepository) {
+ this.paymentRepository = paymentRepository;
+ this.startWorker();
+ }
+
+ public void addQueue(PaymentModel p) {
+ p.setData(OffsetDateTime.now(ZoneOffset.UTC));
+ paymentQueue.add(p);
+ }
+
+ public void startWorker() {
+ for(int i = 1; i <= 4; ++i) {
+ Thread worker = new Thread(() -> {
+ while (true) {
+ try {
+ PaymentModel p = paymentQueue.take();
+ processPayment(p);
+ } catch (InterruptedException e) {
+ }
+ }
+ });
+
+ worker.setName("worker-" + i);
+ worker.start();
+ }
+ }
+
+ public void processPayment(PaymentModel p) {
+ //System.out.println("Processando pagamento " + p.getCorrelationId() +
+ // " no valor de " + p.getAmount() +
+ // " às " + p.getData());
+
+ int ok = sendToProcessor(p);
+ if(ok > 0) {
+ p.setProcessor(ok);
+ saveDB(p);
+ }else
+ paymentQueue.add(p);
+ }
+
+ public int sendToProcessor(PaymentModel p) {
+ try {
+ String body = String.format("""
+ {
+ "correlationId": "%s",
+ "amount": %.2f,
+ "requestedAt": "%s"
+ }
+ """, p.getCorrelationId(), p.getAmount(), p.getData());
+
+ int n = random.nextInt(100);
+ String url;
+ if(n < 60) url = processorDefault;
+ else url = processorFallback;
+
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(url))
+ .header("Content-Type", "application/json")
+ .POST(HttpRequest.BodyPublishers.ofString(body))
+ .build();
+
+ HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+
+ //System.out.println("Resposta servidor: " + response.statusCode() + " - " + response.body());
+ if(response.statusCode() == 200 && url.equals(processorDefault))
+ return 1;
+ if(response.statusCode() == 200 && url.equals(processorFallback))
+ return 2;
+ return 0;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void saveDB(PaymentModel p){
+ //paymentRepository.save(p);
+ dbExecutor.submit(() -> {
+ try {
+ paymentRepository.save(p);
+ } catch (Exception e) {
+ }
+ });
+ }
+}
diff --git a/src/main/java/com/rinha/backend/service/SummaryService.java b/src/main/java/com/rinha/backend/service/SummaryService.java
new file mode 100644
index 0000000..d3fb32e
--- /dev/null
+++ b/src/main/java/com/rinha/backend/service/SummaryService.java
@@ -0,0 +1,41 @@
+package com.rinha.backend.service;
+
+import com.rinha.backend.model.PaymentModel;
+import com.rinha.backend.model.SummaryModel;
+import com.rinha.backend.repository.PaymentRepository;
+import org.springframework.stereotype.Service;
+
+import java.time.OffsetDateTime;
+import java.util.List;
+
+@Service
+public class SummaryService {
+
+ private final PaymentRepository paymentRepository;
+
+ public SummaryService(PaymentRepository paymentRepository) {
+ this.paymentRepository = paymentRepository;
+ }
+
+ public SummaryModel getSummary(OffsetDateTime from, OffsetDateTime to) {
+ SummaryModel summary = new SummaryModel();
+ if (from == null) from = OffsetDateTime.MIN;
+ if (to == null) to = OffsetDateTime.MAX;
+
+ List<PaymentModel> payments = paymentRepository.findAll();
+
+ for (PaymentModel p : payments) {
+ if(p.getData().isBefore(from) || p.getData().isAfter(to)) continue;
+
+ if (p.getProcessor() == 1) {
+ summary.getProcessorDefault().addTotalRequests(1);
+ summary.getProcessorDefault().addTotalAmount(p.getAmount());
+ } else if (p.getProcessor() == 2) {
+ summary.getProcessorFallback().addTotalRequests(1);
+ summary.getProcessorFallback().addTotalAmount(p.getAmount());
+ }
+ }
+
+ return summary;
+ }
+}