feat: add metrics for user registrations, logins, challenges, and game writebacks
Build & Test (NowChessSystems) TeamCity build failed
Build & Test (NowChessSystems) TeamCity build failed
This commit is contained in:
@@ -4,6 +4,7 @@ import de.nowchess.account.domain.{BotAccount, OfficialBotAccount, UserAccount}
|
||||
import de.nowchess.account.dto.{LoginRequest, RegisterRequest}
|
||||
import de.nowchess.account.error.AccountError
|
||||
import de.nowchess.account.repository.{BotAccountRepository, OfficialBotAccountRepository, UserAccountRepository}
|
||||
import io.micrometer.core.instrument.MeterRegistry
|
||||
import io.quarkus.elytron.security.common.BcryptUtil
|
||||
import io.smallrye.jwt.build.Jwt
|
||||
import jakarta.enterprise.context.ApplicationScoped
|
||||
@@ -29,11 +30,21 @@ class AccountService:
|
||||
|
||||
@Inject
|
||||
var officialBotAccountRepository: OfficialBotAccountRepository = uninitialized
|
||||
|
||||
@Inject
|
||||
var meterRegistry: MeterRegistry = uninitialized
|
||||
// scalafix:on
|
||||
|
||||
@Transactional
|
||||
def register(req: RegisterRequest): Either[AccountError, UserAccount] =
|
||||
log.infof("Registering user %s", req.username)
|
||||
val result = registerAccount(req)
|
||||
result match
|
||||
case Right(_) => meterRegistry.counter("nowchess.users.registrations", "result", "success").increment()
|
||||
case Left(_) => meterRegistry.counter("nowchess.users.registrations", "result", "failure").increment()
|
||||
result
|
||||
|
||||
private def registerAccount(req: RegisterRequest): Either[AccountError, UserAccount] =
|
||||
if userAccountRepository.findByUsername(req.username).isDefined then Left(AccountError.UsernameTaken(req.username))
|
||||
else if userAccountRepository.findByEmail(req.email).isDefined then
|
||||
Left(AccountError.EmailAlreadyRegistered(req.email))
|
||||
@@ -48,6 +59,15 @@ class AccountService:
|
||||
Right(account)
|
||||
|
||||
def login(req: LoginRequest): Either[AccountError, String] =
|
||||
val result = authenticateUser(req)
|
||||
result match
|
||||
case Right(_) => meterRegistry.counter("nowchess.auth.logins", "result", "success").increment()
|
||||
case Left(error) =>
|
||||
meterRegistry.counter("nowchess.auth.logins", "result", "failure").increment()
|
||||
meterRegistry.counter("nowchess.auth.login.failures", "reason", loginFailureReason(error)).increment()
|
||||
result
|
||||
|
||||
private def authenticateUser(req: LoginRequest): Either[AccountError, String] =
|
||||
userAccountRepository.findByUsername(req.username) match
|
||||
case None =>
|
||||
log.warnf("Login failed for unknown user %s", req.username)
|
||||
@@ -69,6 +89,17 @@ class AccountService:
|
||||
.sign(),
|
||||
)
|
||||
|
||||
private def loginFailureReason(error: AccountError): String = error match
|
||||
case AccountError.InvalidCredentials => "invalid_credentials"
|
||||
case AccountError.UserBanned => "user_banned"
|
||||
case AccountError.UsernameTaken(_) => "username_taken"
|
||||
case AccountError.EmailAlreadyRegistered(_) => "email_registered"
|
||||
case AccountError.UserNotFound => "user_not_found"
|
||||
case AccountError.BotNotFound => "bot_not_found"
|
||||
case AccountError.BotLimitExceeded => "bot_limit_exceeded"
|
||||
case AccountError.NotAuthorized => "not_authorized"
|
||||
case AccountError.BotBanned => "bot_banned"
|
||||
|
||||
def findByUsername(username: String): Option[UserAccount] =
|
||||
userAccountRepository.findByUsername(username)
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import de.nowchess.account.dto.{
|
||||
}
|
||||
import de.nowchess.account.error.ChallengeError
|
||||
import de.nowchess.account.repository.{ChallengeRepository, UserAccountRepository}
|
||||
import io.micrometer.core.instrument.MeterRegistry
|
||||
import jakarta.enterprise.context.ApplicationScoped
|
||||
import jakarta.inject.Inject
|
||||
import jakarta.transaction.Transactional
|
||||
@@ -48,10 +49,22 @@ class ChallengeService:
|
||||
|
||||
@Inject
|
||||
var eventPublisher: EventPublisher = uninitialized
|
||||
|
||||
@Inject
|
||||
var meterRegistry: MeterRegistry = uninitialized
|
||||
// scalafix:on
|
||||
|
||||
@Transactional
|
||||
def create(challengerId: UUID, destUsername: String, req: ChallengeRequest): Either[ChallengeError, Challenge] =
|
||||
val result = createChallenge(challengerId, destUsername, req)
|
||||
result.foreach(_ => meterRegistry.counter("nowchess.challenges.created").increment())
|
||||
result
|
||||
|
||||
private def createChallenge(
|
||||
challengerId: UUID,
|
||||
destUsername: String,
|
||||
req: ChallengeRequest,
|
||||
): Either[ChallengeError, Challenge] =
|
||||
for
|
||||
destUser <- userAccountRepository.findByUsername(destUsername).toRight(ChallengeError.UserNotFound(destUsername))
|
||||
challenger <- userAccountRepository.findById(challengerId).toRight(ChallengeError.ChallengerNotFound)
|
||||
@@ -80,6 +93,11 @@ class ChallengeService:
|
||||
|
||||
@Transactional
|
||||
def accept(challengeId: UUID, userId: UUID): Either[ChallengeError, Challenge] =
|
||||
val result = acceptChallenge(challengeId, userId)
|
||||
result.foreach(_ => meterRegistry.counter("nowchess.challenges.accepted").increment())
|
||||
result
|
||||
|
||||
private def acceptChallenge(challengeId: UUID, userId: UUID): Either[ChallengeError, Challenge] =
|
||||
for
|
||||
challenge <- challengeRepository.findById(challengeId).toRight(ChallengeError.ChallengeNotFound)
|
||||
_ <- Either.cond(challenge.status == ChallengeStatus.Created, (), ChallengeError.ChallengeNotActive)
|
||||
@@ -96,6 +114,11 @@ class ChallengeService:
|
||||
|
||||
@Transactional
|
||||
def decline(challengeId: UUID, userId: UUID, req: DeclineRequest): Either[ChallengeError, Challenge] =
|
||||
val result = declineChallenge(challengeId, userId, req)
|
||||
result.foreach(_ => meterRegistry.counter("nowchess.challenges.declined").increment())
|
||||
result
|
||||
|
||||
private def declineChallenge(challengeId: UUID, userId: UUID, req: DeclineRequest): Either[ChallengeError, Challenge] =
|
||||
for
|
||||
challenge <- challengeRepository.findById(challengeId).toRight(ChallengeError.ChallengeNotFound)
|
||||
_ <- Either.cond(challenge.status == ChallengeStatus.Created, (), ChallengeError.ChallengeNotActive)
|
||||
@@ -109,6 +132,11 @@ class ChallengeService:
|
||||
|
||||
@Transactional
|
||||
def cancel(challengeId: UUID, userId: UUID): Either[ChallengeError, Challenge] =
|
||||
val result = cancelChallenge(challengeId, userId)
|
||||
result.foreach(_ => meterRegistry.counter("nowchess.challenges.cancelled").increment())
|
||||
result
|
||||
|
||||
private def cancelChallenge(challengeId: UUID, userId: UUID): Either[ChallengeError, Challenge] =
|
||||
for
|
||||
challenge <- challengeRepository.findById(challengeId).toRight(ChallengeError.ChallengeNotFound)
|
||||
_ <- Either.cond(challenge.status == ChallengeStatus.Created, (), ChallengeError.ChallengeNotActive)
|
||||
|
||||
Reference in New Issue
Block a user