aboutsummaryrefslogtreecommitdiffstats
path: root/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/TenantHandlerTest.java
blob: b39050250f9e076d355ac77babc213387055a0c4 (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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.http.v2;

import com.yahoo.cloud.config.ConfigserverConfig;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.TenantName;
import com.yahoo.container.jdisc.HttpRequestBuilder;
import com.yahoo.jdisc.http.HttpRequest.Method;
import com.yahoo.restapi.RestApiTestDriver;
import com.yahoo.vespa.config.server.ApplicationRepository;
import com.yahoo.vespa.config.server.application.OrchestratorMock;
import com.yahoo.vespa.config.server.session.PrepareParams;
import com.yahoo.vespa.config.server.tenant.TenantRepository;
import com.yahoo.vespa.config.server.tenant.TestTenantRepository;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

import static com.yahoo.jdisc.http.HttpRequest.Method.DELETE;
import static com.yahoo.jdisc.http.HttpRequest.Method.GET;
import static com.yahoo.jdisc.http.HttpRequest.Method.PUT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

public class TenantHandlerTest {

    private static final File testApp = new File("src/test/apps/app");

    private TenantRepository tenantRepository;
    private ApplicationRepository applicationRepository;
    private TenantHandler handler;
    private final TenantName a = TenantName.from("a");

    private RestApiTestDriver testDriver;

    @Rule
    public TemporaryFolder temporaryFolder = new TemporaryFolder();

    @Before
    public void setup() throws IOException {
        ConfigserverConfig configserverConfig = new ConfigserverConfig.Builder()
                .configServerDBDir(temporaryFolder.newFolder().getAbsolutePath())
                .configDefinitionsDir(temporaryFolder.newFolder().getAbsolutePath())
                .fileReferencesDir(temporaryFolder.newFolder().getAbsolutePath())
                .build();
        tenantRepository = new TestTenantRepository.Builder()
                .withConfigserverConfig(configserverConfig)
                .build();
        applicationRepository = new ApplicationRepository.Builder()
                .withTenantRepository(tenantRepository)
                .withOrchestrator(new OrchestratorMock())
                .withConfigserverConfig(configserverConfig)
                .build();
        handler = new TenantHandler(RestApiTestDriver.createHandlerTestContext(), applicationRepository);
        testDriver = RestApiTestDriver.newBuilder(handler).build();
    }

    @After
    public void closeTenantRepo() {
        tenantRepository.close();
    }

    @Test
    public void testTenantCreate() throws Exception {
        assertNull(tenantRepository.getTenant(a));
        assertResponse(PUT, "/application/v2/tenant/a",
                       "{\"message\":\"Tenant a created.\"}");
        assertEquals(a, tenantRepository.getTenant(a).getName());
    }

    @Test
    public void testTenantCreateWithAllPossibleCharactersInName() throws Exception {
        TenantName tenantName = TenantName.from("aB-9999_foo");
        assertNull(tenantRepository.getTenant(tenantName));
        assertResponse(PUT, "/application/v2/tenant/aB-9999_foo",
                       "{\"message\":\"Tenant " + tenantName + " created.\"}");
    }

    @Test
    public void testGetNonExisting() throws IOException {
        assertResponse(GET, "/application/v2/tenant/x",
                       "{\"error-code\":\"NOT_FOUND\",\"message\":\"Tenant 'x' was not found.\"}");
    }

    @Test
    public void testGetAndList() throws Exception {
        tenantRepository.addTenant(a);
        assertResponse(GET, "/application/v2/tenant/a",
                       "{\"message\":\"Tenant 'a' exists.\"}");
        assertResponse(GET, "/application/v2/tenant/",
                       "{\"tenants\":[\"default\",\"a\"]}");
        assertResponse(GET, "/application/v2/tenant",
                       "{\"tenants\":[\"default\",\"a\"]}");
    }

    @Test
    public void testCreateExisting() throws Exception {
        assertNull(tenantRepository.getTenant(a));
        assertResponse(PUT, "/application/v2/tenant/a",
                       "{\"message\":\"Tenant a created.\"}");
        assertEquals(tenantRepository.getTenant(a).getName(), a);
        assertResponse(PUT, "/application/v2/tenant/a",
                       "{\"error-code\":\"BAD_REQUEST\",\"message\":\"There already exists a tenant 'a'\"}");
    }

    @Test
    public void testDelete() throws IOException {
        tenantRepository.addTenant(a);
        assertResponse(DELETE, "/application/v2/tenant/a",
                       "{\"message\":\"Tenant a deleted.\"}");
        assertNull(tenantRepository.getTenant(a));
    }

    @Test
    public void testDeleteTenantWithActiveApplications() throws IOException {
        tenantRepository.addTenant(a);
        ApplicationId applicationId = ApplicationId.from(a, ApplicationName.from("foo"), InstanceName.defaultName());
        applicationRepository.deploy(testApp, new PrepareParams.Builder().applicationId(applicationId).build());

        assertResponse(DELETE, "/application/v2/tenant/a",
                       "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Cannot delete tenant 'a', it has active applications: [a.foo]\"}");
    }

    @Test
    public void testDeleteNonExisting() throws IOException {
        assertResponse(DELETE, "/application/v2/tenant/a",
                       "{\"error-code\":\"NOT_FOUND\",\"message\":\"Tenant 'a' was not found.\"}");
    }

    @Test
    public void testIllegalNameSlashes() throws IOException {
        assertResponse(PUT, "/application/v2/tenant/a/b",
                       "{\"error-code\":\"NOT_FOUND\",\"message\":\"Nothing at '/application/v2/tenant/a/b'\"}");
    }

    private void assertResponse(Method method, String path, String payload) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        testDriver.executeRequest(HttpRequestBuilder.create(method, path).build())
                  .render(baos);
        assertEquals(payload, baos.toString(StandardCharsets.UTF_8));
    }

}