Skip to content
Merged
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
86 changes: 86 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: CI Pipeline

on:
push:
branches:
- develop
- main
tags:
- 'v*'


env:
DOCKERHUB_USERNAME: threeamigoscoding

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up JDK 25
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '25'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@0b6dd653ba04f4f93bf581ec31e66cbd7dcb644d

- name: Build with Gradle
run: ./gradlew clean build

- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: build-artifact
path: build/libs/*.jar
retention-days: 1

publish:
needs: build
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Download build artifact
uses: actions/download-artifact@v4
with:
name: build-artifact
path: build/libs

- name: Generate version tag
id: version
run: |
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION_TAG=${GITHUB_REF#refs/tags/v}
elif [[ $GITHUB_REF == refs/heads/main ]]; then
SHORT_SHA=$(git rev-parse --short HEAD)
VERSION_TAG="main-${SHORT_SHA}"
else
SHORT_SHA=$(git rev-parse --short HEAD)
VERSION_TAG="develop-${SHORT_SHA}"
fi
echo "tag=$VERSION_TAG" >> $GITHUB_OUTPUT
echo "Generated version tag: $VERSION_TAG"

- name: Build and push Docker image with Kaniko
env:
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
mkdir -p /tmp/kaniko/.docker
echo "{\"auths\":{\"https://index.docker.io/v1/\":{\"auth\":\"$(echo -n ${{ env.DOCKERHUB_USERNAME }}:${DOCKERHUB_TOKEN} | base64)\"}}}" > /tmp/kaniko/.docker/config.json
docker run \
-v ${{ github.workspace }}:/workspace \
-v /tmp/kaniko/.docker:/kaniko/.docker \
gcr.io/kaniko-project/executor:latest \
--context=/workspace \
--dockerfile=/workspace/Dockerfile \
--destination=${{ env.DOCKERHUB_USERNAME }}/devoops-gateway-service:${{ steps.version.outputs.tag }} \
--destination=${{ env.DOCKERHUB_USERNAME }}/devoops-gateway-service:latest \
--cache=true \
--cache-repo=${{ env.DOCKERHUB_USERNAME }}/devoops-gateway-service-cache
27 changes: 27 additions & 0 deletions .github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: PR Check

on:
pull_request:
branches:
- develop
- main

jobs:
build-and-test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up JDK 25
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '25'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4

- name: Build with Gradle
run: ./gradlew clean build
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ out/
.vscode/

### Mac ###
.DS_Store
.DS_Store

12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM eclipse-temurin:25-jre-alpine

WORKDIR /app

COPY build/libs/*SNAPSHOT.jar app.jar

RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]
20 changes: 16 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,22 @@ repositories {
extra["springCloudVersion"] = "2025.1.0"

dependencies {
implementation("org.springframework.boot:spring-boot-starter-webmvc")
implementation("org.springframework.cloud:spring-cloud-starter-gateway-server-webmvc")
testImplementation("org.springframework.boot:spring-boot-starter-webmvc-test")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation("org.springframework.boot:spring-boot-starter-webmvc")
implementation("org.springframework.cloud:spring-cloud-starter-gateway-server-webmvc")
implementation("io.jsonwebtoken:jjwt-api:0.12.6")
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.6")
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.6")
implementation("net.logstash.logback:logstash-logback-encoder:8.0")
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("io.micrometer:micrometer-registry-prometheus")
//zipkin(tracing)
implementation("org.springframework.boot:spring-boot-micrometer-tracing-brave")
implementation("org.springframework.boot:spring-boot-starter-zipkin")
implementation("io.micrometer:micrometer-tracing-bridge-brave")
implementation("io.zipkin.reporter2:zipkin-reporter-brave")
developmentOnly("org.springframework.boot:spring-boot-devtools")
testImplementation("org.springframework.boot:spring-boot-starter-webmvc-test")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

dependencyManagement {
Expand Down
11 changes: 11 additions & 0 deletions environment/.local.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
SERVER_PORT=8080
USER_SERVICE_URL=http://devoops-user-service:8080
ACCOMMODATION_SERVICE_URL=http://devoops-accommodation-service:8080
NOTIFICATION_SERVICE_URL=http://devoops-notification-service:8080
RATING_SERVICE_URL=http://devoops-rating-service:8080
RESERVATION_SERVICE_URL=http://devoops-reservation-service:8080
SEARCH_SERVICE_URL=http://devoops-search-service:8080
LOGSTASH_HOST=logstash:5000
ZIPKIN_HOST=zipkin
ZIPKIN_PORT=9411
JWT_SECRET=dGhpcyBpcyBhIHZlcnkgc2VjdXJlIGtleSBmb3IgSFMyNTYgdGhhdCBpcyBhdCBsZWFzdCAyNTYgYml0cyBsb25n
54 changes: 54 additions & 0 deletions environment/helm/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
fullnameOverride: devoops-gateway-service
replicaCount: 1

image:
registry: docker.io
repository: threeamigoscoding/devoops-gateway-service
tag: "latest"
pullPolicy: IfNotPresent

service:
type: ClusterIP
httpPort: 8080
grpc:
enabled: false

ingress:
enabled: true
className: nginx
host: devoops.local
path: /
pathType: Prefix
annotations: {}

resources:
requests:
memory: 256Mi
cpu: 250m
limits:
memory: 512Mi
cpu: 1000m

health:
path: /actuator/health
periodSeconds: 10
failureThreshold: 3
startup:
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 60

configData:
JAVA_TOOL_OPTIONS: "-XX:+UseSerialGC -Xms128m -Xmx384m -XX:ActiveProcessorCount=1"
SERVER_PORT: "8080"
USER_SERVICE_URL: "http://devoops-user-service:8080"
ACCOMMODATION_SERVICE_URL: "http://devoops-accommodation-service:8080"
NOTIFICATION_SERVICE_URL: "http://devoops-notification-service:8080"
RATING_SERVICE_URL: "http://devoops-rating-service:8080"
RESERVATION_SERVICE_URL: "http://devoops-reservation-service:8080"
LOGSTASH_HOST: "devoops-logstash:5000"
ZIPKIN_HOST: "devoops-jaeger"
ZIPKIN_PORT: "9411"

secretData:
JWT_SECRET: "dGhpcyBpcyBhIHZlcnkgc2VjdXJlIGtleSBmb3IgSFMyNTYgdGhhdCBpcyBhdCBsZWFzdCAyNTYgYml0cyBsb25n"
Empty file modified gradlew
100644 → 100755
Empty file.
45 changes: 45 additions & 0 deletions src/main/java/com/devoops/gateway/config/MetricsConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.devoops.gateway.config;

import io.micrometer.common.KeyValue;
import io.micrometer.common.KeyValues;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jspecify.annotations.NonNull;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.observation.DefaultServerRequestObservationConvention;
import org.springframework.http.server.observation.ServerRequestObservationContext;
import org.springframework.http.server.observation.ServerRequestObservationConvention;

import java.util.stream.StreamSupport;

@Configuration
public class MetricsConfig {

@Bean
public ServerRequestObservationConvention serverRequestObservationConvention() {
return new DefaultServerRequestObservationConvention() {
@Override
@NonNull
public KeyValues getLowCardinalityKeyValues(@NonNull ServerRequestObservationContext context) {
KeyValues keyValues = super.getLowCardinalityKeyValues(context);

HttpServletResponse response = context.getResponse();
if (response != null && response.getStatus() == 404) {
HttpServletRequest request = context.getCarrier();
assert request != null;
String originalUri = request.getRequestURI();

KeyValues filtered = KeyValues.of(
StreamSupport.stream(keyValues.spliterator(), false)
.filter(kv -> !"uri".equals(kv.getKey()))
.toArray(KeyValue[]::new)
);
keyValues = filtered.and(KeyValue.of("uri", originalUri));
}

return keyValues;
}
};
}
}
Loading