Как опубликовать статическую коллекцию с помощью vertx и quarkus - PullRequest
0 голосов
/ 11 июля 2019

Я создаю приложение с Quarkus и его расширением vert.x. Теперь я хочу создать конечную точку REST, которая должна передавать все сохраненные адреса. Чтобы проверить это без реактивного источника данных, я не хочу создавать ArrayList с примерами адресов и передавать их в потоковом режиме, чтобы я мог проверить, работает ли мой тест. Но я не понимаю, как я могу передать коллекцию.

Мой фактический код:

    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;
      }
    }

А это мой тест:

    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());
      }
    }

Редактировать 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");
      }

И это работает. Таким образом, проблема должна иметь отношение к адресным объектам.

Ответы [ 2 ]

0 голосов
/ 15 июля 2019

Я мог это исправить, я пропустил зависимость:

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>

И мне пришлось конвертировать мои объекты в 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);
      }
    }

Также мой тест был неверным, вот как это выглядит сейчас:

    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());
      }
    }
0 голосов
/ 11 июля 2019

Вы можете использовать что-то вроде

  @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));
  }

Где yourToString - это метод, который создаст правильное строковое представление (возможно, json).

...