Skip to content

Commit

Permalink
enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonathan Henrique Medeiros committed Feb 3, 2024
1 parent ab07589 commit 2504506
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 78 deletions.
22 changes: 17 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,28 @@ COPY pom.xml .
RUN mvn dependency:go-offline

COPY src src
RUN mvn package
RUN mvn package -DskipTests

FROM azul/zulu-openjdk:21 AS release

COPY --from=build /target/*.jar /app.jar
ARG OTEL_AGENT_VERSION=v1.32.0

ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.30.0/opentelemetry-javaagent.jar /
WORKDIR /

COPY docker-entrypoint.sh /
COPY --from=build /target/*.jar app.jar

RUN chmod +x /docker-entrypoint.sh
COPY docker-entrypoint.sh .

RUN useradd billionaire && \
chmod +x docker-entrypoint.sh && \
apt-get update && \
apt-get install -y curl && \
curl -fsSL -o opentelemetry-javaagent.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/${OTEL_AGENT_VERSION}/opentelemetry-javaagent.jar && \
apt-get purge -y --auto-remove curl && \
rm -rf /var/lib/apt/lists/*

USER billionaire

EXPOSE 8080

ENTRYPOINT ["/docker-entrypoint.sh"]
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ install:
test:
@mvn clean test

build:
@VERSION=$$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) && \
docker build . -t "billionaire-api:$$VERSION" --file Dockerfile

version:
@mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$1

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Esta arquitetura consiste em diminuir a concorrência entre transações da API
</br>

[![node](https://img.shields.io/badge/Azul_Zulu_OpenJDK-21-red.svg)](https://www.azul.com/downloads/?package=jdk#zulu)
[![node](https://img.shields.io/badge/Spring_Boot-3.1.4-green.svg)](https://spring.io/)
[![node](https://img.shields.io/badge/Spring_Boot-3.2.2-green.svg)](https://spring.io/)
[![node](https://img.shields.io/badge/MySQL-8.0.28-blue.svg)](https://www.mysql.com/)


Expand Down
2 changes: 1 addition & 1 deletion docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://host.docker.internal:4317
export OTEL_LOGS_EXPORTER=none
export OTEL_SERVICE_NAME=billionaire-api

exec java -Dspring.profiles.active=docker -javaagent:/opentelemetry-javaagent.jar -jar /app.jar
exec java -Dspring.profiles.active=docker -javaagent:opentelemetry-javaagent.jar -jar app.jar
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.4</version>
<version>3.2.2</version>
<relativePath/>
</parent>

<groupId>br.com.multidatasources</groupId>
<artifactId>multidatasources</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>0.0.1</version>
<name>multidatasources</name>

<properties>
Expand All @@ -20,7 +20,7 @@
<maven.compiler.target>${java.version}</maven.compiler.target>
<mapstruct.version>1.5.5.Final</mapstruct.version>
<logstash-logback-encoder.version>7.4</logstash-logback-encoder.version>
<springdoc-openapi-starter-webmvc-ui.version>2.2.0</springdoc-openapi-starter-webmvc-ui.version>
<springdoc-openapi-starter-webmvc-ui.version>2.3.0</springdoc-openapi-starter-webmvc-ui.version>
<snakeyaml.version>2.2</snakeyaml.version>
<h2.version>2.2.220</h2.version>
<opentelemetry.version>1.30.0</opentelemetry.version>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package br.com.multidatasources.service.v1.idempotency;

public enum Algorithm {

SHA_256("SHA-256");

private final String value;

Algorithm(final String value) {
this.value = value;
}

public String value() {
return this.value;
}

}
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
package br.com.multidatasources.service.v1.idempotency.impl;

import br.com.multidatasources.model.IdempotentEntity;
import br.com.multidatasources.service.v1.idempotency.Algorithm;
import br.com.multidatasources.service.v1.idempotency.IdempotencyGenerator;
import br.com.multidatasources.util.JsonUtils;
import org.springframework.stereotype.Component;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

@Component
public class UUIDIdempotencyGenerator implements IdempotencyGenerator {

@Override
public UUID generate(final IdempotentEntity data) {
final var byteBuffer = ByteBuffer.allocate(Long.BYTES);
final var bytes = byteBuffer.putLong(data.hashCode()).array();
return UUID.nameUUIDFromBytes(bytes);
try {
final var messageDigest = MessageDigest.getInstance(Algorithm.SHA_256.value());
final var jsonDataBytes = JsonUtils.toJson(data).getBytes(StandardCharsets.UTF_8);
return UUID.nameUUIDFromBytes(messageDigest.digest(jsonDataBytes));
} catch (final NoSuchAlgorithmException ex) {
throw new IllegalStateException("Algorithm not found", ex);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import br.com.multidatasources.model.Billionaire;
import br.com.multidatasources.repository.BillionaireRepository;
import br.com.multidatasources.service.v1.BillionaireService;
import br.com.multidatasources.service.v1.idempotency.impl.UUIDIdempotencyGenerator;
import jakarta.persistence.EntityExistsException;
import jakarta.persistence.EntityNotFoundException;
Expand All @@ -23,7 +22,6 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

class BillionaireServiceNewTest {
Expand Down Expand Up @@ -115,7 +113,7 @@ void givenAnExistentBillionaire_whenSave_thenThrowsEntityExistsException() {
.then()
.exceptionAsserter()
.isInstanceOf(EntityExistsException.class)
.messageIsEqualTo("Register has exists with idempotency ID: c2ea0bd8-516b-34d1-bc47-7645b8c2e524");
.messageIsEqualTo("Register has exists with idempotency ID: 6a93b53d-93fc-302d-af9e-0c6d4dc80d43");
}

@Test
Expand Down Expand Up @@ -301,7 +299,7 @@ void careerIsEqualTo(final String expected) {
}

void verifyRepositoryDeleteMethodHasCalled() {
verify(billionaireRepository, times(1)).delete(expected);
verify(billionaireRepository).delete(expected);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
import br.com.multidatasources.model.Billionaire;
import br.com.multidatasources.model.factory.BillionaireBuilder;
import br.com.multidatasources.repository.BillionaireRepository;
import br.com.multidatasources.service.v1.BillionaireService;
import br.com.multidatasources.service.v1.idempotency.IdempotencyGenerator;
import jakarta.persistence.EntityExistsException;
import jakarta.persistence.EntityNotFoundException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
Expand All @@ -25,7 +23,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

Expand All @@ -43,7 +41,7 @@ class BillionaireServiceOldTest {

@Test
void givenAValidBillionaireId_whenFindBillionaireById_thenReturnASameBillionaireInformed() {
Billionaire expected = BillionaireBuilder.builder()
final var expected = BillionaireBuilder.builder()
.id(1L)
.firstName("John")
.lastName("Doe")
Expand All @@ -52,35 +50,33 @@ void givenAValidBillionaireId_whenFindBillionaireById_thenReturnASameBillionaire

when(billionaireRepository.findById(anyLong())).thenReturn(Optional.of(expected));

Billionaire actual = subject.findById(1L);
final var actual = subject.findById(1L);

assertThat(actual).usingRecursiveComparison().isEqualTo(expected);
}

@Test
void givenAInvalidBillionaireId_whenFindBillionaireById_thenThrowEntityNotFoundException() {
when(billionaireRepository.findById(anyLong())).thenThrow(new EntityNotFoundException());
when(billionaireRepository.findById(anyLong())).thenReturn(Optional.empty());

Assertions.assertThrows(
EntityNotFoundException.class,
() -> subject.findById(2L),
"Register with id 2 not found"
);
assertThatThrownBy(() -> subject.findById(2L))
.isExactlyInstanceOf(EntityNotFoundException.class)
.hasMessage("Register with id 2 not found");
}

@Test
void givenATwoBillionaires_whenFindAll_thenReturnListWithTwoRegistries() {
Billionaire billionaireOne = BillionaireBuilder.builder()
final var billionaireOne = BillionaireBuilder.builder()
.id(1L)
.firstName("John")
.lastName("Doe")
.career("Software Developer")
.build();

Billionaire billionaireTwo = BillionaireBuilder.builder()
final var billionaireTwo = BillionaireBuilder.builder()
.id(2L)
.firstName("Richard")
.lastName("Roe")
.lastName("Doe")
.career("Software Developer")
.build();

Expand All @@ -90,15 +86,16 @@ void givenATwoBillionaires_whenFindAll_thenReturnListWithTwoRegistries() {

List<Billionaire> actual = subject.findAll();

assertThat(actual).hasSize(2);
assertThat(actual).usingRecursiveComparison().isEqualTo(actual);
assertThat(actual)
.hasSize(2)
.containsExactlyElementsOf(expected);
}

@Test
void givenEmptyDataBillionaires_whenFindAll_thenReturnListWithZeroRegistries() {
when(billionaireRepository.findAll()).thenReturn(Collections.emptyList());

List<Billionaire> actual = subject.findAll();
final var actual = subject.findAll();

assertThat(actual).isEmpty();
}
Expand All @@ -120,8 +117,8 @@ void givenANewBillionaire_whenSave_thenReturnASameBillionaireSaved() {

Billionaire actual = subject.save(expected);

assertThat(actual).usingRecursiveComparison().isEqualTo(expected);
verify(billionaireRepository, times(1)).save(any(Billionaire.class));
assertThat(actual).isEqualTo(expected);
verify(billionaireRepository).save(any(Billionaire.class));
}

@Test
Expand All @@ -142,23 +139,24 @@ void givenAnExistentBillionaire_whenSave_thenThrowsEntityExistsException() {
.isExactlyInstanceOf(EntityExistsException.class)
.hasMessage("Register has exists with idempotency ID: %s".formatted(idempotencyId));

verify(billionaireRepository, times(0)).save(any(Billionaire.class));
verify(billionaireRepository, never()).save(any(Billionaire.class));
}

@Test
void givenAValidBillionaire_whenDelete_thenRepositoryDeleteMethodHasCalledOneTimes() {
Billionaire billionaire = BillionaireBuilder.builder()
final var billionaire = BillionaireBuilder.builder()
.id(1L)
.firstName("John")
.lastName("Doe")
.career("Software Developer")
.build();

doNothing().when(billionaireRepository).delete(any(Billionaire.class));
doNothing()
.when(billionaireRepository).delete(any(Billionaire.class));

subject.delete(billionaire);

verify(billionaireRepository, times(1)).delete(any(Billionaire.class));
verify(billionaireRepository).delete(any(Billionaire.class));
}

}
37 changes: 0 additions & 37 deletions src/test/resources/application-test.properties

This file was deleted.

21 changes: 21 additions & 0 deletions src/test/resources/application-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# DATABASE SCHEMA PROPERTIES
schema:
name: master-db
user: sa
pass: sa

# DATABASE MASTER PROPERTIES
master:
datasource:
host: localhost
url: jdbc:h2:mem:${schema.name};DB_CLOSE_DELAY=-1
username: ${schema.user}
password: ${schema.pass}

# DATABASE REPLICA PROPERTIES
replica:
datasource:
host: localhost
url: jdbc:h2:mem:${schema.name};DB_CLOSE_DELAY=-1
username: ${schema.user}
password: ${schema.pass}

0 comments on commit 2504506

Please sign in to comment.