aboutsummaryrefslogtreecommitdiffstats
path: root/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/HttpException.java
blob: 64b1ebe239da77a221e27a9576fc9bb646f67c2c (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
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.node.admin.configserver;

import com.yahoo.vespa.hosted.node.admin.nodeadmin.ConvergenceException;

import javax.ws.rs.core.Response;

/**
 * @author hakonhall
 */
@SuppressWarnings("serial")
public class HttpException extends ConvergenceException {

    private final boolean isRetryable;

    private HttpException(int statusCode, String message, boolean isRetryable) {
        super("HTTP status code " + statusCode + ": " + message, null, !isRetryable);
        this.isRetryable = isRetryable;
    }

    private HttpException(Response.Status status, String message, boolean isRetryable) {
        super(status.toString() + " (" + status.getStatusCode() + "): " + message, null, !isRetryable);
        this.isRetryable = isRetryable;
    }

    boolean isRetryable() {
        return isRetryable;
    }

    /**
     * Returns on success.
     * @throws HttpException for all non-expected status codes.
     */
    static void handleStatusCode(int statusCode, String message) {
        Response.Status status = Response.Status.fromStatusCode(statusCode);
        if (status == null) {
            throw new HttpException(statusCode, message, true);
        }

        switch (status.getFamily()) {
            case SUCCESSFUL: return;
            case CLIENT_ERROR:
                switch (status) {
                    case FORBIDDEN:
                        throw new ForbiddenException(message);
                    case NOT_FOUND:
                        throw new NotFoundException(message);
                    case CONFLICT:
                        // A response body is assumed to be present, and
                        // will later be interpreted as an error.
                        return;
                }
                throw new HttpException(status, message, false);
        }

        // Other errors like server-side errors are assumed to be NOT retryable,
        // in case retries would put additional load on a bogged down server.
        throw new HttpException(status, message, false);
    }

    public static class NotFoundException extends HttpException {
        public NotFoundException(String message) {
            super(Response.Status.NOT_FOUND, message, false);
        }
    }

    public static class ForbiddenException extends HttpException {
        public ForbiddenException(String message) {
            super(Response.Status.FORBIDDEN, message, false);
        }
    }
}