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

fi.evolver.basics.spring.messaging.entity.Message Maven / Gradle / Ivy

package fi.evolver.basics.spring.messaging.entity;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.Instant;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;

import fi.evolver.basics.spring.util.MessageChainUtils;
import jakarta.persistence.*;


@Entity
@Table(name="message")
public class Message {

	public enum MessageState {
		DELAYED,
		PENDING,
		SENDING,
		SENT,
		FAILED,
		DISABLED,
	}


	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private long id;

	@Column(name="state")
	@Enumerated(EnumType.STRING)
	private MessageState state;

	@Column(name="message_chain_id")
	private Long messageChainId;

	@Column(name="creation_time")
	private Long creationTime;

	@Column(name="last_updated_time")
	private Long lastUpdatedTime;

	@Column(name="fail_count")
	private Integer failCount;

	@Column(name="message_group_id")
	private String messageGroupId;

	@Column(name="priority")
	private Long priority;

	@ManyToOne
	@JoinColumn(name="message_target_config_id")
	private MessageTargetConfig messageTargetConfig;

	@ManyToOne(cascade=CascadeType.PERSIST)
	@JoinColumn(name="message_data_id")
	private MessageData messageData;


	Message() { }

	public Message(MessageTargetConfig target, MessageData messageData, String messageGroupId, Long priority) {
		this.state = target.getThrottling() != null ? MessageState.DELAYED : MessageState.PENDING;
		this.messageChainId = MessageChainUtils.getMessageChainId();
		this.creationTime = Instant.now().toEpochMilli();
		this.lastUpdatedTime = this.creationTime;
		this.failCount = 0;
		this.messageTargetConfig = target;
		this.messageData = messageData;
		this.messageGroupId = messageGroupId;
		this.priority = priority;
	}


	public Message(MessageData messageData) {
		this.messageData = messageData;
	}


	public long getId() {
		return id;
	}

	public byte[] getCompressedData() {
		return messageData.getCompressedData();
	}

	public InputStream getCompressedStream() {
		return new ByteArrayInputStream(getCompressedData());
	}

	public InputStream getDataStream() throws IOException {
		return new GZIPInputStream(getCompressedStream());
	}

	public Instant getCreationTime() {
		return Instant.ofEpochMilli(creationTime);
	}

	public Integer getFailCount() {
		return failCount;
	}

	public Instant getLastUpdatedTime() {
		return Instant.ofEpochMilli(lastUpdatedTime);
	}

	public Long getMessageChainId() {
		return messageChainId;
	}

	public String getMessageGroupId() {
		return messageGroupId;
	}

	public MessageTargetConfig getMessageTargetConfig() {
		return messageTargetConfig;
	}

	public Long getPriority() {
		return priority;
	}

	public MessageState getState() {
		return state;
	}


	public void failure() {
		++failCount;
		setState(Optional.ofNullable(messageTargetConfig.getRetryLimit())
				.map(limit -> failCount > limit ? MessageState.FAILED : MessageState.PENDING)
				.orElse(MessageState.PENDING));
	}

	public void setState(MessageState state) {
		this.state = state;
		this.lastUpdatedTime = Instant.now().toEpochMilli();
	}


	public String getTargetUri() {
		return messageTargetConfig.getUri();
	}

	public Map getMetadata() {
		return messageData.getMetadata().stream().collect(Collectors.toMap(
				MessageMetadata::getKey,
				MessageMetadata::getValue,
				(u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); },
				LinkedHashMap::new));
	}


	public String getMessageType() {
		return messageTargetConfig.getMessageType();
	}

	public String getTargetSystem() {
		return messageTargetConfig.getTargetSystem();
	}


	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append(String.format("%s: %s (%s)", id, messageTargetConfig, state));
		getMetadata().entrySet().stream()
				.map(e -> String.format("\n  %s=%s", e.getKey(), e.getValue()))
				.forEach(builder::append);
		return builder.toString();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy