Code cleanup, introduce event bus tests
This commit is contained in:
parent
139971f459
commit
a47b56a07e
@ -1,72 +0,0 @@
|
|||||||
package io.volvox.td;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
|
|
||||||
import com.fasterxml.jackson.databind.jsontype.NamedType;
|
|
||||||
import it.tdlight.common.Init;
|
|
||||||
import it.tdlight.common.utils.CantLoadLibrary;
|
|
||||||
import it.tdlight.jni.TdApi;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import javax.enterprise.context.ApplicationScoped;
|
|
||||||
|
|
||||||
@ApplicationScoped
|
|
||||||
public class JacksonTdObjectJsonSerializer implements TdObjectJsonSerializer {
|
|
||||||
|
|
||||||
private final ObjectMapper objectMapper;
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
Init.start();
|
|
||||||
} catch (CantLoadLibrary e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public JacksonTdObjectJsonSerializer() {
|
|
||||||
var objectMapper = new ObjectMapper();
|
|
||||||
var validator = BasicPolymorphicTypeValidator.builder();
|
|
||||||
// Iterate TdApi inner classes
|
|
||||||
for (Class<?> declaredClass : TdApi.class.getDeclaredClasses()) {
|
|
||||||
// Register only TDLib objects
|
|
||||||
if (TdApi.Object.class.isAssignableFrom(declaredClass)) {
|
|
||||||
if (Modifier.isAbstract(declaredClass.getModifiers())) {
|
|
||||||
// Register abstract base type
|
|
||||||
|
|
||||||
objectMapper.addMixIn(declaredClass, AbstractTypeMixIn.class);
|
|
||||||
validator.allowIfBaseType(declaredClass);
|
|
||||||
} else {
|
|
||||||
// Register named subtype
|
|
||||||
|
|
||||||
validator.allowIfSubType(declaredClass);
|
|
||||||
objectMapper.registerSubtypes(new NamedType(declaredClass, declaredClass.getSimpleName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.objectMapper = objectMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TdApi.Object deserialize(InputStream json) {
|
|
||||||
try {
|
|
||||||
return objectMapper.readValue(json, TdApi.Object.class);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new UnsupportedOperationException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String serialize(TdApi.Object object) {
|
|
||||||
try {
|
|
||||||
return objectMapper.writeValueAsString(object);
|
|
||||||
} catch (JsonProcessingException e) {
|
|
||||||
throw new UnsupportedOperationException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
|
|
||||||
public abstract static class AbstractTypeMixIn {}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package io.volvox.td;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import javax.enterprise.context.Dependent;
|
|
||||||
|
|
||||||
@Dependent
|
|
||||||
public class RandomUUID {
|
|
||||||
|
|
||||||
final String uuid;
|
|
||||||
|
|
||||||
public RandomUUID() {
|
|
||||||
this.uuid = UUID.randomUUID().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return uuid;
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,6 +6,7 @@ import it.tdlight.jni.TdApi;
|
|||||||
import it.tdlight.jni.TdApi.Update;
|
import it.tdlight.jni.TdApi.Update;
|
||||||
|
|
||||||
public interface TdClient {
|
public interface TdClient {
|
||||||
|
|
||||||
Multi<Update> updates();
|
Multi<Update> updates();
|
||||||
|
|
||||||
<T extends TdApi.Object> Uni<T> send(TdApi.Function<T> function);
|
<T extends TdApi.Object> Uni<T> send(TdApi.Function<T> function);
|
||||||
|
@ -70,9 +70,9 @@ public class TdEventBusClient implements TdClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ConsumeEvent(value = "td.send", codec = TdObjectCodec.class)
|
@ConsumeEvent(value = "td.send", codec = TdObjectCodec.class)
|
||||||
public void onSendRequest(Message<TdObject> msg) {
|
public void onSendRequest(Message<TdObjectCodec.TdObject> msg) {
|
||||||
this.send(msg.body().getObject()).subscribe().with(message -> msg.reply(message, SEND_OPTS), ex -> {
|
this.send(msg.body().getObject()).subscribe().with(message -> msg.reply(message, SEND_OPTS), ex -> {
|
||||||
if (ex instanceof TdException tdException) {
|
if (ex instanceof TelegramException tdException) {
|
||||||
msg.fail(tdException.getCode(), tdException.getMessage());
|
msg.fail(tdException.getCode(), tdException.getMessage());
|
||||||
} else {
|
} else {
|
||||||
msg.fail(500, ex.toString());
|
msg.fail(500, ex.toString());
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package io.volvox.td;
|
package io.volvox.td;
|
||||||
|
|
||||||
import io.quarkus.runtime.StartupEvent;
|
|
||||||
import io.smallrye.mutiny.Multi;
|
import io.smallrye.mutiny.Multi;
|
||||||
import io.smallrye.mutiny.Uni;
|
import io.smallrye.mutiny.Uni;
|
||||||
import it.tdlight.common.ReactiveTelegramClient;
|
import it.tdlight.common.ReactiveTelegramClient;
|
||||||
@ -59,7 +58,7 @@ public class TdNativeClient implements TdClient {
|
|||||||
.transformToUni(item -> {
|
.transformToUni(item -> {
|
||||||
if (item.getConstructor() == Error.CONSTRUCTOR) {
|
if (item.getConstructor() == Error.CONSTRUCTOR) {
|
||||||
TdApi.Error error = (TdApi.Error) item;
|
TdApi.Error error = (TdApi.Error) item;
|
||||||
return Uni.createFrom().failure(new TdException(error.code, error.message));
|
return Uni.createFrom().failure(new TelegramException(error.code, error.message));
|
||||||
} else {
|
} else {
|
||||||
return Uni.createFrom().item(item);
|
return Uni.createFrom().item(item);
|
||||||
}
|
}
|
||||||
@ -75,7 +74,7 @@ public class TdNativeClient implements TdClient {
|
|||||||
.transformToUni(item -> {
|
.transformToUni(item -> {
|
||||||
if (item.getConstructor() == Error.CONSTRUCTOR) {
|
if (item.getConstructor() == Error.CONSTRUCTOR) {
|
||||||
TdApi.Error error = (TdApi.Error) item;
|
TdApi.Error error = (TdApi.Error) item;
|
||||||
return Uni.createFrom().failure(new TdException(error.code, error.message));
|
return Uni.createFrom().failure(new TelegramException(error.code, error.message));
|
||||||
} else {
|
} else {
|
||||||
return Uni.createFrom().item(item);
|
return Uni.createFrom().item(item);
|
||||||
}
|
}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
package io.volvox.td;
|
|
||||||
|
|
||||||
import it.tdlight.jni.TdApi;
|
|
||||||
|
|
||||||
@SuppressWarnings("CdiInjectionPointsInspection")
|
|
||||||
public class TdObject {
|
|
||||||
|
|
||||||
private final TdApi.Object object;
|
|
||||||
|
|
||||||
public TdObject(TdApi.Object object) {
|
|
||||||
this.object = object;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T extends TdApi.Object> T getObject() {
|
|
||||||
//noinspection unchecked
|
|
||||||
return (T) object;
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,10 +5,9 @@ import io.vertx.core.eventbus.MessageCodec;
|
|||||||
import it.tdlight.jni.TdApi;
|
import it.tdlight.jni.TdApi;
|
||||||
import it.tdlight.jni.TdApi.Deserializer;
|
import it.tdlight.jni.TdApi.Deserializer;
|
||||||
import javax.enterprise.context.ApplicationScoped;
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class TdObjectCodec implements MessageCodec<TdObject, TdObject> {
|
public class TdObjectCodec implements MessageCodec<TdObjectCodec.TdObject, TdObjectCodec.TdObject> {
|
||||||
|
|
||||||
@Override public void encodeToWire(Buffer buffer, TdObject t) {
|
@Override public void encodeToWire(Buffer buffer, TdObject t) {
|
||||||
BufferUtils.encode(buffer, out -> t.getObject().serialize(out));
|
BufferUtils.encode(buffer, out -> t.getObject().serialize(out));
|
||||||
@ -33,4 +32,18 @@ public class TdObjectCodec implements MessageCodec<TdObject, TdObject> {
|
|||||||
// Always "-1"
|
// Always "-1"
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class TdObject {
|
||||||
|
|
||||||
|
private final TdApi.Object object;
|
||||||
|
|
||||||
|
public TdObject(TdApi.Object object) {
|
||||||
|
this.object = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends TdApi.Object> T getObject() {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (T) object;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,70 @@
|
|||||||
package io.volvox.td;
|
package io.volvox.td;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
|
||||||
|
import com.fasterxml.jackson.databind.jsontype.NamedType;
|
||||||
|
import it.tdlight.common.Init;
|
||||||
|
import it.tdlight.common.utils.CantLoadLibrary;
|
||||||
import it.tdlight.jni.TdApi;
|
import it.tdlight.jni.TdApi;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
|
||||||
public interface TdObjectJsonSerializer {
|
@ApplicationScoped
|
||||||
|
public class TdObjectJsonSerializer {
|
||||||
|
|
||||||
TdApi.Object deserialize(InputStream json);
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
String serialize(TdApi.Object object);
|
static {
|
||||||
|
try {
|
||||||
|
Init.start();
|
||||||
|
} catch (CantLoadLibrary e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TdObjectJsonSerializer() {
|
||||||
|
var objectMapper = new ObjectMapper();
|
||||||
|
var validator = BasicPolymorphicTypeValidator.builder();
|
||||||
|
// Iterate TdApi inner classes
|
||||||
|
for (Class<?> declaredClass : TdApi.class.getDeclaredClasses()) {
|
||||||
|
// Register only TDLib objects
|
||||||
|
if (TdApi.Object.class.isAssignableFrom(declaredClass)) {
|
||||||
|
if (Modifier.isAbstract(declaredClass.getModifiers())) {
|
||||||
|
// Register abstract base type
|
||||||
|
|
||||||
|
objectMapper.addMixIn(declaredClass, AbstractTypeMixIn.class);
|
||||||
|
validator.allowIfBaseType(declaredClass);
|
||||||
|
} else {
|
||||||
|
// Register named subtype
|
||||||
|
|
||||||
|
validator.allowIfSubType(declaredClass);
|
||||||
|
objectMapper.registerSubtypes(new NamedType(declaredClass, declaredClass.getSimpleName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.objectMapper = objectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TdApi.Object deserialize(InputStream json) {
|
||||||
|
try {
|
||||||
|
return objectMapper.readValue(json, TdApi.Object.class);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UnsupportedOperationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String serialize(TdApi.Object object) {
|
||||||
|
try {
|
||||||
|
return objectMapper.writeValueAsString(object);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new UnsupportedOperationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
|
||||||
|
public abstract static class AbstractTypeMixIn {}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@ import io.quarkus.runtime.ShutdownEvent;
|
|||||||
import io.quarkus.vertx.ConsumeEvent;
|
import io.quarkus.vertx.ConsumeEvent;
|
||||||
import io.vertx.core.eventbus.EventBus;
|
import io.vertx.core.eventbus.EventBus;
|
||||||
import io.vertx.core.eventbus.Message;
|
import io.vertx.core.eventbus.Message;
|
||||||
import it.tdlight.tdnative.NativeClient;
|
|
||||||
import it.tdlight.tdnative.NativeLog;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -29,7 +27,7 @@ public class TdService {
|
|||||||
Instance<TdEventBusClient> sessionInstances;
|
Instance<TdEventBusClient> sessionInstances;
|
||||||
|
|
||||||
@ConsumeEvent(value = "td.start-session")
|
@ConsumeEvent(value = "td.start-session")
|
||||||
private void onStartSession(Message<String> msg) {
|
public void onStartSession(Message<String> msg) {
|
||||||
var sessionId = this.startSession();
|
var sessionId = this.startSession();
|
||||||
msg.reply(sessionId);
|
msg.reply(sessionId);
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,11 @@
|
|||||||
package io.volvox.td;
|
package io.volvox.td;
|
||||||
|
|
||||||
import io.quarkus.runtime.StartupEvent;
|
|
||||||
import io.smallrye.mutiny.Uni;
|
import io.smallrye.mutiny.Uni;
|
||||||
import it.tdlight.jni.TdApi;
|
import it.tdlight.jni.TdApi;
|
||||||
import it.tdlight.jni.TdApi.Function;
|
import it.tdlight.jni.TdApi.Function;
|
||||||
import it.tdlight.jni.TdApi.Object;
|
import it.tdlight.jni.TdApi.Object;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Objects;
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.enterprise.context.Dependent;
|
|
||||||
import javax.enterprise.context.Initialized;
|
|
||||||
import javax.enterprise.event.Observes;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package io.volvox.td;
|
package io.volvox.td;
|
||||||
|
|
||||||
public class TdException extends Exception {
|
public class TelegramException extends Exception {
|
||||||
|
|
||||||
private final int code;
|
private final int code;
|
||||||
private final String message;
|
private final String message;
|
||||||
|
|
||||||
public TdException(int code, String message) {
|
public TelegramException(int code, String message) {
|
||||||
super(code + ": " + message);
|
super(code + ": " + message);
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.message = message;
|
this.message = message;
|
30
service-td/src/test/java/io/volvox/td/TdEventBusTest.java
Normal file
30
service-td/src/test/java/io/volvox/td/TdEventBusTest.java
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package io.volvox.td;
|
||||||
|
|
||||||
|
import io.quarkus.test.junit.QuarkusTest;
|
||||||
|
import io.smallrye.mutiny.Uni;
|
||||||
|
import io.smallrye.mutiny.helpers.test.UniAssertSubscriber;
|
||||||
|
import io.vertx.mutiny.core.eventbus.EventBus;
|
||||||
|
import io.vertx.mutiny.core.eventbus.Message;
|
||||||
|
import java.util.UUID;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@QuarkusTest
|
||||||
|
public class TdEventBusTest {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
EventBus bus;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStartSession() {
|
||||||
|
Uni<String> uni = bus.<String>request("td.start-session", null).map(Message::body);
|
||||||
|
|
||||||
|
UniAssertSubscriber<String> subscriber = uni.subscribe().withSubscriber(UniAssertSubscriber.create());
|
||||||
|
|
||||||
|
String item = subscriber.awaitItem().assertCompleted().getItem();
|
||||||
|
|
||||||
|
Assertions.assertNotNull(item);
|
||||||
|
Assertions.assertDoesNotThrow(() -> UUID.fromString(item));
|
||||||
|
}
|
||||||
|
}
|
@ -1,22 +1,15 @@
|
|||||||
package io.volvox.td;
|
package io.volvox.td;
|
||||||
|
|
||||||
import io.quarkus.test.junit.QuarkusTest;
|
|
||||||
import io.restassured.specification.Argument;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.hamcrest.CoreMatchers;
|
|
||||||
import org.hamcrest.core.IsNot;
|
|
||||||
import org.hamcrest.text.IsEmptyString;
|
|
||||||
import org.hamcrest.text.MatchesPattern;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static io.restassured.RestAssured.given;
|
import static io.restassured.RestAssured.given;
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.CoreMatchers.not;
|
import static org.hamcrest.CoreMatchers.not;
|
||||||
import static org.hamcrest.text.IsEmptyString.emptyOrNullString;
|
import static org.hamcrest.text.IsEmptyString.emptyOrNullString;
|
||||||
|
|
||||||
|
import io.quarkus.test.junit.QuarkusTest;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@QuarkusTest
|
@QuarkusTest
|
||||||
public class TdResourceTest {
|
public class TdResourceTest {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user