aboutsummaryrefslogtreecommitdiffstats
path: root/config-model/src/main/java/com/yahoo/vespa/model/container/http/Http.java
blob: 4eed3628bfd057f06c31daec8f492069d04f5ba3 (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
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.container.http;

import com.yahoo.component.ComponentSpecification;
import com.yahoo.component.provider.ComponentRegistry;
import com.yahoo.config.model.producer.AbstractConfigProducer;
import com.yahoo.container.jdisc.config.HttpServerConfig;
import com.yahoo.jdisc.http.ServerConfig;
import com.yahoo.vespa.model.container.component.chain.Chain;
import com.yahoo.vespa.model.container.component.chain.ChainedComponent;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * Represents the http servers and filters of a Jdisc cluster.
 *
 * @author Tony Vaagenes
 */
public class Http extends AbstractConfigProducer<AbstractConfigProducer<?>>
        implements HttpServerConfig.Producer, ServerConfig.Producer {

    public static class Binding {
        public final ComponentSpecification filterId;
        public final String binding;

        public Binding(ComponentSpecification filterId, String binding) {
            this.filterId = filterId;
            this.binding = binding;
        }
    }

    private FilterChains filterChains;
    private JettyHttpServer httpServer;
    public final List<Binding> bindings;
    private final Optional<AccessControl> accessControl;

    public Http(List<Binding> bindings) {
        this(bindings, null);
    }

    public Http(List<Binding> bindings, AccessControl accessControl) {
        super( "http");
        this.bindings = Collections.unmodifiableList(bindings);
        this.accessControl = Optional.ofNullable(accessControl);
    }

    public void setFilterChains(FilterChains filterChains) {
        this.filterChains = filterChains;
    }

    public FilterChains getFilterChains() {
        return filterChains;
    }

    public JettyHttpServer getHttpServer() {
        return httpServer;
    }

    public void setHttpServer(JettyHttpServer newServer) {
        JettyHttpServer oldServer = this.httpServer;
        this.httpServer = newServer;

        if (oldServer == null && newServer != null) {
            addChild(newServer);
        } else if (newServer == null && oldServer != null) {
            removeChild(oldServer);
        } else if (newServer == null && oldServer == null) {
            //do nothing
        } else {
            //none of them are null
            removeChild(oldServer);
            addChild(newServer);
        }
    }

    public void removeAllServers() {
        setHttpServer(null);
    }

    public List<Binding> getBindings() {
        return bindings;
    }

    public Optional<AccessControl> getAccessControl() {
        return accessControl;
    }

    @Override
    public void getConfig(HttpServerConfig.Builder builder) {
        for (Binding binding: bindings)
            builder.filter(filterBindings(binding));
    }

    @Override
    public void getConfig(ServerConfig.Builder builder) {
        for (final Binding binding : bindings) {
            builder.filter(
                    new ServerConfig.Filter.Builder()
                            .id(binding.filterId.stringValue())
                            .binding(binding.binding));
        }
    }

    static HttpServerConfig.Filter.Builder filterBindings(Binding binding) {
        HttpServerConfig.Filter.Builder builder = new HttpServerConfig.Filter.Builder();
        builder.id(binding.filterId.stringValue()).
                binding(binding.binding);
        return builder;
    }


    @Override
    public void validate() throws Exception {
        validate(bindings);
    }

    void validate(Collection<Binding> bindings) {
        if (!bindings.isEmpty()) {
            if (filterChains == null)
                throw new IllegalArgumentException("Null FilterChains is not allowed when there are filter bindings!");

            ComponentRegistry<ChainedComponent<?>> filters = filterChains.componentsRegistry();
            ComponentRegistry<Chain<Filter>> chains = filterChains.allChains();

            for (Binding binding: bindings) {
                if (filters.getComponent(binding.filterId) == null && chains.getComponent(binding.filterId) == null)
                    throw new RuntimeException("Can't find filter " + binding.filterId + " for binding " + binding.binding);
            }
        }
    }

}