aboutsummaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2020-11-18 12:37:35 +0100
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2020-11-18 12:37:35 +0100
commitf0a6e9ec11836851e3029ca5f63b93243484059a (patch)
treefd2c9a63b27e88a12b2c7195ae9e08aedbec27f3 /config-model
parent337116886cdd4ab59c79a09e87316e3d29185386 (diff)
Support default request/response filter chain per connector
Diffstat (limited to 'config-model')
-rw-r--r--config-model/pom.xml5
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/Container.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/http/ConnectorFactory.java65
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/http/Http.java16
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyConnectorBuilder.java11
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/http/DefaultFilterTest.java69
7 files changed, 158 insertions, 12 deletions
diff --git a/config-model/pom.xml b/config-model/pom.xml
index c0751431d03..56517b63884 100644
--- a/config-model/pom.xml
+++ b/config-model/pom.xml
@@ -46,6 +46,11 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf.version}</version>
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java b/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java
index a7f5398c7b5..e8b56a6190a 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java
@@ -172,7 +172,7 @@ public abstract class Container extends AbstractService implements
}
private void initDefaultJettyConnector() {
- defaultHttpServer.addConnector(new ConnectorFactory("SearchServer", getSearchPort()));
+ defaultHttpServer.addConnector(new ConnectorFactory.Builder("SearchServer", getSearchPort()).build());
}
private ContainerServiceType myServiceType = null;
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ConnectorFactory.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ConnectorFactory.java
index 2633fa958eb..9eab99af4d0 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ConnectorFactory.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ConnectorFactory.java
@@ -9,6 +9,8 @@ import com.yahoo.vespa.model.container.component.SimpleComponent;
import com.yahoo.vespa.model.container.http.ssl.DefaultSslProvider;
import com.yahoo.vespa.model.container.http.ssl.SslProvider;
+import java.util.Optional;
+
import static com.yahoo.component.ComponentSpecification.fromString;
/**
@@ -21,21 +23,29 @@ public class ConnectorFactory extends SimpleComponent implements ConnectorConfig
private final String name;
private final int listenPort;
private final SslProvider sslProviderComponent;
+ private volatile ComponentId defaultRequestFilterChain;
+ private volatile ComponentId defaultResponseFilterChain;
- public ConnectorFactory(String name, int listenPort) {
- this(name, listenPort, new DefaultSslProvider(name));
+ protected ConnectorFactory(String name, int listenPort, SslProvider sslProviderComponent) {
+ this(name, listenPort, sslProviderComponent, null, null);
}
- public ConnectorFactory(String name,
- int listenPort,
- SslProvider sslProviderComponent) {
+ protected ConnectorFactory(
+ String name,
+ int listenPort,
+ SslProvider sslProviderComponent,
+ ComponentId defaultRequestFilterChain,
+ ComponentId defaultResponseFilterChain) {
super(new ComponentModel(
- new BundleInstantiationSpecification(new ComponentId(name),
- fromString("com.yahoo.jdisc.http.server.jetty.ConnectorFactory"),
- fromString("jdisc_http_service"))));
+ new BundleInstantiationSpecification(
+ new ComponentId(name),
+ fromString("com.yahoo.jdisc.http.server.jetty.ConnectorFactory"),
+ fromString("jdisc_http_service"))));
this.name = name;
this.listenPort = listenPort;
this.sslProviderComponent = sslProviderComponent;
+ this.defaultRequestFilterChain = defaultRequestFilterChain;
+ this.defaultResponseFilterChain = defaultResponseFilterChain;
addChild(sslProviderComponent);
inject(sslProviderComponent);
}
@@ -55,4 +65,43 @@ public class ConnectorFactory extends SimpleComponent implements ConnectorConfig
return listenPort;
}
+ public Optional<ComponentId> getDefaultRequestFilterChain() { return Optional.ofNullable(defaultRequestFilterChain); }
+
+ public Optional<ComponentId> getDefaultResponseFilterChain() { return Optional.ofNullable(defaultResponseFilterChain); }
+
+ public void setDefaultRequestFilterChain(ComponentId filterChain) { this.defaultRequestFilterChain = filterChain; }
+
+ public void setDefaultResponseFilterChain(ComponentId filterChain) { this.defaultResponseFilterChain = filterChain; }
+
+ public static class Builder {
+ private final String name;
+ private final int listenPort;
+
+ private SslProvider sslProvider;
+ private ComponentId defaultRequestFilterChain;
+ private ComponentId defaultResponseFilterChain;
+
+ public Builder(String name, int listenPort) {
+ this.name = name;
+ this.listenPort = listenPort;
+ }
+
+ public Builder setSslProvider(SslProvider sslProvider) {
+ this.sslProvider = sslProvider; return this;
+ }
+
+ public Builder setDefaultRequestFilterChain(ComponentId filterChain) {
+ this.defaultRequestFilterChain = filterChain; return this;
+ }
+
+ public Builder setDefaultResponseFilterChain(ComponentId filterChain) {
+ this.defaultResponseFilterChain = filterChain;
+ return this;
+ }
+
+ public ConnectorFactory build() {
+ SslProvider sslProvider = this.sslProvider != null ? this.sslProvider : new DefaultSslProvider(name);
+ return new ConnectorFactory(name, listenPort, sslProvider, defaultRequestFilterChain, defaultResponseFilterChain);
+ }
+ }
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/Http.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/Http.java
index f58f5faa382..1ed043857e2 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/Http.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/Http.java
@@ -79,6 +79,7 @@ public class Http extends AbstractConfigProducer<AbstractConfigProducer<?>> impl
.id(binding.chainId().stringValue())
.binding(binding.binding().patternString()));
}
+ populateDefaultFiltersConfig(builder, httpServer);
}
@Override
@@ -96,4 +97,19 @@ public class Http extends AbstractConfigProducer<AbstractConfigProducer<?>> impl
throw new RuntimeException("Can't find filter " + binding.chainId() + " for binding " + binding.binding());
}
}
+
+ private static void populateDefaultFiltersConfig(ServerConfig.Builder builder, JettyHttpServer httpServer) {
+ if (httpServer != null) {
+ for (ConnectorFactory connector : httpServer.getConnectorFactories()) {
+ connector.getDefaultRequestFilterChain().ifPresent(
+ filterChain -> builder.defaultFilters(new ServerConfig.DefaultFilters.Builder()
+ .filterId(filterChain.stringValue())
+ .localPort(connector.getListenPort())));
+ connector.getDefaultResponseFilterChain().ifPresent(
+ filterChain -> builder.defaultFilters(new ServerConfig.DefaultFilters.Builder()
+ .filterId(filterChain.stringValue())
+ .localPort(connector.getListenPort())));
+ }
+ }
+ }
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyConnectorBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyConnectorBuilder.java
index 505cc81c0cb..9f25550418e 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyConnectorBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyConnectorBuilder.java
@@ -1,6 +1,7 @@
// 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.xml;
+import com.yahoo.component.ComponentId;
import com.yahoo.config.model.builder.xml.XmlHelper;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.producer.AbstractConfigProducer;
@@ -30,9 +31,15 @@ public class JettyConnectorBuilder extends VespaDomBuilder.DomConfigProducerBuil
protected ConnectorFactory doBuild(DeployState deployState, AbstractConfigProducer ancestor, Element serverSpec) {
String name = XmlHelper.getIdString(serverSpec);
int port = HttpBuilder.readPort(new ModelElement(serverSpec), deployState.isHosted(), deployState.getDeployLogger());
-
+ ConnectorFactory.Builder builder = new ConnectorFactory.Builder(name, port);
+ XmlHelper.getOptionalAttribute(serverSpec, "default-request-chain")
+ .map(ComponentId::new)
+ .ifPresent(builder::setDefaultRequestFilterChain);
+ XmlHelper.getOptionalAttribute(serverSpec, "default-response-chain")
+ .map(ComponentId::new)
+ .ifPresent(builder::setDefaultResponseFilterChain);
SslProvider sslProviderComponent = getSslConfigComponents(name, serverSpec);
- return new ConnectorFactory(name, port, sslProviderComponent);
+ return builder.setSslProvider(sslProviderComponent).build();
}
SslProvider getSslConfigComponents(String serverName, Element serverSpec) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
index fc604c6174a..c8f2bd08ea5 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
@@ -362,7 +362,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
if(cluster.getHttp().getHttpServer().isEmpty()) {
JettyHttpServer defaultHttpServer = new JettyHttpServer(new ComponentId("DefaultHttpServer"), cluster, cluster.isHostedVespa());
cluster.getHttp().setHttpServer(defaultHttpServer);
- defaultHttpServer.addConnector(new ConnectorFactory("SearchServer", Defaults.getDefaults().vespaWebServicePort()));
+ defaultHttpServer.addConnector(new ConnectorFactory.Builder("SearchServer", Defaults.getDefaults().vespaWebServicePort()).build());
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/http/DefaultFilterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/http/DefaultFilterTest.java
new file mode 100644
index 00000000000..e5c01989c22
--- /dev/null
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/http/DefaultFilterTest.java
@@ -0,0 +1,69 @@
+// Copyright Verizon Media. 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.config.model.builder.xml.test.DomBuilderTest;
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.container.core.ChainsConfig;
+import com.yahoo.jdisc.http.ServerConfig;
+import com.yahoo.vespa.model.container.component.BindingPattern;
+import com.yahoo.vespa.model.container.component.UserBindingPattern;
+import com.yahoo.vespa.model.container.xml.ContainerModelBuilder;
+import org.junit.Test;
+import org.w3c.dom.Element;
+
+import java.util.Set;
+
+import static java.util.stream.Collectors.toSet;
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author bjorncs
+ */
+public class DefaultFilterTest extends DomBuilderTest {
+
+ private void buildContainerCluster(Element containerElem) {
+ new ContainerModelBuilder(true, ContainerModelBuilder.Networking.enable).build(DeployState.createTestState(), null, null, root, containerElem);
+ root.freezeModelTopology();
+ }
+
+ @Test
+ public void default_request_and_response_filters_in_services_xml_are_listen_in_server_config() {
+ BindingPattern binding = UserBindingPattern.fromHttpPath("/my-chain-binding");
+ Element xml = parse(
+ "<container version='1.0'>",
+ " <http>",
+ " <filtering>",
+ " <request-chain id='request-chain-with-binding'>",
+ " <binding>" + binding.patternString() + "</binding>",
+ " </request-chain>",
+ " <response-chain id='response-chain-with-binding'>",
+ " <binding>" + binding.patternString() + "</binding>",
+ " </response-chain>",
+ " <request-chain id='my-default-request-chain'/>" +
+ " <response-chain id='my-default-response-chain'/>",
+ " </filtering>",
+ " <server id='server1' port='8000' default-request-chain=\"my-default-request-chain\" default-response-chain=\"my-default-response-chain\"/>",
+ " <server id='server2' port='9000' />",
+ " </http>",
+ "</container>");
+ buildContainerCluster(xml);
+
+ assertDefaultFiltersInConfig(root.getConfig(ServerConfig.class, "container/http/jdisc-jetty/server1"));
+ assertDefaultFiltersInConfig(root.getConfig(ServerConfig.class, "container/http/jdisc-jetty/server2"));
+
+ ChainsConfig chainsConfig = root.getConfig(ChainsConfig.class, "container/filters/chain");
+ Set<String> chainsIds = chainsConfig.chains().stream().map(ChainsConfig.Chains::id).collect(toSet());
+ assertThat(chainsIds)
+ .containsExactlyInAnyOrder(
+ "request-chain-with-binding", "response-chain-with-binding", "my-default-request-chain", "my-default-response-chain");
+ }
+
+ private static void assertDefaultFiltersInConfig(ServerConfig config) {
+ assertThat(config.defaultFilters())
+ .containsExactlyInAnyOrder(
+ new ServerConfig.DefaultFilters(new ServerConfig.DefaultFilters.Builder()
+ .filterId("my-default-request-chain").localPort(8000)),
+ new ServerConfig.DefaultFilters(new ServerConfig.DefaultFilters.Builder()
+ .filterId("my-default-response-chain").localPort(8000)));
+ }
+}