Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,6 @@ dist

# TernJS port file
.tern-port

# Neo4J initial
neo4j
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,57 @@ You can use Graphql;
When you finish your challenge, after forking a repository, you **must** open a pull request to our repository. There are no limitations to the implementation, you can follow the programming paradigm, modularization, and style that you feel is the most appropriate solution.

If you have any questions, please let us know.

# Solution
For this scenario I created two reactive microservices transaction-service and anti-fraud-service , two Apache Kafka Topics (transactions, fraud-results) to communicate each other and Neo4J graph db to store transactions.

## Stack
- Java 25
- Maven 3.5.10
- Zookeeper
- Apache Kafka
- Neo4J

## Instructions to run the solution
You just run the following docker command line, it download and create images and then run docker instances for zookeeper, apache kafka, neo4j, transaction-service, anti-fraud-service.

```sh
docker-compose up -d
```

## Functionality
### 1. Call transaction endpoint creation
To test the flow we can call the following endpoint in order to create the transaction, you can call multiple times with differen values minor or major than 1000, this endpoint register the transaction in the neo4j database and sent the evento to the transaction topic.

```curl
curl --location 'http://localhost:8080/api/v1/transactions' \
--header 'Content-Type: application/json' \
--data '{
"accountExternalIdDebit":"ACCT_DEBT_999_1",
"accountExternalIdCredit":"ACCT_CRED_999_1",
"transferTypeId":1,
"value": 1100
}'
```


### 2. Fraud evaluation
- The anti-fraud-service listen the events from the transaction topic.
- Evaluate the amount
- Send the new status (ACCEPTED, REJECTED) to the fraud-results topic
- The transaction-service listen the events and update the status.

### 3. Verify creation and updating status
You have two ways to verify the transaction status: by endoint and by neo4j console
- By endpoint: you can use the following endpoint (replace the transactionId)
```curl
curl --location 'http://localhost:8080/api/v1/transactions/fb2e5b98-6414-421f-9eff-349806889d18'
```
- By neo4j console: you can go the following and run the query.
```url
http://localhost:7474/browser/
```

```sh
MATCH (n:Account) RETURN n LIMIT 25
```
2 changes: 2 additions & 0 deletions anti-fraud-service/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/mvnw text eol=lf
*.cmd text eol=crlf
33 changes: 33 additions & 0 deletions anti-fraud-service/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
HELP.md
target/
.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/
3 changes: 3 additions & 0 deletions anti-fraud-service/.mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.12/apache-maven-3.9.12-bin.zip
42 changes: 42 additions & 0 deletions anti-fraud-service/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# ── Stage 1: Build ────────────────────────────────────────────────────────────
FROM eclipse-temurin:25-jdk-alpine AS builder

WORKDIR /app

COPY pom.xml .
COPY .mvn/ .mvn/
COPY mvnw .

RUN chmod +x mvnw && \
./mvnw dependency:go-offline -B

COPY src/ src/

RUN ./mvnw clean package -DskipTests -B && \
mkdir -p target/extracted && \
java -Djarmode=layertools -jar target/*.jar extract --destination target/extracted

# ── Stage 2: Runtime ──────────────────────────────────────────────────────────
FROM eclipse-temurin:25-jre-alpine AS runtime

RUN addgroup -S appgroup && adduser -S appuser -G appgroup

WORKDIR /app

COPY --from=builder --chown=appuser:appgroup /app/target/extracted/dependencies/ ./
COPY --from=builder --chown=appuser:appgroup /app/target/extracted/spring-boot-loader/ ./
COPY --from=builder --chown=appuser:appgroup /app/target/extracted/snapshot-dependencies/ ./
COPY --from=builder --chown=appuser:appgroup /app/target/extracted/application/ ./

USER appuser

# Solo puerto interno de Actuator (no expone REST hacia afuera)
EXPOSE 8081

ENV JAVA_OPTS="-XX:+UseContainerSupport \
-XX:MaxRAMPercentage=75.0 \
-XX:+UseZGC \
-Djava.security.egd=file:/dev/./urandom \
-Dspring.profiles.active=docker"

ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS org.springframework.boot.loader.launch.JarLauncher"]
Loading