mirror of
https://github.com/kuhyx/WUT_Computer_Science.git
synced 2026-07-04 15:23:11 +02:00
chore: vibe debuging untill it started working
This commit is contained in:
parent
c6b4e8fd3a
commit
3d03d755f6
129
.gitignore
vendored
Normal file
129
.gitignore
vendored
Normal 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*
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -267,7 +267,7 @@ public class AlertVisualizer {
|
|||||||
dialog.setVisible(true);
|
dialog.setVisible(true);
|
||||||
|
|
||||||
// Auto-dismiss after 5 seconds
|
// 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.setRepeats(false);
|
||||||
timer.start();
|
timer.start();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,6 +2,9 @@ package com.anomaly.model;
|
|||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an alert generated when an anomaly is detected in a transaction.
|
||||||
|
*/
|
||||||
public class TransactionAlert {
|
public class TransactionAlert {
|
||||||
private String alertType;
|
private String alertType;
|
||||||
private String cardId;
|
private String cardId;
|
||||||
@ -11,14 +14,13 @@ public class TransactionAlert {
|
|||||||
private double longitude;
|
private double longitude;
|
||||||
private Instant timestamp;
|
private Instant timestamp;
|
||||||
private String message;
|
private String message;
|
||||||
private Instant alertTime;
|
|
||||||
|
|
||||||
public TransactionAlert() {
|
public TransactionAlert() {
|
||||||
this.alertTime = Instant.now();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransactionAlert(String alertType, String cardId, String userId, double amount,
|
public TransactionAlert(String alertType, String cardId, String userId,
|
||||||
double latitude, double longitude, Instant timestamp, String message) {
|
double amount, double latitude, double longitude,
|
||||||
|
Instant timestamp, String message) {
|
||||||
this.alertType = alertType;
|
this.alertType = alertType;
|
||||||
this.cardId = cardId;
|
this.cardId = cardId;
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
@ -27,28 +29,72 @@ public class TransactionAlert {
|
|||||||
this.longitude = longitude;
|
this.longitude = longitude;
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.alertTime = Instant.now();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getters and setters
|
// Getters and setters
|
||||||
public String getAlertType() { return alertType; }
|
public String getAlertType() {
|
||||||
public void setAlertType(String alertType) { this.alertType = alertType; }
|
return alertType;
|
||||||
public String getCardId() { return cardId; }
|
}
|
||||||
public void setCardId(String cardId) { this.cardId = cardId; }
|
|
||||||
public String getUserId() { return userId; }
|
public void setAlertType(String alertType) {
|
||||||
public void setUserId(String userId) { this.userId = userId; }
|
this.alertType = alertType;
|
||||||
public double getAmount() { return amount; }
|
}
|
||||||
public void setAmount(double amount) { this.amount = amount; }
|
|
||||||
public double getLatitude() { return latitude; }
|
public String getCardId() {
|
||||||
public void setLatitude(double latitude) { this.latitude = latitude; }
|
return cardId;
|
||||||
public double getLongitude() { return longitude; }
|
}
|
||||||
public void setLongitude(double longitude) { this.longitude = longitude; }
|
|
||||||
public Instant getTimestamp() { return timestamp; }
|
public void setCardId(String cardId) {
|
||||||
public void setTimestamp(Instant timestamp) { this.timestamp = timestamp; }
|
this.cardId = cardId;
|
||||||
public String getMessage() { return message; }
|
}
|
||||||
public void setMessage(String message) { this.message = message; }
|
|
||||||
public Instant getAlertTime() { return alertTime; }
|
public String getUserId() {
|
||||||
public void setAlertTime(Instant alertTime) { this.alertTime = alertTime; }
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
@ -59,8 +105,8 @@ public class TransactionAlert {
|
|||||||
", amount=" + amount +
|
", amount=" + amount +
|
||||||
", latitude=" + latitude +
|
", latitude=" + latitude +
|
||||||
", longitude=" + longitude +
|
", longitude=" + longitude +
|
||||||
|
", timestamp=" + timestamp +
|
||||||
", message='" + message + '\'' +
|
", message='" + message + '\'' +
|
||||||
", alertTime=" + alertTime +
|
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
233
run_anomaly_detection.sh
Executable 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
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user