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
2 changes: 2 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ ARG SERVICE_NAME
WORKDIR /app

COPY ./$SERVICE_NAME ./$SERVICE_NAME
COPY ./common ./common
COPY ./protobuf ./protobuf
COPY ./gradle ./gradle
COPY ./gradle.properties .
COPY ./gradlew .
Expand Down
88 changes: 0 additions & 88 deletions backend/api_gateway/HELP.md

This file was deleted.

13 changes: 8 additions & 5 deletions backend/api_gateway/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@ repositories {
}

dependencies {
implementation("org.springframework.boot:spring-boot-starter-actuator:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-security:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-validation:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-web:3.1.5")
implementation(project(":common"))
implementation(project(":protobuf"))
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("io.nats:jnats:2.17.1")
developmentOnly("org.springframework.boot:spring-boot-devtools")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.boot:spring-boot-testcontainers")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.linkedout.backend
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication

@SpringBootApplication
@SpringBootApplication(scanBasePackages = ["com.linkedout"])
open class ApiGatewayApplication

fun main(args: Array<String>) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.linkedout.backend.controller

import com.linkedout.backend.model.Job
import com.linkedout.backend.service.JobService
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/v1/jobs")
open class JobsController(private val jobService: JobService) {
@GetMapping
open fun getJobs(): List<Job> {
return jobService.findAll()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.linkedout.backend.model

data class Job(
val id: String,
val title: String,
val category: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.linkedout.backend.service

import com.linkedout.backend.model.Job
import com.linkedout.common.service.NatsService
import com.linkedout.common.utils.RequestResponseFactory
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service

@Service
class JobService(private val natsService: NatsService, @Value("\${app.services.jobs.subjects.findAll}") private val findAllSubject: String) {
fun findAll(): List<Job> {
// Request jobs from the jobs service
val response = natsService.requestWithReply(findAllSubject, RequestResponseFactory.newRequest().build())

// Handle the response
if (!response.hasGetJobsResponse()) {
throw Exception("Invalid response")
}

val getJobsResponse = response.getGetJobsResponse()

return getJobsResponse.jobsList
.map { job ->
Job(job.id, job.title, job.category)
}
}
}
11 changes: 11 additions & 0 deletions backend/api_gateway/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,14 @@ spring:

server:
port: 9090

nats:
timeout: 1000
spring:
server: nats://localhost:4222

app:
services:
jobs:
subjects:
findAll: jobs.findAll
47 changes: 47 additions & 0 deletions backend/common/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.springframework.boot.gradle.tasks.bundling.BootJar

plugins {
`java-library`
id("org.springframework.boot")
id("io.spring.dependency-management")
id("org.jlleitschuh.gradle.ktlint")
kotlin("jvm")
kotlin("plugin.spring")
kotlin("plugin.jpa")
}

group = "com.linkedout"
version = "1.0.0-SNAPSHOT"

java {
sourceCompatibility = JavaVersion.VERSION_17
}

repositories {
mavenCentral()
}

dependencies {
implementation(project(":protobuf"))
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework:spring-messaging")
implementation("io.nats:jnats:2.17.1")
implementation("com.google.protobuf:protobuf-kotlin:3.25.0")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict"
jvmTarget = "17"
}
}

tasks.withType<Test> {
useJUnitPlatform()
}

tasks.getByName<BootJar>("bootJar") {
enabled = false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.linkedout.common.service

import com.linkedout.proto.RequestOuterClass.Request
import com.linkedout.proto.ResponseOuterClass.Response
import io.nats.client.Connection
import io.nats.client.Nats
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Lazy
import org.springframework.stereotype.Service
import java.time.Duration

@Service
@Lazy
class NatsService(@Value("\${nats.spring.server}") private val natsUrl: String, @Value("\${nats.timeout}") private val natsTimeout: Long) {
val nc: Connection = Nats.connect(natsUrl)
val timeout: Duration = Duration.ofMillis(natsTimeout)

fun requestWithReply(subject: String, request: Request): Response {
val rawResponse = nc.request(subject, request.toByteArray(), timeout)
val response = Response.parseFrom(rawResponse.data)

if (!response.success) {
throw Exception(response.errorMessage)
}

return response
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.linkedout.common.stream.converter

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.messaging.converter.MessageConverter

@Configuration
class ConverterConfiguration {
@Bean
fun requestConverter(): MessageConverter {
return RequestConverter()
}

@Bean
fun responseConverter(): MessageConverter {
return ResponseConverter()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.linkedout.common.stream.converter

import com.linkedout.proto.RequestOuterClass
import org.springframework.messaging.Message
import org.springframework.messaging.converter.AbstractMessageConverter
import org.springframework.util.MimeType

class RequestConverter : AbstractMessageConverter(MimeType("application", "vnd.linkedout.proto-request")) {
override fun supports(clazz: Class<*>): Boolean {
return RequestOuterClass.Request::class.java == clazz
}

override fun convertFromInternal(message: Message<*>, targetClass: Class<*>, conversionHint: Any?): Any? {
val payload = message.payload
return payload as? RequestOuterClass.Request ?: RequestOuterClass.Request.parseFrom(payload as ByteArray)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.linkedout.common.stream.converter

import com.linkedout.proto.ResponseOuterClass
import org.springframework.messaging.MessageHeaders
import org.springframework.messaging.converter.AbstractMessageConverter
import org.springframework.util.MimeType

class ResponseConverter : AbstractMessageConverter(MimeType("application", "vnd.linkedout.proto-response")) {
override fun supports(clazz: Class<*>): Boolean {
return ResponseOuterClass.Response::class.java == clazz
}

override fun convertToInternal(payload: Any, headers: MessageHeaders?, conversionHint: Any?): Any? {
return (payload as ResponseOuterClass.Response).toByteArray()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.linkedout.common.utils

import com.linkedout.proto.RequestOuterClass
import com.linkedout.proto.ResponseOuterClass
import java.util.UUID

class RequestResponseFactory private constructor() {
companion object {
fun newRequest(): RequestOuterClass.Request.Builder {
return RequestOuterClass.Request.newBuilder()
.setRequestId(UUID.randomUUID().toString())
}

fun newSuccessfulResponse(): ResponseOuterClass.Response.Builder {
return ResponseOuterClass.Response.newBuilder()
.setSuccess(true)
}

fun newFailedResponse(message: String): ResponseOuterClass.Response.Builder {
return ResponseOuterClass.Response.newBuilder()
.setSuccess(false)
.setErrorMessage(message)
}
}
}
19 changes: 13 additions & 6 deletions backend/jobs/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,26 @@ repositories {
}

dependencies {
implementation("org.springframework.boot:spring-boot-starter-actuator:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-data-r2dbc:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-validation:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-webflux:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-web:3.1.5")
implementation("org.springframework:spring-jdbc:6.0.13")
implementation(project(":common"))
implementation(project(":protobuf"))
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework:spring-jdbc")
implementation("org.springframework.cloud:spring-cloud-stream:4.0.4")
implementation("io.nats:jnats:2.17.1")
implementation("io.nats:nats-spring:0.5.6")
implementation("io.nats:nats-spring-cloud-stream-binder:0.5.3")
implementation("org.flywaydb:flyway-core:9.22.3")
implementation("org.postgresql:r2dbc-postgresql:1.0.2.RELEASE")
implementation("jakarta.validation:jakarta.validation-api:3.0.2")
implementation("org.jetbrains.kotlin:kotlin-reflect:1.9.20")
developmentOnly("org.springframework.boot:spring-boot-devtools")
runtimeOnly("org.postgresql:postgresql")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.cloud:spring-cloud-stream-test-binder:4.0.4")
}

tasks.withType<KotlinCompile> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.linkedout.jobs
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
@SpringBootApplication(scanBasePackages = ["com.linkedout"])
class JobsApplication

fun main(args: Array<String>) {
Expand Down
Loading