aboutsummaryrefslogtreecommitdiffstats
path: root/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/restapi/AkamaiHandlerTest.java
blob: 2814fcff8f7dd15252a0a097b3d05ab8e39bda22 (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
106
107
108
109
110
111
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.routing.restapi;

import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.zone.RoutingMethod;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.container.jdisc.HttpRequestBuilder;
import com.yahoo.container.jdisc.HttpResponse;
import com.yahoo.container.jdisc.ThreadedHttpRequestHandler;
import com.yahoo.vespa.hosted.routing.RoutingTable;
import com.yahoo.vespa.hosted.routing.RoutingTable.Endpoint;
import com.yahoo.vespa.hosted.routing.mock.HealthStatusMock;
import com.yahoo.vespa.hosted.routing.mock.RoutingStatusMock;
import com.yahoo.vespa.hosted.routing.status.HealthStatus;
import com.yahoo.vespa.hosted.routing.status.ServerGroup;
import com.yahoo.yolean.Exceptions;
import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
 * @author oyving
 * @author mpolden
 */
public class AkamaiHandlerTest {

    private static final String
            ENDPOINT_OK = "ok.vespa.yahooapis.com",
            ENDPOINT_UNKNOWN = "unknown.vespa.yahooapis.com",
            ENDPOINT_UNAVAILABLE = "out.vespa.yahooapis.com",
            ENDPOINT_UNHEALTHY = "unhealthy.vespa.yahooapis.com",
            ENDPOINT_INACTIVE = "inactive.vespa.yahooapis.com";

    private static final String ENDPOINT_WITH_PORT_OK = ENDPOINT_OK + ":4080";

    private final RoutingStatusMock statusService = new RoutingStatusMock().setStatus("i3.a3.t3.us-north-1.prod", false);

    private final HealthStatus healthStatus = new HealthStatusMock().setStatus(new ServerGroup(List.of(
            new ServerGroup.Server("i1.a1.t1.us-north-1.prod", "hostport", true),
            new ServerGroup.Server("i2.a2.t2.us-north-1.prod", "hostport", false))));

    private final AkamaiHandler handler = new AkamaiHandler(ThreadedHttpRequestHandler.testContext(),
                                                            () -> Optional.of(makeRoutingTable()),
                                                            statusService,
                                                            healthStatus);

    @Test
    public void ok_endpoint() {
        assertResponse(ENDPOINT_OK, 200, AkamaiHandler.ROTATION_OK_MESSAGE);
        assertResponse(ENDPOINT_WITH_PORT_OK, 200, AkamaiHandler.ROTATION_OK_MESSAGE);
    }

    @Test
    public void unknown_endpoint() {
        assertResponse(ENDPOINT_UNKNOWN, 404, AkamaiHandler.ROTATION_UNKNOWN_MESSAGE);
    }

    @Test
    public void out_of_rotation_endpoint() {
        assertResponse(ENDPOINT_UNAVAILABLE, 404, AkamaiHandler.ROTATION_UNAVAILABLE_MESSAGE);
    }

    @Test
    public void unhealthy_endpoint() {
        assertResponse(ENDPOINT_UNHEALTHY, 502, AkamaiHandler.ROTATION_UNHEALTHY_MESSAGE);
    }

    @Test
    public void inactive_endpoint() {
        assertResponse(ENDPOINT_INACTIVE, 404, AkamaiHandler.ROTATION_INACTIVE_MESSAGE);
    }

    private void assertResponse(String rotation, int status, String message) {
        HttpRequest req = HttpRequestBuilder.create(com.yahoo.jdisc.http.HttpRequest.Method.GET, "/akamai/v1/status")
                                            .withHeader("Host", rotation)
                                            .build();
        HttpResponse response = handler.handle(req);
        assertEquals(status, response.getStatus());
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        Exceptions.uncheck(() -> response.render(out));
        String responseBody = out.toString();

        String expected = "\"message\":\"" + message + "\"";
        assertTrue("Contains expected message", responseBody.contains(expected));
    }

    private static RoutingTable makeRoutingTable() {
        return new RoutingTable(Map.of(
                new Endpoint(ENDPOINT_OK, RoutingMethod.sharedLayer4), createTarget("t1", "a1", "i1", "default", true),
                new Endpoint(ENDPOINT_UNAVAILABLE, RoutingMethod.sharedLayer4), createTarget("t3", "a3", "i3", "default", true),
                new Endpoint(ENDPOINT_UNHEALTHY, RoutingMethod.sharedLayer4), createTarget("t2", "a2", "i2", "default", true),
                new Endpoint(ENDPOINT_INACTIVE, RoutingMethod.sharedLayer4), createTarget("t1", "a1", "i1", "default", false)
        ), 42);
    }

    private static RoutingTable.Target createTarget(String tenantName, String applicationName, String instanceName, String clusterName, boolean routingActive) {
        ZoneId zone = ZoneId.from("prod", "us-north-1");
        ClusterSpec.Id cluster = ClusterSpec.Id.from(clusterName);
        return RoutingTable.Target.create(ApplicationId.from(tenantName, applicationName, instanceName), cluster, zone,
                                          List.of(new RoutingTable.Real("host", 8080, 1, routingActive)));
    }

}