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

fi.evolver.basics.spring.messaging.util.SendUtils Maven / Gradle / Ivy

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

import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fi.evolver.basics.spring.log.entity.MessageLogMetadata;
import fi.evolver.basics.spring.messaging.entity.Message;
import fi.evolver.basics.spring.util.MessageChainUtils;
import fi.evolver.utils.TagUtils;
import fi.evolver.utils.TagUtils.Tag;
import fi.evolver.utils.UriUtils;


public class SendUtils {
	private static final Logger LOG = LoggerFactory.getLogger(SendUtils.class);

	public static final String PROPERTY_CONNECT_TIMEOUT_MS = "ConnectTimeoutMs";
	public static final String PROPERTY_READ_TIMEOUT_MS = "ReadTimeoutMs";
	private static final String PROPERTY_CHARSET = "Charset";
	private static final String PROPERTY_COMPRESSION = "Compression";


	public enum Compression {
		NONE,
		GZIP,
	}


	private SendUtils() {}


	public static URI updateUri(String uri, Message message) throws URISyntaxException {
		return new URI(TagUtils.replaceTags(uri, createTags(message, UriUtils::encode)));
	}


	public static String replaceTags(String value, Message message) {
		return TagUtils.replaceTags(value, createTags(message, UnaryOperator.identity()));
	}


	public static Map replaceTags(Map values, Message message) {
		if (values.isEmpty())
			return Collections.emptyMap();

		Tag[] tags = createTags(message, UnaryOperator.identity());
		Map results = new LinkedHashMap<>();
		values.forEach((k, v) -> results.put(k, TagUtils.replaceTags(v, tags)));
		return results;
	}


	public static Optional getTagReplacedTargetProperty(Message message, String name) {
		return message.getMessageTargetConfig().getProperty(name)
				.map(p -> replaceTags(p, message));
	}


	private static Tag[] createTags(Message message, UnaryOperator mapper) {
		List tags = new ArrayList<>();
		tags.add(TagUtils.TIMESTAMP);
		tags.add(MessageChainUtils.TAG);
		message.getMetadata().forEach((k, v) -> tags.add(TagUtils.tag(k, mapper.apply(v))));
		return tags.toArray(new Tag[tags.size()]);
	}


	private static Compression inferCompression(Message message) {
		String compression = null;
		try {
			compression = message.getMessageTargetConfig().getProperty(PROPERTY_COMPRESSION).orElse("NONE");
			return Compression.valueOf(compression.toUpperCase());
		}
		catch (IllegalArgumentException e) {
			LOG.warn("Unsupported compression {}. Defaulting to {}", compression, Compression.NONE);
			return Compression.NONE;
		}
	}


	public static List mapMetadata(Map metadata) {
		return metadata.entrySet().stream()
				.filter(e -> e.getKey() != null && e.getValue() != null)
				.map(e -> new MessageLogMetadata(e.getKey(), e.getValue()))
				.collect(Collectors.toList());
	}


	private static Charset inferCharset(Message message) {
		String charsetName = null;
		try {
			charsetName = message.getMessageTargetConfig().getProperty(PROPERTY_CHARSET).orElse("UTF-8");
			return Charset.forName(charsetName);
		}
		catch (Exception e) {
			LOG.warn("Failed parsing character encoding: {}, defaulting to UTF-8", charsetName, e);
			return StandardCharsets.UTF_8;
		}
	}


	public static InputStream createDataStream(Message message) throws IOException {
		Compression compression = inferCompression(message);
		Charset charset = inferCharset(message);
		return handleCompression(transcodeFromUtf8(message.getCompressedStream(), charset), compression);
	}


	public static InputStream transcodeFromUtf8(InputStream in, Charset targetCharset) throws IOException {
		if (StandardCharsets.UTF_8.name().equals(targetCharset.name()))
			return in;

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try (GZIPOutputStream gout = new GZIPOutputStream(baos);
				Writer writer = new OutputStreamWriter(gout, targetCharset);
				Reader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(in), StandardCharsets.UTF_8))) {

			char[] buffer = new char[2028];
			int count;
			while ((count = reader.read(buffer, 0, buffer.length)) > 0)
				writer.write(buffer, 0, count);
		}

		return new ByteArrayInputStream(baos.toByteArray());
	}


	public static InputStream handleCompression(InputStream dataStream, Compression compression) throws IOException {
		switch (compression) {
			case NONE:	return new GZIPInputStream(dataStream);
			case GZIP:	return dataStream;
			default:
				throw new IOException("Unsupported compression method " + compression);
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy