All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.reactivecommons.async.impl.RabbitDiscardNotifier Maven / Gradle / Ivy

package org.reactivecommons.async.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.java.Log;
import org.reactivecommons.api.domain.DomainEvent;
import org.reactivecommons.api.domain.DomainEventBus;
import org.reactivecommons.async.impl.communications.Message;
import org.reactivecommons.async.impl.exceptions.MessageConversionException;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.util.logging.Level;

import static java.lang.String.format;

@Log
public class RabbitDiscardNotifier implements DiscardNotifier {

    private final DomainEventBus eventBus;
    private final ObjectMapper objectMapper;

    public RabbitDiscardNotifier(DomainEventBus eventBus, ObjectMapper objectMapper) {
        this.eventBus = eventBus;
        this.objectMapper = objectMapper;
    }

    @Override
    public Mono notifyDiscard(Message message) {
        try {
            return notify(message).onErrorResume(this::onError);
        }catch (Exception e){
            return onError(e);
        }
    }

    private Mono notify(Message message){
        try {
            JsonSkeleton node = readSkeleton(message);
            return Mono.from(eventBus.emit(createEvent(node)));
        } catch (MessageConversionException e) {
            return notifyUnreadableMessage(message, e);
        }
    }

    private Mono notifyUnreadableMessage(Message message, MessageConversionException e) {
        String bodyString;
        try{
            bodyString = new String(message.getBody());
        }catch (Exception ex){
            bodyString = "Opaque binary Message, unable to decode: " + ex.getMessage();
        }
        log.log(Level.SEVERE, format("Unable to interpret discarded message: %s", bodyString), e);
        DomainEvent event = new DomainEvent<>("corruptData.dlq", "corruptData", bodyString);
        return Mono.from(eventBus.emit(event));
    }

    private Mono onError(Throwable e){
        log.log(Level.SEVERE, "FATAL!! unable to notify Discard of message!!", e);
        return Mono.empty();
    }

    private JsonSkeleton readSkeleton(Message message) {
        try {
            return objectMapper.readValue(message.getBody(), JsonSkeleton.class);
        } catch (IOException e) {
            throw new MessageConversionException(e);
        }
    }


    private DomainEvent createEvent(JsonSkeleton skeleton) {
        if (skeleton.isCommand()) {
            return new DomainEvent<>(skeleton.name+".dlq", skeleton.commandId, skeleton.data);
        } else if (skeleton.isEvent()) {
            return new DomainEvent<>(skeleton.name+".dlq", skeleton.eventId, skeleton.data);
        } else if (skeleton.isQuery()) {
            return new DomainEvent<>(skeleton.resource+".dlq", skeleton.resource+"query", skeleton.queryData);
        } else {
            throw new MessageConversionException("Fail to math message type");
        }
    }

    @Data
    private static class JsonSkeleton {
        private String name;
        private String resource;
        private String eventId;
        private JsonNode data;
        private JsonNode queryData;
        private String commandId;

        public boolean isEvent() {
            return !empty(eventId) && !empty(name) && data != null;
        }

        public boolean isCommand() {
            return !empty(commandId) && !empty(name) && data != null;
        }

        public boolean isQuery() {
            return  !empty(resource) && queryData != null;
        }

        private boolean empty(String str) {
            return str == null || str.trim().isEmpty();
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy