Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
overpathz committed Jan 5, 2025
1 parent 3b29cbd commit e8cc431
Show file tree
Hide file tree
Showing 26 changed files with 1,333 additions and 0 deletions.
19 changes: 19 additions & 0 deletions .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM maven:3.9.5-eclipse-temurin-21 AS build-env
WORKDIR /app

COPY pom.xml .
RUN mvn dependency:go-offline

COPY src ./src
RUN mvn package -DskipTests

FROM openjdk:21-slim
VOLUME /tmp

COPY --from=build-env /app/target/distributed-job-processor-0.0.1.jar /app/app.jar

ENTRYPOINT ["java", "-jar", "/app/app.jar"]
33 changes: 33 additions & 0 deletions HELP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Getting Started

### Reference Documentation

For further reference, please consider the following sections:

* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/3.4.1/maven-plugin)
* [Create an OCI image](https://docs.spring.io/spring-boot/3.4.1/maven-plugin/build-image.html)
* [Resilience4J](https://docs.spring.io/spring-cloud-circuitbreaker/reference/spring-cloud-circuitbreaker-resilience4j.html)
* [Spring Data JPA](https://docs.spring.io/spring-boot/3.4.1/reference/data/sql.html#data.sql.jpa-and-spring-data)
* [Spring Data Redis (Access+Driver)](https://docs.spring.io/spring-boot/3.4.1/reference/data/nosql.html#data.nosql.redis)
* [Prometheus](https://docs.spring.io/spring-boot/3.4.1/reference/actuator/metrics.html#actuator.metrics.export.prometheus)
* [Spring Web](https://docs.spring.io/spring-boot/3.4.1/reference/web/servlet.html)

### Guides

The following guides illustrate how to use some features concretely:

* [Accessing Data with JPA](https://spring.io/guides/gs/accessing-data-jpa/)
* [Messaging with Redis](https://spring.io/guides/gs/messaging-redis/)
* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
* [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)

### Maven Parent overrides

Due to Maven's design, elements are inherited from the parent POM to the project POM.
While most of the inheritance is fine, it also inherits unwanted elements like `<license>` and `<developers>` from the
parent.
To prevent this, the project POM contains empty overrides for these elements.
If you manually switch to a different parent and actually want the inheritance, you need to remove those overrides.

41 changes: 41 additions & 0 deletions deployment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: distributed-job-processor
labels:
app: distributed-job-processor
spec:
replicas: 3 # Set the number of replicas here
selector:
matchLabels:
app: distributed-job-processor
template:
metadata:
labels:
app: distributed-job-processor
spec:
containers:
- name: distributed-job-processor
image: distributed-job-processor:0.0.1
ports:
- containerPort: 8080
env:
- name: SPRING_DATASOURCE_URL
value: "jdbc:postgresql://host.docker.internal:5432/paymentsdb"
- name: SPRING_DATASOURCE_USERNAME
value: "puser"
- name: SPRING_DATASOURCE_PASSWORD
value: "ppass"
---
apiVersion: v1
kind: Service
metadata:
name: distributed-job-processor-service
spec:
selector:
app: distributed-job-processor
ports:
- protocol: TCP
port: 8080
targetPort: 8080
type: NodePort # Expose on a specific port for testing
132 changes: 132 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
version: "3.8"

services:
# 1. POSTGRES DB
db:
image: postgres:15-alpine
container_name: distributed-job-processor-postgres
environment:
POSTGRES_DB: paymentsdb
POSTGRES_USER: puser
POSTGRES_PASSWORD: ppass
ports:
- "5432:5432"
volumes:
- db-data:/var/lib/postgresql/data
- ./init-db/init.sql:/docker-entrypoint-initdb.d/init.sql
- ./init-db/init-payment-intents.sql:/docker-entrypoint-initdb.d/init-payment-intents.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U puser -d paymentsdb"]
interval: 5s
timeout: 5s
retries: 5

# 2. DISTRIBUTED-JOB-PROCESSOR Spring Boot App
distributed-job-processor:
build:
context: .
dockerfile: Dockerfile
image: com.overpathz/distributed-job-processor:0.0.1
container_name: distributed-job-processor-app
depends_on:
db:
condition: service_healthy
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: "jdbc:postgresql://db:5432/paymentsdb"
SPRING_DATASOURCE_USERNAME: "puser"
SPRING_DATASOURCE_PASSWORD: "ppass"
# ? Optional stuff. Expose Prometheus endpoint on /actuator/prometheus
# (Actuator + Micrometer dependencies required)

# 3. ELASTICSEARCH (logs from filebeat)
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.9.2
container_name: elasticsearch
environment:
- discovery.type=single-node
- xpack.security.enabled=false # disable security for local development
- xpack.security.transport.ssl.enabled=false
- xpack.security.http.ssl.enabled=false
- ES_JAVA_OPTS=-Xms512m -Xmx512m # configurable :)
volumes:
- es-data:/usr/share/elasticsearch/data
ports:
- "9200:9200"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9200/_cluster/health"]
interval: 5s
timeout: 5s
retries: 5

# 4. KIBANA (logs from elasticsearch)
kibana:
image: docker.elastic.co/kibana/kibana:8.9.2
container_name: kibana
depends_on:
elasticsearch:
condition: service_healthy
environment:
- SERVER_NAME=kibana
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- XPACK_SECURITY_ENABLED=false
ports:
- "5601:5601"

# 5. FILEBEAT (collects container logs and sends to Elasticsearch)
filebeat:
image: docker.elastic.co/beats/filebeat:8.9.2
container_name: filebeat
user: root
depends_on:
elasticsearch:
condition: service_healthy
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- ./filebeat/filebeat.docker.yml:/usr/share/filebeat/filebeat.yml:ro
environment:
- ELASTICSEARCH_HOST=elasticsearch
- ELASTICSEARCH_PORT=9200
# If you enable ES security, specify credentials or tokens

# 6. PROMETHEUS. Scrapes metrics from our docker container
prometheus:
image: prom/prometheus:v2.47.1
container_name: prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--web.enable-lifecycle"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
ports:
- "9090:9090"
healthcheck:
test: ["CMD-SHELL", "wget --spider -q http://localhost:9090/-/healthy || exit 1"]
interval: 5s
timeout: 5s
retries: 5

# 7. GRAFANA. Dashboard for metrics from Prometheus
grafana:
image: grafana/grafana:10.1.0
container_name: grafana
depends_on:
prometheus:
condition: service_healthy
ports:
- "3000:3000"
environment:
GF_SECURITY_ADMIN_PASSWORD: "admin"
GF_SERVER_DOMAIN: "localhost"
GF_SERVER_ROOT_URL: "http://localhost:3000"
volumes:
- grafana-data:/var/lib/grafana

volumes:
db-data:
name: db-data
es-data:
grafana-data:
33 changes: 33 additions & 0 deletions filebeat/filebeat.docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
filebeat.autodiscover:
providers:
- type: docker
hints.enabled: true
templates:
- condition:
contains:
docker.container.name: "distributed-job-processor-app"
config:
- type: container
paths:
- /var/lib/docker/containers/${data.docker.container.id}/*.log
# You can add more parse or multiline settings here if needed

- type: docker
hints.enabled: true
templates:
- condition:
contains:
docker.container.name: "distributed-job-processor-postgres"
config:
- type: container
paths:
- /var/lib/docker/containers/${data.docker.container.id}/*.log

# -> logs to Elasticsearch
output.elasticsearch:
hosts: ["${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}"]
# If security is enabled, add username/password or token

# (Optional) console output for debugging
# output.console:
# pretty: true
19 changes: 19 additions & 0 deletions init-db/init-payment-intents.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
CREATE TABLE IF NOT EXISTS payment_intent (
id SERIAL PRIMARY KEY,
amount NUMERIC(10, 2) NOT NULL,
status VARCHAR(50) NOT NULL,
created_at TIMESTAMP NOT NULL
);


DO
$$
DECLARE
i INT;
BEGIN
FOR i IN 1..1000000 LOOP
INSERT INTO payment_intent (amount, status, created_at)
VALUES ((100 + i % 10), 'NEW', NOW());
END LOOP;
END
$$;
8 changes: 8 additions & 0 deletions init-db/init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
DO
$$
BEGIN
IF NOT EXISTS(SELECT 1 FROM pg_database WHERE datname = 'paymentsdb') THEN
CREATE DATABASE paymentsdb;
END IF;
END
$$;
Loading

0 comments on commit e8cc431

Please sign in to comment.