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
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.linkedout.backend.controller

import com.linkedout.backend.model.MessageChannel
import com.linkedout.backend.service.MessageChannelsService
import org.springframework.http.server.reactive.ServerHttpRequest
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import java.security.Principal

@RestController
@RequestMapping("/api/v1/messaging")
class MessagingController(private val messageChannelsService: MessageChannelsService) {
@GetMapping
open fun getMessageChannelsOfUser(request: ServerHttpRequest, principal: Principal): Flux<MessageChannel> {
return messageChannelsService.findAllChannelsOfUser(request.id, principal.name)
}

@GetMapping("/{channelId}")
open fun getMessageChannelOfUser(
request: ServerHttpRequest,
principal: Principal,
@PathVariable channelId: String
): Mono<MessageChannel> {
return messageChannelsService.findOneChannelOfUser(request.id, principal.name, channelId)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.linkedout.backend.model

data class Employer(
val id: String,
val firstName: String,
val lastName: String,
val picture: String,
val phone: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.linkedout.backend.model

data class MessageChannel(
val id: String,
val employer: Employer,
val lastMessage: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class JobCategoryService(private val natsService: NatsService, @Value("\${app.se
throw Exception("Invalid response")
}

val getJobCategoriesResponse = response.getGetJobCategoriesResponse()
val getJobCategoriesResponse = response.getJobCategoriesResponse

return Flux.fromIterable(getJobCategoriesResponse.categoriesList)
.map { jobCategory ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class JobService(private val natsService: NatsService, @Value("\${app.services.j
throw Exception("Invalid response")
}

val getJobsResponse = response.getGetJobsResponse()
val getJobsResponse = response.getJobsResponse

return Flux.fromIterable(getJobsResponse.jobsList)
.map { job ->
Expand All @@ -34,7 +34,6 @@ class JobService(private val natsService: NatsService, @Value("\${app.services.j
.setGetJobRequest(
GetJobRequest.newBuilder()
.setId(id)
.build()
)
.build()

Expand All @@ -45,7 +44,7 @@ class JobService(private val natsService: NatsService, @Value("\${app.services.j
throw Exception("Invalid response")
}

val getJobResponse = response.getGetJobResponse()
val getJobResponse = response.getJobResponse
return Mono.just(Job(getJobResponse.job.id, getJobResponse.job.title, getJobResponse.job.category))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.linkedout.backend.service

import com.linkedout.backend.model.Employer
import com.linkedout.backend.model.MessageChannel
import com.linkedout.common.service.NatsService
import com.linkedout.common.utils.RequestResponseFactory
import com.linkedout.proto.services.Messaging
import com.linkedout.proto.services.Messaging.GetUserMessageChannelsRequest
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono

@Service
class MessageChannelsService(
private val natsService: NatsService,
@Value("\${app.services.messageChannels.subjects.findAllOfUser}") private val findAllOfUsersSubject: String,
@Value("\${app.services.messageChannels.subjects.findOneOfUser}") private val findOneOfUserSubject: String
) {
fun findAllChannelsOfUser(requestId: String, userId: String): Flux<MessageChannel> {
// Request message channels from the messaging service
val request = RequestResponseFactory.newRequest(requestId)
.setGetUserMessageChannelsRequest(
GetUserMessageChannelsRequest.newBuilder()
.setUserId(userId)
)
.build()

val response = natsService.requestWithReply(findAllOfUsersSubject, request)

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

val getUserMessageChannelsResponse = response.getUserMessageChannelsResponse

return Flux.fromIterable(getUserMessageChannelsResponse.messageChannelsList)
.map { messageChannel ->
// TODO: Get the employer from the employer service
MessageChannel(
messageChannel.id,
Employer("<TODO>", "<TODO>", "<TODO>", "<TODO>", "<TODO>"),
messageChannel.lastMessage
)
}
}

fun findOneChannelOfUser(requestId: String, userId: String, channelId: String): Mono<MessageChannel> {
// Request message channel from the messaging service
val request = RequestResponseFactory.newRequest(requestId)
.setGetUserMessageChannelByIdRequest(
Messaging.GetUserMessageChannelByIdRequest.newBuilder()
.setUserId(userId)
.setMessageChannelId(channelId)
)
.build()

val response = natsService.requestWithReply(findOneOfUserSubject, request)

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

val getUserMessageChannelByIdResponse = response.getUserMessageChannelByIdResponse
// TODO: Get the employer from the employer service
return Mono.just(
MessageChannel(
getUserMessageChannelByIdResponse.messageChannel.id,
Employer("<TODO>", "<TODO>", "<TODO>", "<TODO>", "<TODO>"),
getUserMessageChannelByIdResponse.messageChannel.lastMessage
)
)
}
}
4 changes: 4 additions & 0 deletions backend/api_gateway/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ app:
jobCategories:
subjects:
findAll: jobs.findAllCategories
messageChannels:
subjects:
findAllOfUser: messaging.findAllChannelsOfUser
findOneOfUser: messaging.findOneChannelOfUser
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import com.linkedout.proto.models.JobOuterClass
import com.linkedout.proto.services.Jobs
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Component
import java.util.*
import java.util.UUID
import java.util.function.Function

@Component
class GetJob(private val jobService: JobService) : Function<Request, Response> {
override fun apply(t: Request): Response {
// Get the job from the database
val responseMono = jobService.findOneWithCategory(UUID.fromString(t.getGetJobRequest().id))
val responseMono = jobService.findOneWithCategory(UUID.fromString(t.getJobRequest.id))
.map { job ->
JobOuterClass.Job.newBuilder()
.setId(job.id)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.linkedout.jobs
package com.linkedout.messaging

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.linkedout.messaging.function.messageChannels

import com.linkedout.common.utils.RequestResponseFactory
import com.linkedout.messaging.service.MessageChannelService
import com.linkedout.proto.RequestOuterClass.Request
import com.linkedout.proto.ResponseOuterClass.Response
import com.linkedout.proto.models.MessageChannelOuterClass
import com.linkedout.proto.services.Messaging.GetUserMessageChannelByIdResponse
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Component
import java.util.*
import java.util.function.Function

@Component
class GetChannelOfUser(private val messageChannelService: MessageChannelService) : Function<Request, Response> {
override fun apply(t: Request): Response {
// Get the message channel from the database
val request = t.getUserMessageChannelByIdRequest
val responseMono = messageChannelService.findOneWithSeasonworkerId(UUID.fromString(request.userId), UUID.fromString(request.messageChannelId))
.map { messageChannel ->
// TODO: Get the last message
MessageChannelOuterClass.MessageChannel.newBuilder()
.setId(messageChannel.id.toString())
.setEmployerId(messageChannel.employerId.toString())
.setLastMessage("<TODO>")
.build()
}
.map { messageChannel ->
GetUserMessageChannelByIdResponse.newBuilder()
.setMessageChannel(messageChannel)
.build()
}

// Block until the response is ready
val response = try {
responseMono.block()
} catch (e: Exception) {
return RequestResponseFactory.newFailedResponse(e.message ?: "Unknown error").build()
}
?: return RequestResponseFactory.newFailedResponse("Message channel not found", HttpStatus.NOT_FOUND).build()

return RequestResponseFactory.newSuccessfulResponse()
.setGetUserMessageChannelByIdResponse(response)
.build()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.linkedout.messaging.function.messageChannels

import com.linkedout.common.utils.RequestResponseFactory
import com.linkedout.messaging.service.MessageChannelService
import com.linkedout.proto.RequestOuterClass.Request
import com.linkedout.proto.ResponseOuterClass.Response
import com.linkedout.proto.models.MessageChannelOuterClass.MessageChannel
import com.linkedout.proto.services.Messaging.GetUserMessageChannelsResponse
import org.springframework.stereotype.Component
import java.util.UUID
import java.util.function.Function

@Component
class GetChannelsOfUser(private val messageChannelService: MessageChannelService) : Function<Request, Response> {
override fun apply(t: Request): Response {
// Get the message channels from the database
val responseMono = messageChannelService.findAllWithSeasonworkerId(UUID.fromString(t.getUserMessageChannelsRequest.userId))
.map { messageChannel ->
// TODO: Get the last message
MessageChannel.newBuilder()
.setId(messageChannel.id.toString())
.setEmployerId(messageChannel.employerId.toString())
.setLastMessage("<TODO>")
.build()
}
.reduce(GetUserMessageChannelsResponse.newBuilder()) { builder, messageChannel ->
builder.addMessageChannels(messageChannel)
builder
}
.map { builder ->
builder.build()
}

// Block until the response is ready
val response = try {
responseMono.block()
} catch (e: Exception) {
return RequestResponseFactory.newFailedResponse(e.message ?: "Unknown error").build()
}
?: return RequestResponseFactory.newSuccessfulResponse()
.setGetUserMessageChannelsResponse(GetUserMessageChannelsResponse.getDefaultInstance())
.build()

return RequestResponseFactory.newSuccessfulResponse()
.setGetUserMessageChannelsResponse(response)
.build()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.linkedout.messaging.model

import org.springframework.data.annotation.Id
import org.springframework.data.relational.core.mapping.Column
import org.springframework.data.relational.core.mapping.Table
import java.util.UUID

@Table("messagechannel")
data class MessageChannel(
@Id
val id: UUID,
@Column("seasonworkerid")
val seasonworkerId: UUID,
@Column("employerid")
val employerId: UUID
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.linkedout.messaging.repository

import com.linkedout.messaging.model.MessageChannel
import org.springframework.data.r2dbc.repository.Query
import org.springframework.data.repository.reactive.ReactiveCrudRepository
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import java.util.UUID

interface MessageChannelRepository : ReactiveCrudRepository<MessageChannel, UUID> {
@Query(
"""
SELECT * FROM messagechannel
WHERE seasonworkerid = :seasonworkerId
"""
)
fun findAllWithSeasonworkerId(seasonworkerId: UUID): Flux<MessageChannel>

@Query(
"""
SELECT * FROM messagechannel
WHERE seasonworkerid = :seasonworkerId
AND id = :messageChannelId
"""
)
fun findOneWithSeasonworkerId(seasonworkerId: UUID, messageChannelId: UUID): Mono<MessageChannel>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.linkedout.messaging.service

import com.linkedout.messaging.model.MessageChannel
import com.linkedout.messaging.repository.MessageChannelRepository
import org.springframework.stereotype.Service
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import java.util.UUID

@Service
class MessageChannelService(private val messageChannelRepository: MessageChannelRepository) {
fun findAllWithSeasonworkerId(seasonworkerId: UUID): Flux<MessageChannel> {
return messageChannelRepository.findAllWithSeasonworkerId(seasonworkerId)
}

fun findOneWithSeasonworkerId(seasonworkerId: UUID, messageChannelId: UUID): Mono<MessageChannel> {
return messageChannelRepository.findOneWithSeasonworkerId(seasonworkerId, messageChannelId)
}
}
20 changes: 20 additions & 0 deletions backend/messaging/src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1 +1,21 @@
spring.cloud.function.definition=getChannelsOfUser;getChannelOfUser

spring.cloud.stream.bindings.getChannelsOfUser-in-0.destination=messaging.findAllChannelsOfUser
spring.cloud.stream.bindings.getChannelsOfUser-in-0.group=messagingSvc
spring.cloud.stream.bindings.getChannelsOfUser-in-0.binder=nats
spring.cloud.stream.bindings.getChannelsOfUser-in-0.content-type=application/vnd.linkedout.proto-request
spring.cloud.stream.bindings.getChannelsOfUser-out-0.destination=
spring.cloud.stream.bindings.getChannelsOfUser-out-0.group=messagingSvc
spring.cloud.stream.bindings.getChannelsOfUser-out-0.binder=nats
spring.cloud.stream.bindings.getChannelsOfUser-out-0.content-type=application/vnd.linkedout.proto-response

spring.cloud.stream.bindings.getChannelOfUser-in-0.destination=messaging.findOneChannelOfUser
spring.cloud.stream.bindings.getChannelOfUser-in-0.group=messagingSvc
spring.cloud.stream.bindings.getChannelOfUser-in-0.binder=nats
spring.cloud.stream.bindings.getChannelOfUser-in-0.content-type=application/vnd.linkedout.proto-request
spring.cloud.stream.bindings.getChannelOfUser-out-0.destination=
spring.cloud.stream.bindings.getChannelOfUser-out-0.group=messagingSvc
spring.cloud.stream.bindings.getChannelOfUser-out-0.binder=nats
spring.cloud.stream.bindings.getChannelOfUser-out-0.content-type=application/vnd.linkedout.proto-response

nats.spring.server=nats://localhost:4222
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE MessageChannel (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
seasonworkerId UUID NOT NULL,
employerId UUID NOT NULL
);
8 changes: 8 additions & 0 deletions backend/protobuf/src/main/proto/models/messageChannel.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
syntax = "proto3";
package com.linkedout.proto.models;

message MessageChannel {
string id = 1;
string employer_id = 2;
string last_message = 3;
}
Loading