[英]How to publish static collection with vertx and quarkus
I'm building an application with Quarkus and it's vert.x extension. 我正在使用Quarkus及其vert.x扩展名构建应用程序。 Now I want to build a REST endpoint which should stream all saved addresses.
现在,我想构建一个REST端点,该端点应流式传输所有保存的地址。 To test this whiout a reactive data source I wan't to create a ArrayList with example addresses and stream them so I can check if my test works.
为了测试这种反应性数据源,我将不创建带有示例地址的ArrayList并将其流化,以便我可以检查我的测试是否有效。 But I don't find how I can stream a collection.
但是我找不到如何流式传输收藏集的方法。
My actual code: 我的实际代码:
import io.vertx.reactivex.core.Vertx;
import org.reactivestreams.Publisher;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.Collection;
@Path("/addresses")
public class AddressResource {
private Collection<Address> adresses;
@Inject private Vertx vertx;
public AddressResource() {
super();
adresses = new ArrayList<>();
}
@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
public Publisher<Address> get() {
Address address = new Address();
address.setStreet("590 Holly Street");
address.setCity("Townsend");
address.setState("Ohio");
address.setZip(6794);
adresses.add(address);
adresses.add(address);
adresses.add(address);
adresses.add(address);
adresses.add(address);
adresses.add(address);
// What to do here?
return null;
}
}
And this is my test: 这是我的测试:
import io.quarkus.test.junit.QuarkusTest;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import javax.json.bind.JsonbBuilder;
import java.util.ArrayList;
import java.util.List;
import static io.restassured.RestAssured.given;
@QuarkusTest
public class DBServiceTest {
@Test
void testGetAddresses() throws InterruptedException {
given()
.when()
.get("/addresses")
.then()
.statusCode(200)
.body(Matchers.containsInAnyOrder(readTestAdresses().toArray()));
}
private List<Address> readTestAdresses() {
return JsonbBuilder.create()
.fromJson(
this.getClass().getResourceAsStream("test-addresses.json"),
new ArrayList<Address>() {}.getClass().getGenericSuperclass());
}
}
Edit 1: I tried the following: 编辑1:我尝试了以下操作:
@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
public Publisher<String> get() {
Address address = new Address();
address.setStreet("590 Holly Street");
address.setCity("Townsend");
address.setState("Ohio");
address.setZip(6794);
adresses.add(address);
return Flowable.just("Test 1","Test 2","Test 3");
}
And this works. 这可行。 So the problem must have something to do with the address objects.
因此,问题必须与地址对象有关。
You can use something like 您可以使用类似
@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
public Publisher<String> get() {
Address address = new Address();
address.setStreet("590 Holly Street");
address.setCity("Townsend");
address.setState("Ohio");
address.setZip(6794);
return Flowable.just(address, address, address,....).map(a -> yourToString(a));
}
Where yourToString
is a method that will create the proper string representation (json perhaps). 其中
yourToString
是一种将创建正确的字符串表示形式(也许是json)的方法。
I could fix it, I missed a dependency: 我可以解决它,我错过了一个依赖项:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>
And had to convert my objects to json manually and so on change the return type to Publisher<String>
: 并且不得不手动将我的对象转换为json等,将返回类型更改为
Publisher<String>
:
import io.reactivex.Flowable;
import io.vertx.core.json.Json;
import org.reactivestreams.Publisher;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.Collection;
@Path("/addresses")
@Consumes(MediaType.APPLICATION_JSON)
public class AddressResource {
private Collection<Address> addresses;
public AddressResource() {
super();
addresses = new ArrayList<>();
}
@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
public Publisher<String> get() {
Address address = new Address();
address.setStreet("590 Holly Street");
address.setCity("Townsend");
address.setState("Ohio");
address.setZip(6794);
addresses.add(address);
return Flowable.fromIterable(addresses).map(Json::encode);
}
}
Also my test was wrong, this is how it looks like now: 我的测试也是错误的,这是现在的样子:
import io.quarkus.test.common.http.TestHTTPResource;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import javax.json.bind.JsonbBuilder;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.sse.SseEventSource;
import java.net.URL;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import static org.assertj.core.api.Assertions.assertThat;
@QuarkusTest
public class DBServiceTest {
@TestHTTPResource("/addresses")
private URL enpointUrl;
@Test
@DisplayName("Get all addresses")
void testGetAddresses() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(String.valueOf(enpointUrl));
try (SseEventSource source = SseEventSource.target(target).build()) {
CompletableFuture<Collection<Address>> futureAddresses = new CompletableFuture<>();
Set<Address> foundAddresses = new HashSet<>();
source.register(
event -> {
if (!foundAddresses.add(
event.readData(Address.class, MediaType.APPLICATION_JSON_TYPE))) {
futureAddresses.complete(foundAddresses);
}
},
Assertions::fail);
source.open();
Collection<Address> addresses = futureAddresses.join();
assertThat(addresses).containsExactlyInAnyOrderElementsOf(readTestAdresses());
}
}
private List<Address> readTestAdresses() {
return JsonbBuilder.create()
.fromJson(
this.getClass().getResourceAsStream("test-addresses.json"),
new ArrayList<Address>() {}.getClass().getGenericSuperclass());
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.