chore: vibe debuging untill it started working

This commit is contained in:
Krzysztof kuhy Rudnicki 2025-04-15 17:22:50 +02:00
parent c6b4e8fd3a
commit 3d03d755f6
8 changed files with 779 additions and 25 deletions

129
.gitignore vendored Normal file
View File

@ -0,0 +1,129 @@
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
# Eclipse m2e generated files
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Docker project generated files to ignore
# if you want to ignore files created by your editor/tools,
# please consider a global .gitignore https://help.github.com/articles/ignoring-files
.vagrant*
bin
docker/docker
.*.swp
a.out
*.orig
build_src
.flymake*
.idea
.DS_Store
docs/_build
docs/_static
docs/_templates
.gopath/
.dotcloud
*.test
bundles/
.hg/
.git/
vendor/pkg/
pyenv
Vagrantfile
dist
*classes
*.class
target/
build/
build_eclipse/
out/
.gradle/
.vscode/
lib_managed/
src_managed/
project/boot/
project/plugins/project/
patch-process/*
.idea
.svn
.classpath
/.metadata
/.recommenders
*~
*#
.#*
rat.out
TAGS
*.iml
.project
.settings
*.ipr
*.iws
.vagrant
Vagrantfile.local
/logs
.DS_Store
config/server-*
config/zookeeper-*
gradle/wrapper/*.jar
gradlew.bat
results
tests/results
.ducktape
tests/.ducktape
tests/venv
.cache
docs/generated/
.release-settings.json
kafkatest.egg-info/
systest/
*.swp
jmh-benchmarks/generated
jmh-benchmarks/src/main/generated
**/.jqwik-database
**/src/generated
**/src/generated-test
storage/kafka-tiered-storage/
docker/test/report_*.html
kafka.Kafka
__pycache__
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*

View File

@ -0,0 +1,106 @@
package com.anomaly.model;
import java.time.Instant;
public class TransactionAlert {
private String alertType;
private Instant alertTime;
private Instant timestamp;
private String cardId;
private String userId;
private double amount;
private double latitude;
private double longitude;
private String message;
// Default constructor for Gson deserialization
public TransactionAlert() {
}
public TransactionAlert(String alertType, Instant alertTime, Instant timestamp,
String cardId, String userId, double amount,
double latitude, double longitude, String message) {
this.alertType = alertType;
this.alertTime = alertTime;
this.timestamp = timestamp;
this.cardId = cardId;
this.userId = userId;
this.amount = amount;
this.latitude = latitude;
this.longitude = longitude;
this.message = message;
}
// Getters and setters
public String getAlertType() {
return alertType;
}
public void setAlertType(String alertType) {
this.alertType = alertType;
}
public Instant getAlertTime() {
return alertTime;
}
public void setAlertTime(Instant alertTime) {
this.alertTime = alertTime;
}
public Instant getTimestamp() {
return timestamp;
}
public void setTimestamp(Instant timestamp) {
this.timestamp = timestamp;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -267,7 +267,7 @@ public class AlertVisualizer {
dialog.setVisible(true);
// Auto-dismiss after 5 seconds
Timer timer = new Timer(5000, e -> dialog.dispose());
javax.swing.Timer timer = new javax.swing.Timer(5000, e -> dialog.dispose());
timer.setRepeats(false);
timer.start();
});

View File

@ -0,0 +1,90 @@
package com.anomaly.model;
import java.time.Instant;
/**
* Represents a financial transaction with location data.
*/
public class Transaction {
private String cardId;
private String userId;
private double amount;
private double latitude;
private double longitude;
private Instant timestamp;
// Default constructor for deserialization
public Transaction() {
}
public Transaction(String cardId, String userId, double amount,
double latitude, double longitude, Instant timestamp) {
this.cardId = cardId;
this.userId = userId;
this.amount = amount;
this.latitude = latitude;
this.longitude = longitude;
this.timestamp = timestamp;
}
// Getters and setters
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public Instant getTimestamp() {
return timestamp;
}
public void setTimestamp(Instant timestamp) {
this.timestamp = timestamp;
}
@Override
public String toString() {
return "Transaction{" +
"cardId='" + cardId + '\'' +
", userId='" + userId + '\'' +
", amount=" + amount +
", latitude=" + latitude +
", longitude=" + longitude +
", timestamp=" + timestamp +
'}';
}
}

View File

@ -2,6 +2,9 @@ package com.anomaly.model;
import java.time.Instant;
/**
* Represents an alert generated when an anomaly is detected in a transaction.
*/
public class TransactionAlert {
private String alertType;
private String cardId;
@ -11,14 +14,13 @@ public class TransactionAlert {
private double longitude;
private Instant timestamp;
private String message;
private Instant alertTime;
public TransactionAlert() {
this.alertTime = Instant.now();
}
public TransactionAlert(String alertType, String cardId, String userId, double amount,
double latitude, double longitude, Instant timestamp, String message) {
public TransactionAlert(String alertType, String cardId, String userId,
double amount, double latitude, double longitude,
Instant timestamp, String message) {
this.alertType = alertType;
this.cardId = cardId;
this.userId = userId;
@ -27,28 +29,72 @@ public class TransactionAlert {
this.longitude = longitude;
this.timestamp = timestamp;
this.message = message;
this.alertTime = Instant.now();
}
// Getters and setters
public String getAlertType() { return alertType; }
public void setAlertType(String alertType) { this.alertType = alertType; }
public String getCardId() { return cardId; }
public void setCardId(String cardId) { this.cardId = cardId; }
public String getUserId() { return userId; }
public void setUserId(String userId) { this.userId = userId; }
public double getAmount() { return amount; }
public void setAmount(double amount) { this.amount = amount; }
public double getLatitude() { return latitude; }
public void setLatitude(double latitude) { this.latitude = latitude; }
public double getLongitude() { return longitude; }
public void setLongitude(double longitude) { this.longitude = longitude; }
public Instant getTimestamp() { return timestamp; }
public void setTimestamp(Instant timestamp) { this.timestamp = timestamp; }
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
public Instant getAlertTime() { return alertTime; }
public void setAlertTime(Instant alertTime) { this.alertTime = alertTime; }
public String getAlertType() {
return alertType;
}
public void setAlertType(String alertType) {
this.alertType = alertType;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public Instant getTimestamp() {
return timestamp;
}
public void setTimestamp(Instant timestamp) {
this.timestamp = timestamp;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
@ -59,8 +105,8 @@ public class TransactionAlert {
", amount=" + amount +
", latitude=" + latitude +
", longitude=" + longitude +
", timestamp=" + timestamp +
", message='" + message + '\'' +
", alertTime=" + alertTime +
'}';
}
}

View File

@ -0,0 +1,65 @@
package com.anomaly.model;
/**
* Represents a financial transaction with amount and available credit limit information.
*/
public class Transaction {
private double amount;
private double availableLimit;
private String cardNumber;
private String timestamp;
// Default constructor for deserialization
public Transaction() {
}
// Full constructor
public Transaction(double amount, double availableLimit, String cardNumber, String timestamp) {
this.amount = amount;
this.availableLimit = availableLimit;
this.cardNumber = cardNumber;
this.timestamp = timestamp;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public double getAvailableLimit() {
return availableLimit;
}
public void setAvailableLimit(double availableLimit) {
this.availableLimit = availableLimit;
}
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
@Override
public String toString() {
return "Transaction{" +
"amount=" + amount +
", availableLimit=" + availableLimit +
", cardNumber='" + cardNumber + '\'' +
", timestamp='" + timestamp + '\'' +
'}';
}
}

233
run_anomaly_detection.sh Executable file
View File

@ -0,0 +1,233 @@
#!/bin/bash
# Colors for output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
PROJECT_ROOT=$(pwd)
TOPICS=("transactions" "alerts")
function check_prerequisites {
echo -e "${BLUE}Checking prerequisites...${NC}"
# Check for Java
if ! command -v java &> /dev/null; then
echo -e "${RED}Java is not installed. Please install JDK 11 or higher.${NC}"
exit 1
fi
# Check for Maven
if ! command -v mvn &> /dev/null; then
echo -e "${RED}Maven is not installed. Please install Maven.${NC}"
exit 1
fi
# Check for Docker
if ! command -v docker &> /dev/null; then
echo -e "${RED}Docker is not installed. Please install Docker.${NC}"
exit 1
fi
# Check for docker-compose
if ! command -v docker-compose &> /dev/null; then
echo -e "${RED}Docker Compose is not installed. Please install Docker Compose.${NC}"
exit 1
fi
echo -e "${GREEN}All prerequisites are met.${NC}"
}
function build_projects {
echo -e "${BLUE}Building all projects...${NC}"
# Build each project
for project in "transaction-simulator" "kafka-consumer-visualizer" "anomaly-detector" "alarm-visualizer"; do
echo -e "${YELLOW}Building $project...${NC}"
cd "$PROJECT_ROOT/$project"
mvn clean package -DskipTests
if [ $? -ne 0 ]; then
echo -e "${RED}Failed to build $project.${NC}"
exit 1
fi
done
cd "$PROJECT_ROOT"
echo -e "${GREEN}All projects built successfully.${NC}"
}
function start_infrastructure {
echo -e "${BLUE}Starting Kafka and Flink containers...${NC}"
docker-compose up -d
# Wait for Kafka to be ready
echo -e "${YELLOW}Waiting for Kafka to be ready...${NC}"
sleep 10
# Create Kafka topics
for topic in "${TOPICS[@]}"; do
echo -e "${YELLOW}Creating Kafka topic: $topic${NC}"
docker-compose exec kafka kafka-topics --create \
--topic "$topic" \
--bootstrap-server localhost:9092 \
--partitions 3 \
--replication-factor 1 \
--if-not-exists
done
echo -e "${GREEN}Infrastructure is up and running.${NC}"
}
function start_applications {
echo -e "${BLUE}Starting applications...${NC}"
# Start anomaly detector (Flink app)
echo -e "${YELLOW}Starting Anomaly Detector (Flink App)...${NC}"
cd "$PROJECT_ROOT/anomaly-detector"
java -jar target/anomaly-detector-1.0-SNAPSHOT.jar > "$PROJECT_ROOT/logs/anomaly-detector.log" 2>&1 &
ANOMALY_DETECTOR_PID=$!
echo $ANOMALY_DETECTOR_PID > "$PROJECT_ROOT/logs/anomaly-detector.pid"
sleep 5
# Start alarm visualizer
echo -e "${YELLOW}Starting Alarm Visualizer...${NC}"
cd "$PROJECT_ROOT/alarm-visualizer"
java -jar target/alarm-visualizer-1.0-SNAPSHOT.jar > "$PROJECT_ROOT/logs/alarm-visualizer.log" 2>&1 &
ALARM_VISUALIZER_PID=$!
echo $ALARM_VISUALIZER_PID > "$PROJECT_ROOT/logs/alarm-visualizer.pid"
# Start test consumer/visualizer
echo -e "${YELLOW}Starting Test Consumer Visualizer...${NC}"
cd "$PROJECT_ROOT/kafka-consumer-visualizer"
java -jar target/kafka-consumer-visualizer-1.0-SNAPSHOT.jar > "$PROJECT_ROOT/logs/consumer-visualizer.log" 2>&1 &
CONSUMER_PID=$!
echo $CONSUMER_PID > "$PROJECT_ROOT/logs/consumer-visualizer.pid"
sleep 5
# Start transaction simulator
echo -e "${YELLOW}Starting Transaction Simulator...${NC}"
cd "$PROJECT_ROOT/transaction-simulator"
java -jar target/transaction-simulator-1.0-SNAPSHOT.jar > "$PROJECT_ROOT/logs/transaction-simulator.log" 2>&1 &
SIMULATOR_PID=$!
echo $SIMULATOR_PID > "$PROJECT_ROOT/logs/transaction-simulator.pid"
cd "$PROJECT_ROOT"
echo -e "${GREEN}All applications are running.${NC}"
echo -e "${GREEN}Log files are available in the logs directory.${NC}"
}
function stop_applications {
echo -e "${BLUE}Stopping applications...${NC}"
# Stop all Java applications
if [ -f "$PROJECT_ROOT/logs/transaction-simulator.pid" ]; then
kill $(cat "$PROJECT_ROOT/logs/transaction-simulator.pid") 2>/dev/null
rm "$PROJECT_ROOT/logs/transaction-simulator.pid"
fi
if [ -f "$PROJECT_ROOT/logs/consumer-visualizer.pid" ]; then
kill $(cat "$PROJECT_ROOT/logs/consumer-visualizer.pid") 2>/dev/null
rm "$PROJECT_ROOT/logs/consumer-visualizer.pid"
fi
if [ -f "$PROJECT_ROOT/logs/anomaly-detector.pid" ]; then
kill $(cat "$PROJECT_ROOT/logs/anomaly-detector.pid") 2>/dev/null
rm "$PROJECT_ROOT/logs/anomaly-detector.pid"
fi
if [ -f "$PROJECT_ROOT/logs/alarm-visualizer.pid" ]; then
kill $(cat "$PROJECT_ROOT/logs/alarm-visualizer.pid") 2>/dev/null
rm "$PROJECT_ROOT/logs/alarm-visualizer.pid"
fi
echo -e "${GREEN}All applications stopped.${NC}"
}
function stop_infrastructure {
echo -e "${BLUE}Stopping infrastructure...${NC}"
docker-compose down
echo -e "${GREEN}Infrastructure stopped.${NC}"
}
function show_logs {
echo -e "${BLUE}Available logs:${NC}"
ls -l "$PROJECT_ROOT/logs"
echo -e "${YELLOW}Use 'tail -f logs/[filename]' to view a specific log.${NC}"
}
function print_usage {
echo -e "${BLUE}Credit Card Transaction Anomaly Detection System${NC}"
echo -e "Usage: $0 [options]"
echo -e "Options:"
echo -e " ${GREEN}start${NC} Build and start the entire system"
echo -e " ${GREEN}stop${NC} Stop all components"
echo -e " ${GREEN}restart${NC} Restart the entire system"
echo -e " ${GREEN}status${NC} Check if components are running"
echo -e " ${GREEN}logs${NC} Show log files"
}
function check_status {
echo -e "${BLUE}Checking system status...${NC}"
# Check Docker containers
echo -e "${YELLOW}Docker containers:${NC}"
docker-compose ps
# Check Java processes
echo -e "\n${YELLOW}Java applications:${NC}"
for app in "transaction-simulator" "consumer-visualizer" "anomaly-detector" "alarm-visualizer"; do
if [ -f "$PROJECT_ROOT/logs/$app.pid" ]; then
pid=$(cat "$PROJECT_ROOT/logs/$app.pid")
if ps -p $pid > /dev/null; then
echo -e "${GREEN}$app is running (PID: $pid)${NC}"
else
echo -e "${RED}$app is not running (stale PID file)${NC}"
fi
else
echo -e "${RED}$app is not running${NC}"
fi
done
}
# Create logs directory
mkdir -p "$PROJECT_ROOT/logs"
# Parse command-line arguments
case "$1" in
start)
check_prerequisites
build_projects
start_infrastructure
start_applications
;;
stop)
stop_applications
stop_infrastructure
;;
restart)
stop_applications
stop_infrastructure
sleep 5
start_infrastructure
sleep 5
start_applications
;;
status)
check_status
;;
logs)
show_logs
;;
*)
print_usage
;;
esac

View File

@ -0,0 +1,85 @@
package com.anomaly.model;
import java.time.Instant;
import java.util.Objects;
public class Transaction {
private final String cardId;
private final String userId;
private final double latitude;
private final double longitude;
private final double amount;
private final double availableLimit;
private final Instant timestamp;
public Transaction(String cardId, String userId, double latitude, double longitude,
double amount, double availableLimit, Instant timestamp) {
this.cardId = cardId;
this.userId = userId;
this.latitude = latitude;
this.longitude = longitude;
this.amount = amount;
this.availableLimit = availableLimit;
this.timestamp = timestamp;
}
public String getCardId() {
return cardId;
}
public String getUserId() {
return userId;
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
public double getAmount() {
return amount;
}
public double getAvailableLimit() {
return availableLimit;
}
public Instant getTimestamp() {
return timestamp;
}
@Override
public String toString() {
return "Transaction{" +
"cardId='" + cardId + '\'' +
", userId='" + userId + '\'' +
", latitude=" + latitude +
", longitude=" + longitude +
", amount=" + amount +
", availableLimit=" + availableLimit +
", timestamp=" + timestamp +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Transaction that = (Transaction) o;
return Double.compare(that.latitude, latitude) == 0 &&
Double.compare(that.longitude, longitude) == 0 &&
Double.compare(that.amount, amount) == 0 &&
Double.compare(that.availableLimit, availableLimit) == 0 &&
Objects.equals(cardId, that.cardId) &&
Objects.equals(userId, that.userId) &&
Objects.equals(timestamp, that.timestamp);
}
@Override
public int hashCode() {
return Objects.hash(cardId, userId, latitude, longitude, amount, availableLimit, timestamp);
}
}