208 lines
7.2 KiB
Java
208 lines
7.2 KiB
Java
package org.lucares.pdbui;
|
|
|
|
import java.io.IOException;
|
|
import java.net.ConnectException;
|
|
import java.net.InetSocketAddress;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.channels.FileChannel;
|
|
import java.nio.channels.SocketChannel;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.StandardOpenOption;
|
|
import java.time.Instant;
|
|
import java.time.OffsetDateTime;
|
|
import java.time.ZoneOffset;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.concurrent.BlockingQueue;
|
|
import java.util.concurrent.LinkedBlockingDeque;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.stream.Collectors;
|
|
|
|
import org.lucares.collections.LongList;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
public class PdbTestUtil {
|
|
private static final Logger LOGGER = LoggerFactory.getLogger(PdbTestUtil.class);
|
|
|
|
static final Map<String, Object> POISON = new HashMap<>();
|
|
|
|
public static final void send(final String format, final Collection<Map<String, Object>> entries, final int port)
|
|
throws IOException, InterruptedException {
|
|
switch (format) {
|
|
case "csv":
|
|
sendAsCsv(entries, port);
|
|
break;
|
|
case "json":
|
|
sendAsJson(entries, port);
|
|
break;
|
|
default:
|
|
throw new IllegalStateException("unhandled format: " + format);
|
|
}
|
|
}
|
|
|
|
@SafeVarargs
|
|
public static final void sendAsCsv(final int port, final Map<String, Object>... entries)
|
|
throws IOException, InterruptedException {
|
|
sendAsCsv(Arrays.asList(entries), port);
|
|
}
|
|
|
|
public static final void sendAsCsv(final Collection<Map<String, Object>> entries, final int port)
|
|
throws IOException, InterruptedException {
|
|
|
|
final Set<String> keys = entries.stream().map(Map::keySet).flatMap(Set::stream).collect(Collectors.toSet());
|
|
|
|
sendAsCsv(keys, entries, port);
|
|
}
|
|
|
|
public static final void sendAsCsv(final Collection<String> keys, final Collection<Map<String, Object>> entries,
|
|
final int port) throws IOException, InterruptedException {
|
|
|
|
final StringBuilder csv = new StringBuilder();
|
|
|
|
csv.append(String.join(",", keys));
|
|
csv.append("\n");
|
|
|
|
for (final Map<String, Object> entry : entries) {
|
|
final List<String> line = new ArrayList<>();
|
|
for (final String key : keys) {
|
|
final String value = String.valueOf(entry.getOrDefault(key, ""));
|
|
line.add(value);
|
|
}
|
|
csv.append(String.join(",", line));
|
|
csv.append("\n");
|
|
}
|
|
System.out.println("sending: " + csv);
|
|
send(csv.toString(), port);
|
|
}
|
|
|
|
@SafeVarargs
|
|
public static final void sendAsJson(final int port, final Map<String, Object>... entries)
|
|
throws IOException, InterruptedException {
|
|
|
|
sendAsJson(Arrays.asList(entries), port);
|
|
}
|
|
|
|
public static final void sendAsJson(final Collection<Map<String, Object>> entries, final int port)
|
|
throws IOException, InterruptedException {
|
|
final LinkedBlockingDeque<Map<String, Object>> queue = new LinkedBlockingDeque<>(entries);
|
|
queue.put(POISON);
|
|
sendAsJson(queue, port);
|
|
}
|
|
|
|
public static final void sendAsJson(final BlockingQueue<Map<String, Object>> aEntriesSupplier, final int port)
|
|
throws IOException {
|
|
|
|
final ObjectMapper mapper = new ObjectMapper();
|
|
final SocketChannel channel = connect(port);
|
|
|
|
Map<String, Object> entry;
|
|
while ((entry = aEntriesSupplier.poll()) != POISON) {
|
|
|
|
final StringBuilder streamData = new StringBuilder();
|
|
streamData.append(mapper.writeValueAsString(entry));
|
|
streamData.append("\n");
|
|
|
|
final ByteBuffer src = ByteBuffer.wrap(streamData.toString().getBytes(StandardCharsets.UTF_8));
|
|
channel.write(src);
|
|
}
|
|
|
|
try {
|
|
// ugly workaround: the channel was closed too early and not all
|
|
// data was received
|
|
TimeUnit.MILLISECONDS.sleep(10);
|
|
} catch (final InterruptedException e) {
|
|
throw new IllegalStateException(e);
|
|
}
|
|
channel.close();
|
|
LOGGER.trace("closed sender connection");
|
|
}
|
|
|
|
public static final void send(final String data, final int port) throws IOException {
|
|
|
|
final SocketChannel channel = connect(port);
|
|
|
|
final StringBuilder streamData = new StringBuilder();
|
|
streamData.append(data);
|
|
|
|
final ByteBuffer src = ByteBuffer.wrap(streamData.toString().getBytes(StandardCharsets.UTF_8));
|
|
channel.write(src);
|
|
|
|
try {
|
|
// ugly workaround: the channel was closed too early and not all
|
|
// data was received
|
|
TimeUnit.MILLISECONDS.sleep(10);
|
|
} catch (final InterruptedException e) {
|
|
throw new IllegalStateException(e);
|
|
}
|
|
channel.close();
|
|
LOGGER.trace("closed sender connection");
|
|
}
|
|
|
|
public static void send(final Path file, final int port) throws IOException {
|
|
final SocketChannel outputChannel = connect(port);
|
|
|
|
try (final FileChannel inputChannel = FileChannel.open(file, StandardOpenOption.READ)) {
|
|
inputChannel.transferTo(0, Long.MAX_VALUE, outputChannel);
|
|
}
|
|
|
|
try {
|
|
// ugly workaround: the channel was closed too early and not all
|
|
// data was received
|
|
TimeUnit.MILLISECONDS.sleep(10);
|
|
} catch (final InterruptedException e) {
|
|
throw new IllegalStateException(e);
|
|
}
|
|
outputChannel.close();
|
|
LOGGER.trace("closed sender connection");
|
|
}
|
|
|
|
private static SocketChannel connect(final int port) throws IOException {
|
|
|
|
SocketChannel result = null;
|
|
|
|
while (true) {
|
|
try {
|
|
result = SocketChannel.open();
|
|
result.configureBlocking(true);
|
|
result.connect(new InetSocketAddress("127.0.0.1", port));
|
|
break;
|
|
} catch (final ConnectException e) {
|
|
// server socket not yet ready, it should be ready any time soon
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public static String timeValueLongListToString(final LongList timeValueLongList) {
|
|
final StringBuilder result = new StringBuilder();
|
|
|
|
int i = 0;
|
|
while (i < timeValueLongList.size()) {
|
|
final OffsetDateTime time = OffsetDateTime.ofInstant(Instant.ofEpochMilli(timeValueLongList.get(i)),
|
|
ZoneOffset.UTC);
|
|
i++;
|
|
final long value = timeValueLongList.get(i);
|
|
i++;
|
|
|
|
result.append(time.format(DateTimeFormatter.ISO_DATE_TIME));
|
|
result.append("=");
|
|
result.append(value);
|
|
result.append("\n");
|
|
}
|
|
|
|
return result.toString();
|
|
}
|
|
|
|
}
|