summaryrefslogtreecommitdiffstats
path: root/container-core
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@yahoo-inc.com>2017-07-19 11:23:41 +0200
committerBjørn Christian Seime <bjorncs@yahoo-inc.com>2017-07-20 13:13:09 +0200
commit94e3449f4b57647b199a03e2e59f91ee902b35eb (patch)
tree682aedfecbe6fa62fbfd3be986c74fe4338b1531 /container-core
parent929a44e999bbaae9600753aea1a8335a9facd69e (diff)
Remove Scala from container-core
Diffstat (limited to 'container-core')
-rw-r--r--container-core/pom.xml31
-rw-r--r--container-core/src/main/java/com/yahoo/container/http/filter/FilterChainRepository.java165
-rw-r--r--container-core/src/main/scala/com/yahoo/container/http/filter/FilterChainRepository.scala154
3 files changed, 165 insertions, 185 deletions
diff --git a/container-core/pom.xml b/container-core/pom.xml
index 79d8fc1f199..c608f35f26c 100644
--- a/container-core/pom.xml
+++ b/container-core/pom.xml
@@ -186,11 +186,6 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>com.yahoo.vespa</groupId>
- <artifactId>scalalib</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<scope>provided</scope>
@@ -204,32 +199,6 @@
<build>
<plugins>
<plugin>
- <groupId>net.alchim31.maven</groupId>
- <artifactId>scala-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>compile</id>
- <goals>
- <goal>compile</goal>
- </goals>
- <phase>compile</phase>
- </execution>
- <execution>
- <id>test-compile</id>
- <goals>
- <goal>testCompile</goal>
- </goals>
- <phase>test-compile</phase>
- </execution>
- <execution>
- <phase>process-resources</phase>
- <goals>
- <goal>compile</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
diff --git a/container-core/src/main/java/com/yahoo/container/http/filter/FilterChainRepository.java b/container-core/src/main/java/com/yahoo/container/http/filter/FilterChainRepository.java
new file mode 100644
index 00000000000..a736fd1372f
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/http/filter/FilterChainRepository.java
@@ -0,0 +1,165 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.http.filter;
+
+import com.yahoo.component.AbstractComponent;
+import com.yahoo.component.ComponentId;
+import com.yahoo.component.ComponentSpecification;
+import com.yahoo.component.chain.Chain;
+import com.yahoo.component.chain.ChainedComponent;
+import com.yahoo.component.chain.ChainsConfigurer;
+import com.yahoo.component.chain.model.ChainsModel;
+import com.yahoo.component.chain.model.ChainsModelBuilder;
+import com.yahoo.component.provider.ComponentRegistry;
+import com.yahoo.container.core.ChainsConfig;
+import com.yahoo.jdisc.http.filter.RequestFilter;
+import com.yahoo.jdisc.http.filter.ResponseFilter;
+import com.yahoo.jdisc.http.filter.SecurityRequestFilter;
+import com.yahoo.jdisc.http.filter.SecurityRequestFilterChain;
+import com.yahoo.jdisc.http.filter.SecurityResponseFilter;
+import com.yahoo.jdisc.http.filter.SecurityResponseFilterChain;
+import com.yahoo.jdisc.http.filter.chain.RequestFilterChain;
+import com.yahoo.jdisc.http.filter.chain.ResponseFilterChain;
+import com.yahoo.processing.execution.chain.ChainRegistry;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
+
+/**
+ * Creates JDisc request/response filter chains.
+ *
+ * @author tonytv
+ * @author bjorncs
+ */
+public class FilterChainRepository extends AbstractComponent {
+
+ private final ComponentRegistry<Object> filterAndChains;
+
+ public FilterChainRepository(ChainsConfig chainsConfig,
+ ComponentRegistry<RequestFilter> requestFilters,
+ ComponentRegistry<ResponseFilter> responseFilters,
+ ComponentRegistry<SecurityRequestFilter> securityRequestFilters,
+ ComponentRegistry<SecurityResponseFilter> securityResponseFilters) {
+ ComponentRegistry<Object> filterAndChains = new ComponentRegistry<>();
+ addAllFilters(filterAndChains, requestFilters, responseFilters, securityRequestFilters, securityResponseFilters);
+ addAllChains(filterAndChains, chainsConfig, requestFilters, responseFilters, securityRequestFilters, securityResponseFilters);
+ filterAndChains.freeze();
+ this.filterAndChains = filterAndChains;
+ }
+
+ public Object getFilter(ComponentSpecification componentSpecification) {
+ return filterAndChains.getComponent(componentSpecification);
+ }
+
+ private static void addAllFilters(ComponentRegistry<Object> destination,
+ ComponentRegistry<?>... registries) {
+ for (ComponentRegistry<?> registry : registries) {
+ registry.allComponentsById()
+ .forEach((id, filter) -> destination.register(id, wrapIfSecurityFilter(filter)));
+ }
+ }
+
+ private static void addAllChains(ComponentRegistry<Object> destination,
+ ChainsConfig chainsConfig,
+ ComponentRegistry<?>... filters) {
+ ChainRegistry<FilterWrapper> chainRegistry = buildChainRegistry(chainsConfig, filters);
+ chainRegistry.allComponents()
+ .forEach(chain -> destination.register(chain.getId(), toJDiscChain(chain)));
+ }
+
+ private static ChainRegistry<FilterWrapper> buildChainRegistry(ChainsConfig chainsConfig,
+ ComponentRegistry<?>... filters) {
+ ChainRegistry<FilterWrapper> chainRegistry = new ChainRegistry<>();
+ ChainsModel chainsModel = ChainsModelBuilder.buildFromConfig(chainsConfig);
+ ChainsConfigurer.prepareChainRegistry(chainRegistry, chainsModel, allFiltersWrapped(filters));
+ chainRegistry.freeze();
+ return chainRegistry;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Object toJDiscChain(Chain<FilterWrapper> chain) {
+ checkFilterTypesCompatible(chain);
+ List<?> jdiscFilters = chain.components().stream()
+ .map(filterWrapper -> filterWrapper.filter)
+ .collect(toList());
+ Object head = jdiscFilters.get(0);
+ if (jdiscFilters.size() == 1) return head;
+ else if (head instanceof RequestFilter)
+ return RequestFilterChain.newInstance((List<RequestFilter>) jdiscFilters);
+ else if (head instanceof ResponseFilter)
+ return ResponseFilterChain.newInstance((List<ResponseFilter>) jdiscFilters);
+ throw new IllegalStateException();
+ }
+
+ private static void checkFilterTypesCompatible(Chain<FilterWrapper> chain) {
+ Set<ComponentId> requestFilters = chain.components().stream()
+ .filter(filter -> filter instanceof RequestFilter || filter instanceof SecurityRequestFilter)
+ .map(FilterWrapper::getId)
+ .collect(toSet());
+ Set<ComponentId> responseFilters = chain.components().stream()
+ .filter(filter -> filter instanceof ResponseFilter || filter instanceof SecurityResponseFilter)
+ .map(FilterWrapper::getId)
+ .collect(toSet());
+ if (!requestFilters.isEmpty() && !responseFilters.isEmpty()) {
+ throw new IllegalArgumentException(
+ String.format(
+ "Can't mix request and response filters in chain %s: request filters: %s, response filters: %s.",
+ chain.getId(), requestFilters, responseFilters));
+ }
+ }
+
+ private static ComponentRegistry<FilterWrapper> allFiltersWrapped(ComponentRegistry<?>... registries) {
+ ComponentRegistry<FilterWrapper> wrappedFilters = new ComponentRegistry<>();
+ for (ComponentRegistry<?> registry : registries) {
+ registry.allComponentsById()
+ .forEach((id, filter) -> wrappedFilters.register(id, new FilterWrapper(id, filter)));
+ }
+ wrappedFilters.freeze();
+ return wrappedFilters;
+ }
+
+ private static Object wrapIfSecurityFilter(Object filter) {
+ if (isSecurityFilter(filter)) return createSecurityChain(Collections.singletonList(filter));
+ return filter;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Object createSecurityChain(List<?> filters) {
+ Object head = filters.get(0);
+ if (head instanceof SecurityRequestFilter)
+ return SecurityRequestFilterChain.newInstance((List<SecurityRequestFilter>) filters);
+ else if (head instanceof SecurityResponseFilter)
+ return SecurityResponseFilterChain.newInstance((List<SecurityResponseFilter>) filters);
+ throw new IllegalArgumentException("Unexpected class " + head.getClass());
+ }
+
+ private static boolean isSecurityFilter(Object filter) {
+ return filter instanceof SecurityRequestFilter || filter instanceof SecurityResponseFilter;
+ }
+
+ private static class FilterWrapper extends ChainedComponent {
+ public final Object filter;
+ public final Class<?> filterType;
+
+ public FilterWrapper(ComponentId id, Object filter) {
+ super(id);
+ this.filter = filter;
+ this.filterType = getFilterType(filter);
+ }
+
+ private static Class<?> getFilterType(Object filter) {
+ if (filter instanceof RequestFilter)
+ return RequestFilter.class;
+ else if (filter instanceof ResponseFilter)
+ return ResponseFilter.class;
+ else if (filter instanceof SecurityRequestFilter)
+ return SecurityRequestFilter.class;
+ else if (filter instanceof SecurityResponseFilter)
+ return SecurityResponseFilter.class;
+ throw new IllegalArgumentException("Unsupported filter type: " + filter.getClass().getName());
+ }
+ }
+}
diff --git a/container-core/src/main/scala/com/yahoo/container/http/filter/FilterChainRepository.scala b/container-core/src/main/scala/com/yahoo/container/http/filter/FilterChainRepository.scala
deleted file mode 100644
index 18195b7dc50..00000000000
--- a/container-core/src/main/scala/com/yahoo/container/http/filter/FilterChainRepository.scala
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.container.http.filter
-
-import com.yahoo.component.chain.model.ChainsModelBuilder
-import com.yahoo.component.chain.{Chain, ChainedComponent, ChainsConfigurer}
-import com.yahoo.component.provider.ComponentRegistry
-import com.yahoo.component.{AbstractComponent, ComponentId, ComponentSpecification}
-import com.yahoo.container.core.ChainsConfig
-import com.yahoo.container.http.filter.FilterChainRepository._
-import com.yahoo.jdisc.http.filter.chain.{RequestFilterChain, ResponseFilterChain}
-import com.yahoo.jdisc.http.filter.{RequestFilter, ResponseFilter, SecurityRequestFilter, SecurityRequestFilterChain, SecurityResponseFilter, SecurityResponseFilterChain}
-import com.yahoo.processing.execution.chain.ChainRegistry
-
-import scala.collection.JavaConverters._
-
-
-/**
- * Creates JDisc request/response filter chains.
- * @author tonytv
- */
-class FilterChainRepository(chainsConfig: ChainsConfig,
- requestFilters: ComponentRegistry[RequestFilter],
- responseFilters: ComponentRegistry[ResponseFilter],
- securityRequestFilters: ComponentRegistry[SecurityRequestFilter],
- securityResponseFilters: ComponentRegistry[SecurityResponseFilter]) extends AbstractComponent {
-
- private val filtersAndChains = new ComponentRegistry[AnyRef]
- addAllFilters(filtersAndChains, requestFilters, responseFilters, securityRequestFilters, securityResponseFilters)
- addAllChains(filtersAndChains, chainsConfig, requestFilters, responseFilters, securityRequestFilters, securityResponseFilters)
- filtersAndChains.freeze()
-
- def getFilter(componentSpecification: ComponentSpecification) =
- filtersAndChains.getComponent(componentSpecification)
-}
-
- private[filter] object FilterChainRepository {
- case class FilterWrapper(id: ComponentId, filter: AnyRef) extends ChainedComponent(id) {
- def filterType: Class[_] = filter match {
- case f: RequestFilter => classOf[RequestFilter]
- case f: ResponseFilter => classOf[ResponseFilter]
- case f: SecurityRequestFilter => classOf[SecurityRequestFilter]
- case f: SecurityResponseFilter => classOf[SecurityResponseFilter]
- case _ => throw new IllegalArgumentException("Unsupported filter type: " + filter.getClass.getName)
- }
- }
-
- def allFiltersWrapped(registries: ComponentRegistry[_ <: AnyRef]*): ComponentRegistry[FilterWrapper] = {
- val wrappedFilters = new ComponentRegistry[FilterWrapper]
-
- def registerWrappedFilters(registry: ComponentRegistry[_ <: AnyRef]) {
- for ((id, filter) <- registry.allComponentsById().asScala)
- wrappedFilters.register(id, new FilterWrapper(id, filter))
- }
-
- registries.foreach(registerWrappedFilters)
- wrappedFilters.freeze()
- wrappedFilters
- }
-
- private def addAllFilters(destination: ComponentRegistry[AnyRef], registries: ComponentRegistry[_ <: AnyRef]*) {
- def wrapSecurityFilter(filter: AnyRef) = {
- if (isSecurityFilter(filter)) createSecurityChain(List(filter))
- else filter
- }
-
- for {
- registry <- registries
- (id, filter) <- registry.allComponentsById().asScala
- } destination.register(id, wrapSecurityFilter(filter))
- }
-
- private def addAllChains(destination: ComponentRegistry[AnyRef], chainsConfig: ChainsConfig, filters: ComponentRegistry[_ <: AnyRef]*) {
- val chainRegistry = buildChainsRegistry(chainsConfig, filters)
-
- for (chain <- chainRegistry.allComponents().asScala) {
- destination.register(chain.getId, toJDiscChain(chain))
- }
- }
-
-
- def buildChainsRegistry(chainsConfig: ChainsConfig, filters: Seq[ComponentRegistry[_ <: AnyRef]]) = {
- val chainRegistry = new ChainRegistry[FilterWrapper]
- val chainsModel = ChainsModelBuilder.buildFromConfig(chainsConfig)
-
- ChainsConfigurer.prepareChainRegistry(chainRegistry, chainsModel, allFiltersWrapped(filters: _*))
- chainRegistry.freeze()
- chainRegistry
- }
-
- private def toJDiscChain(chain: Chain[FilterWrapper]): AnyRef = {
- checkFilterTypesCompatible(chain)
- val jDiscFilters = chain.components().asScala map {_.filter}
-
- wrapJDiscChain(wrapSecurityFilters(jDiscFilters.toList))
- }
-
- def wrapJDiscChain(filters: List[AnyRef]): AnyRef = {
- if (filters.size == 1) filters.head
- else {
- filters.head match {
- case _: RequestFilter => RequestFilterChain.newInstance(filters.asInstanceOf[List[RequestFilter]].asJava)
- case _: ResponseFilter => ResponseFilterChain.newInstance(filters.asInstanceOf[List[ResponseFilter]].asJava)
- }
- }
- }
-
- def wrapSecurityFilters(filters: List[AnyRef]): List[AnyRef] = {
- if (filters.isEmpty) List()
- else {
- val (securityFilters, rest) = filters.span(isSecurityFilter)
- if (securityFilters.isEmpty) {
- val (regularFilters, rest) = filters.span(!isSecurityFilter(_))
- regularFilters ++ wrapSecurityFilters(rest)
- } else {
- createSecurityChain(securityFilters) :: wrapSecurityFilters(rest)
- }
- }
- }
-
- def createSecurityChain(filters: List[AnyRef]): AnyRef = {
- filters.head match {
- case _: SecurityRequestFilter => SecurityRequestFilterChain.newInstance(filters.asInstanceOf[List[SecurityRequestFilter]].asJava)
- case _: SecurityResponseFilter => SecurityResponseFilterChain.newInstance(filters.asInstanceOf[List[SecurityResponseFilter]].asJava)
- case _ => throw new IllegalArgumentException("Unexpected class " + filters.head.getClass)
- }
- }
-
- def isSecurityFilter(filter: AnyRef) = {
- filter match {
- case _: SecurityRequestFilter => true
- case _: SecurityResponseFilter => true
- case _ => false
- }
- }
-
- def checkFilterTypesCompatible(chain: Chain[FilterWrapper]) {
- val requestFilters = Set[Class[_]](classOf[RequestFilter], classOf[SecurityRequestFilter])
- val responseFilters = Set[Class[_]](classOf[ResponseFilter], classOf[SecurityResponseFilter])
-
- def check(a: FilterWrapper, b: FilterWrapper) {
- if (requestFilters(a.filterType) && responseFilters(b.filterType))
- throw new RuntimeException("Can't mix request and response filters in chain %s: %s, %s".format(chain.getId, a.getId, b.getId))
- }
-
- overlappingPairIterator(chain.components.asScala).foreach {
- case Seq(_) =>
- case Seq(filter1: FilterWrapper, filter2: FilterWrapper) =>
- check(filter1, filter2)
- check(filter2, filter1)
- }
- }
-
- def overlappingPairIterator[T](s: Seq[T]) = s.iterator.sliding(2, 1)
-}