summaryrefslogtreecommitdiffstats
path: root/vespa-feed-client/src/test/java/ai/vespa/feed/client/HttpFeedClientTest.java
blob: 6aa0de2160ca7ea644b1b12be500cbd955e54e2d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package ai.vespa.feed.client;

import org.junit.jupiter.api.Test;

import java.net.URI;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
 * @author jonmv
 */
class HttpFeedClientTest {

    @Test
    void testFeeding() throws ExecutionException, InterruptedException {
        DocumentId id = DocumentId.of("ns", "type", "0");
        AtomicReference<BiFunction<DocumentId, HttpRequest, CompletableFuture<HttpResponse>>> dispatch = new AtomicReference<>();
        class MockRequestStrategy implements RequestStrategy {
            @Override public OperationStats stats() { throw new UnsupportedOperationException(); }
            @Override public FeedClient.CircuitBreaker.State circuitBreakerState() { return FeedClient.CircuitBreaker.State.CLOSED; }
            @Override public void destroy() { throw new UnsupportedOperationException(); }
            @Override public void await() { throw new UnsupportedOperationException(); }
            @Override public CompletableFuture<HttpResponse> enqueue(DocumentId documentId, HttpRequest request) { return dispatch.get().apply(documentId, request); }
        }
        FeedClient client = new HttpFeedClient(FeedClientBuilder.create(URI.create("https://dummy:123")), new MockRequestStrategy());

        // Vespa error is an error result.
        dispatch.set((documentId, request) -> {
            try {
                assertEquals(id, documentId);
                assertEquals("/document/v1/ns/type/docid/0?create=true&condition=false&timeout=5000ms&route=route",
                             request.path());
                assertEquals("json", new String(request.body(), UTF_8));

                HttpResponse response = HttpResponse.of(502,
                                                        ("{\n" +
                                                         "  \"pathId\": \"/document/v1/ns/type/docid/0\",\n" +
                                                         "  \"id\": \"id:ns:type::0\",\n" +
                                                         "  \"message\": \"Ooops! ... I did it again.\",\n" +
                                                         "  \"trace\": \"I played with your heart. Got lost in the game.\"\n" +
                                                         "}").getBytes(UTF_8));
                return CompletableFuture.completedFuture(response);
            }
            catch (Throwable thrown) {
                CompletableFuture<HttpResponse> failed = new CompletableFuture<>();
                failed.completeExceptionally(thrown);
                return failed;
            }
        });
        ExecutionException expected = assertThrows(ExecutionException.class,
                                                   () ->  client.put(id,
                                                                     "json",
                                                                     OperationParameters.empty()
                                                                                        .createIfNonExistent(true)
                                                                                        .testAndSetCondition("false")
                                                                                        .route("route")
                                                                                        .timeout(Duration.ofSeconds(5)))
                                                                .get());
        assertTrue(expected.getCause() instanceof ResultException);
        ResultException result = (ResultException) expected.getCause();
        assertEquals("Ooops! ... I did it again.", result.getMessage());
        assertEquals("I played with your heart. Got lost in the game.", result.getTrace().get());


        // Handler error is a FeedException.
        dispatch.set((documentId, request) -> {
            try {
                assertEquals(id, documentId);
                assertEquals("/document/v1/ns/type/docid/0",
                             request.path());
                assertEquals("json", new String(request.body(), UTF_8));

                HttpResponse response = HttpResponse.of(500,
                                                        ("{\n" +
                                                         "  \"pathId\": \"/document/v1/ns/type/docid/0\",\n" +
                                                         "  \"id\": \"id:ns:type::0\",\n" +
                                                         "  \"message\": \"Alla ska i jorden.\",\n" +
                                                         "  \"trace\": \"Din tid den kom, och senn så for den. \"\n" +
                                                         "}").getBytes(UTF_8));
                return CompletableFuture.completedFuture(response);
            }
            catch (Throwable thrown) {
                CompletableFuture<HttpResponse> failed = new CompletableFuture<>();
                failed.completeExceptionally(thrown);
                return failed;
            }
        });
        expected = assertThrows(ExecutionException.class,
                                () -> client.put(id,
                                                 "json",
                                                 OperationParameters.empty())
                                            .get());
        assertEquals("Status 500 executing 'POST /document/v1/ns/type/docid/0': Alla ska i jorden.", expected.getCause().getMessage());
    }

}