<commit_before>package ox.softeng.burst.grails.plugin

import com.budjb.rabbitmq.publisher.RabbitMessagePublisher
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.MessageSource
import org.springframework.validation.Errors
import ox.softeng.burst.domain.Severity
import ox.softeng.burst.grails.plugin.exception.BurstException
import ox.softeng.burst.services.MessageDTO

import javax.xml.bind.JAXB
import java.time.OffsetDateTime
import java.time.ZoneId

class BurstService {

    static transactional = false

    Logger logger = LoggerFactory.getLogger(BurstService)

    @Autowired
    RabbitMessagePublisher rabbitMessagePublisher

    @Value('${info.app.name}')
    String appName

    MessageSource messageSource

    void broadcastMessage(MessageDTO message) {

        StringWriter writer = new StringWriter()
        JAXB.marshal(message, writer)

        logger.info("Broadcasting BuRST message")
        logger.debug("{}", message)
        rabbitMessagePublisher.send {
            routingKey = 'burst'
            body = writer.toString()
        }
    }

    void broadcastMessage(@DelegatesTo(MessageDTO) Closure<MessageDTO> closure) {
        broadcastMessage(new MessageDTO().with(closure))
    }

    void broadcastException(BurstException ex, List<String> topics, Map<String, String> metadataMap = [:]) {
        broadcastException(ex, appName, topics, metadataMap)
    }

    void broadcastException(BurstException ex, String source, List<String> topics, Map<String, String> metadataMap = [:]) {
        broadcastMessage {
            it.dateTimeCreated = OffsetDateTime.now(ZoneId.of('UTC'))
            it.severity = Severity.CRITICAL
            it.details = ex.getMessage()
            it.source = source
            it.topics = topics
            metadataMap.each {k, v ->
                it.addToMetadata(k, v ?: 'unknown')
            }
            it
        }
    }

    void broadcastErrors(Errors errors, String errorCode, List<String> topics, Map<String, String> metadataMap = [:]) {
        broadcastErrors(errors, errorCode, appName, topics, metadataMap)
    }

    void broadcastErrors(Errors errors, String errorCode, String source, List<String> topics, Map<String, String> metadataMap = [:]) {
        String details = "$errorCode - Errors while trying to process a '${errors.objectName}' resource::\n"

        errors.allErrors.each {error ->
            details += "  ${messageSource.getMessage(error, Locale.default)}\n"
        }

        broadcastMessage {
            it.dateTimeCreated = OffsetDateTime.now(ZoneId.of('UTC'))
            it.severity = Severity.ERROR
            it.details = details
            it.source = source
            it.topics = topics<commit_msg>Improve service error handling message<commit_after>package ox.softeng.burst.grails.plugin

import com.budjb.rabbitmq.publisher.RabbitMessagePublisher
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.MessageSource
import org.springframework.validation.Errors
import ox.softeng.burst.domain.Severity
import ox.softeng.burst.grails.plugin.exception.BurstException
import ox.softeng.burst.services.MessageDTO

import javax.xml.bind.JAXB
import java.time.OffsetDateTime
import java.time.ZoneId

class BurstService {

    static transactional = false

    Logger logger = LoggerFactory.getLogger(BurstService)

    @Autowired
    RabbitMessagePublisher rabbitMessagePublisher

    @Value('${info.app.name}')
    String appName

    MessageSource messageSource

    void broadcastMessage(MessageDTO message) {

        StringWriter writer = new StringWriter()
        JAXB.marshal(message, writer)

        logger.info("Broadcasting BuRST message")
        logger.debug("{}", message)
        rabbitMessagePublisher.send {
            routingKey = 'burst'
            body = writer.toString()
        }
    }

    void broadcastMessage(@DelegatesTo(MessageDTO) Closure<MessageDTO> closure) {
        broadcastMessage(new MessageDTO().with(closure))
    }

    void broadcastException(BurstException ex, List<String> topics, Map<String, String> metadataMap = [:]) {
        broadcastException(ex, appName, topics, metadataMap)
    }

    void broadcastException(BurstException ex, String source, List<String> topics, Map<String, String> metadataMap = [:]) {
        broadcastMessage {
            it.dateTimeCreated = OffsetDateTime.now(ZoneId.of('UTC'))
            it.severity = Severity.CRITICAL
            it.details = ex.getMessage()
            it.source = source
            it.topics = topics
            metadataMap.each {k, v ->
                it.addToMetadata(k, v ?: 'unknown')
            }
            it
        }
    }

    void broadcastErrors(Errors errors, String errorCode, List<String> topics, Map<String, String> metadataMap = [:]) {
        broadcastErrors(errors, errorCode, appName, topics, metadataMap)
    }

    void broadcastErrors(Errors errors, String errorCode, String source, List<String> topics, Map<String, String> metadataMap = [:]) {
        String details = "$errorCode - Errors while trying to process '${errors.objectName}' resource::\n"

        errors.allErrors.each {error ->
            details += "  ${messageSource.getMessage(error, Locale.default)}\n"
        }

        broadcastMessage {
            it.dateTimeCreated = OffsetDateTime.now(ZoneId.of('UTC'))
            it.severity = Severity.ERROR
            it.details = details
            it.source = source
            it.topics = topics
{'fraction_non_alphanumeric': 0.09838905248570934, 'fraction_numerical': 0.0006928806513078123, 'mean_word_length': 3.0152990264255912, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3877510', 'n_tokens_mistral': 1610, 'n_tokens_neox': 1560, 'n_words': 328}