From 94e3449f4b57647b199a03e2e59f91ee902b35eb Mon Sep 17 00:00:00 2001 From: Bjørn Christian Seime Date: Wed, 19 Jul 2017 11:23:41 +0200 Subject: Remove Scala from container-core --- container-core/pom.xml | 31 ---- .../http/filter/FilterChainRepository.java | 165 +++++++++++++++++++++ .../http/filter/FilterChainRepository.scala | 154 ------------------- 3 files changed, 165 insertions(+), 185 deletions(-) create mode 100644 container-core/src/main/java/com/yahoo/container/http/filter/FilterChainRepository.java delete mode 100644 container-core/src/main/scala/com/yahoo/container/http/filter/FilterChainRepository.scala 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 @@ -185,11 +185,6 @@ mockito-core test - - com.yahoo.vespa - scalalib - ${project.version} - com.fasterxml.jackson.core jackson-core @@ -203,32 +198,6 @@ - - net.alchim31.maven - scala-maven-plugin - - - compile - - compile - - compile - - - test-compile - - testCompile - - test-compile - - - process-resources - - compile - - - - org.apache.maven.plugins maven-jar-plugin 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 filterAndChains; + + public FilterChainRepository(ChainsConfig chainsConfig, + ComponentRegistry requestFilters, + ComponentRegistry responseFilters, + ComponentRegistry securityRequestFilters, + ComponentRegistry securityResponseFilters) { + ComponentRegistry 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 destination, + ComponentRegistry... registries) { + for (ComponentRegistry registry : registries) { + registry.allComponentsById() + .forEach((id, filter) -> destination.register(id, wrapIfSecurityFilter(filter))); + } + } + + private static void addAllChains(ComponentRegistry destination, + ChainsConfig chainsConfig, + ComponentRegistry... filters) { + ChainRegistry chainRegistry = buildChainRegistry(chainsConfig, filters); + chainRegistry.allComponents() + .forEach(chain -> destination.register(chain.getId(), toJDiscChain(chain))); + } + + private static ChainRegistry buildChainRegistry(ChainsConfig chainsConfig, + ComponentRegistry... filters) { + ChainRegistry 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 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) jdiscFilters); + else if (head instanceof ResponseFilter) + return ResponseFilterChain.newInstance((List) jdiscFilters); + throw new IllegalStateException(); + } + + private static void checkFilterTypesCompatible(Chain chain) { + Set requestFilters = chain.components().stream() + .filter(filter -> filter instanceof RequestFilter || filter instanceof SecurityRequestFilter) + .map(FilterWrapper::getId) + .collect(toSet()); + Set 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 allFiltersWrapped(ComponentRegistry... registries) { + ComponentRegistry 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) filters); + else if (head instanceof SecurityResponseFilter) + return SecurityResponseFilterChain.newInstance((List) 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) -} -- cgit v1.2.3 From 43298ad59815c9731e0d2f0cd8604af08a119021 Mon Sep 17 00:00:00 2001 From: Bjørn Christian Seime Date: Wed, 19 Jul 2017 13:40:35 +0200 Subject: Rewrite ProjectBundleClassPaths to Java --- .../application/container/jersey/JerseyTest.scala | 19 +-- bundle-plugin-test/pom.xml | 10 -- .../src/test/java/com/yahoo/BundleIT.java | 14 +-- bundle-plugin/pom.xml | 2 +- .../mojo/GenerateBundleClassPathMappingsMojo.scala | 20 ++-- .../com/yahoo/container/di/osgi/OsgiUtil.scala | 12 +- scalalib/pom.xml | 4 - .../osgi/maven/ProjectBundleClassPaths.scala | 44 ------- .../yahoo/osgi/maven/ProjectBundleClassPaths.java | 130 +++++++++++++++++++++ .../osgi/maven/ProjectBundleClassPathsTest.java | 35 ++++++ 10 files changed, 198 insertions(+), 92 deletions(-) delete mode 100644 scalalib/src/main/scala/com/yahoo/vespa/scalalib/osgi/maven/ProjectBundleClassPaths.scala create mode 100644 vespajlib/src/main/java/com/yahoo/osgi/maven/ProjectBundleClassPaths.java create mode 100644 vespajlib/src/test/java/com/yahoo/osgi/maven/ProjectBundleClassPathsTest.java diff --git a/application/src/test/scala/com/yahoo/application/container/jersey/JerseyTest.scala b/application/src/test/scala/com/yahoo/application/container/jersey/JerseyTest.scala index a199c28a4b2..2aee68f254a 100644 --- a/application/src/test/scala/com/yahoo/application/container/jersey/JerseyTest.scala +++ b/application/src/test/scala/com/yahoo/application/container/jersey/JerseyTest.scala @@ -8,8 +8,8 @@ import com.yahoo.application.Networking import com.yahoo.application.container.JDiscTest._ import com.yahoo.container.test.jars.jersey.resources.TestResourceBase import com.yahoo.container.test.jars.jersey.{resources => jarResources} -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping +import com.yahoo.osgi.maven.ProjectBundleClassPaths +import com.yahoo.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping import org.apache.http.HttpResponse import org.apache.http.client.methods.HttpGet import org.apache.http.impl.client.HttpClientBuilder @@ -18,6 +18,7 @@ import org.hamcrest.CoreMatchers.is import org.junit.Assert._ import org.junit.Test +import scala.collection.JavaConverters._ import scala.io.Source /** @@ -51,11 +52,11 @@ class JerseyTest { @Test def jersey_resources_in_provided_dependencies_can_be_invoked_from_application(): Unit = { - val providedDependency = BundleClasspathMapping(bundleSymbolicName, List(testClassesDirectory)) + val providedDependency = new BundleClasspathMapping(bundleSymbolicName, List(testClassesDirectory).asJava) - save(ProjectBundleClassPaths( - mainBundle = BundleClasspathMapping("main", List()), - providedDependencies = List(providedDependency))) + save(new ProjectBundleClassPaths( + new BundleClasspathMapping("main", List().asJava), + List(providedDependency).asJava)) with_jersey_resources() { httpGetter => assertResourcesResponds(classPathResources, httpGetter) @@ -153,12 +154,12 @@ class JerseyTest { } def saveMainBundleClassPathMappings(classPathElement: String): Unit = { - val mainBundleClassPathMappings = BundleClasspathMapping(bundleSymbolicName, List(classPathElement)) - save(ProjectBundleClassPaths(mainBundleClassPathMappings, providedDependencies = List())) + val mainBundleClassPathMappings = new BundleClasspathMapping(bundleSymbolicName, List(classPathElement).asJava) + save(new ProjectBundleClassPaths(mainBundleClassPathMappings, List().asJava)) } def save(projectBundleClassPaths: ProjectBundleClassPaths): Unit = { - val path = Paths.get(testClassesDirectory).resolve(ProjectBundleClassPaths.classPathMappingsFileName) + val path = Paths.get(testClassesDirectory).resolve(ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME) ProjectBundleClassPaths.save(path, projectBundleClassPaths) } diff --git a/bundle-plugin-test/pom.xml b/bundle-plugin-test/pom.xml index ebc60f86b93..2112d616523 100644 --- a/bundle-plugin-test/pom.xml +++ b/bundle-plugin-test/pom.xml @@ -42,16 +42,6 @@ jrt ${project.version} - - org.scala-lang - scala-library - - - com.yahoo.vespa - scalalib - ${project.version} - test - diff --git a/bundle-plugin-test/src/test/java/com/yahoo/BundleIT.java b/bundle-plugin-test/src/test/java/com/yahoo/BundleIT.java index a7d27a449e6..f088007ebb7 100644 --- a/bundle-plugin-test/src/test/java/com/yahoo/BundleIT.java +++ b/bundle-plugin-test/src/test/java/com/yahoo/BundleIT.java @@ -1,11 +1,10 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo; -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths; +import com.yahoo.osgi.maven.ProjectBundleClassPaths; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import scala.collection.JavaConverters; import java.io.File; import java.io.FilenameFilter; @@ -132,18 +131,17 @@ public class BundleIT { @SuppressWarnings("unchecked") @Test - public void bundle_class_path_mappings_are_generated() throws URISyntaxException { - URL mappingsUrl = getClass().getResource("/" + ProjectBundleClassPaths.classPathMappingsFileName()); + public void bundle_class_path_mappings_are_generated() throws URISyntaxException, IOException { + URL mappingsUrl = getClass().getResource("/" + com.yahoo.osgi.maven.ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME); assertNotNull( - "Could not find " + ProjectBundleClassPaths.classPathMappingsFileName() + " in the test output directory", + "Could not find " + ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME + " in the test output directory", mappingsUrl); ProjectBundleClassPaths bundleClassPaths = ProjectBundleClassPaths.load(Paths.get(mappingsUrl.toURI())); - assertThat(bundleClassPaths.mainBundle().bundleSymbolicName(), is("bundle-plugin-test")); + assertThat(bundleClassPaths.mainBundle.bundleSymbolicName, is("bundle-plugin-test")); - Collection mainBundleClassPaths = - JavaConverters.asJavaCollectionConverter(bundleClassPaths.mainBundle().classPathElements()).asJavaCollection(); + Collection mainBundleClassPaths = bundleClassPaths.mainBundle.classPathElements; assertThat(mainBundleClassPaths, hasItems( diff --git a/bundle-plugin/pom.xml b/bundle-plugin/pom.xml index 31355ff21d2..60facd877ed 100644 --- a/bundle-plugin/pom.xml +++ b/bundle-plugin/pom.xml @@ -74,7 +74,7 @@ com.yahoo.vespa - scalalib + vespajlib ${project.version} diff --git a/bundle-plugin/src/main/scala/com/yahoo/container/plugin/mojo/GenerateBundleClassPathMappingsMojo.scala b/bundle-plugin/src/main/scala/com/yahoo/container/plugin/mojo/GenerateBundleClassPathMappingsMojo.scala index cad91e00684..4f463e7b494 100644 --- a/bundle-plugin/src/main/scala/com/yahoo/container/plugin/mojo/GenerateBundleClassPathMappingsMojo.scala +++ b/bundle-plugin/src/main/scala/com/yahoo/container/plugin/mojo/GenerateBundleClassPathMappingsMojo.scala @@ -6,14 +6,15 @@ import java.nio.file.Paths import com.google.common.base.Preconditions import com.yahoo.container.plugin.bundle.AnalyzeBundle -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths -import ProjectBundleClassPaths.BundleClasspathMapping -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths +import com.yahoo.osgi.maven.ProjectBundleClassPaths +import com.yahoo.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping import org.apache.maven.artifact.Artifact import org.apache.maven.plugin.AbstractMojo -import org.apache.maven.plugins.annotations.{ResolutionScope, Mojo, Parameter} +import org.apache.maven.plugins.annotations.{Mojo, Parameter, ResolutionScope} import org.apache.maven.project.MavenProject +import scala.collection.JavaConverters._ + /** @@ -61,13 +62,12 @@ class GenerateBundleClassPathMappingsMojo extends AbstractMojo { val classPathElements = (outputDirectory +: embeddedArtifactsFiles).map(_.getAbsolutePath) - val classPathMappings = ProjectBundleClassPaths( - mainBundle = BundleClasspathMapping(bundleSymbolicName, classPathElements), - providedDependencies = providedJarArtifacts flatMap createDependencyClasspathMapping - ) + val classPathMappings = new ProjectBundleClassPaths( + new BundleClasspathMapping(bundleSymbolicName, classPathElements.asJava), + providedJarArtifacts.flatMap(createDependencyClasspathMapping).asJava) ProjectBundleClassPaths.save( - testOutputPath.resolve(ProjectBundleClassPaths.classPathMappingsFileName), + testOutputPath.resolve(ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME), classPathMappings) } @@ -82,7 +82,7 @@ class GenerateBundleClassPathMappingsMojo extends AbstractMojo { */ def createDependencyClasspathMapping(artifact: Artifact): Option[BundleClasspathMapping] = { for (bundleSymbolicName <- bundleSymbolicNameForArtifact(artifact)) - yield BundleClasspathMapping(bundleSymbolicName, classPathElements = List(artifact.getFile.getAbsolutePath)) + yield new BundleClasspathMapping(bundleSymbolicName, List(artifact.getFile.getAbsolutePath).asJava) } def bundleSymbolicNameForArtifact(artifact: Artifact): Option[String] = { diff --git a/container-di/src/main/scala/com/yahoo/container/di/osgi/OsgiUtil.scala b/container-di/src/main/scala/com/yahoo/container/di/osgi/OsgiUtil.scala index f2120786579..d119f7b0cd4 100644 --- a/container-di/src/main/scala/com/yahoo/container/di/osgi/OsgiUtil.scala +++ b/container-di/src/main/scala/com/yahoo/container/di/osgi/OsgiUtil.scala @@ -10,10 +10,10 @@ import java.util.stream.Collectors import com.google.common.io.Files.fileTreeTraverser import com.yahoo.component.ComponentSpecification import com.yahoo.container.di.Osgi.RelativePath +import com.yahoo.osgi.maven.ProjectBundleClassPaths +import com.yahoo.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping import com.yahoo.vespa.scalalib.arm.Using.using import com.yahoo.vespa.scalalib.java.function.FunctionConverters._ -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping import org.osgi.framework.Bundle import org.osgi.framework.wiring.BundleWiring @@ -46,7 +46,7 @@ object OsgiUtil { bundleSpec: ComponentSpecification, packagesToScan: Set[String]) = { classEntriesFrom( - bundleClassPathMapping(bundleSpec, classLoader).classPathElements, + bundleClassPathMapping(bundleSpec, classLoader).classPathElements.asScala.toList, packagesToScan) } @@ -59,7 +59,7 @@ object OsgiUtil { projectBundleClassPaths.mainBundle } else { log.log(Level.WARNING, s"Dependencies of the bundle $bundleSpec will not be scanned. Please file a feature request if you need this" ) - matchingBundleClassPathMapping(bundleSpec, projectBundleClassPaths.providedDependencies) + matchingBundleClassPathMapping(bundleSpec, projectBundleClassPaths.providedDependencies.asScala.toList) } } @@ -71,9 +71,9 @@ object OsgiUtil { } private def loadProjectBundleClassPaths(classLoader: ClassLoader): ProjectBundleClassPaths = { - val classPathMappingsFileLocation = classLoader.getResource(ProjectBundleClassPaths.classPathMappingsFileName) + val classPathMappingsFileLocation = classLoader.getResource(ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME) if (classPathMappingsFileLocation == null) - throw new RuntimeException(s"Couldn't find ${ProjectBundleClassPaths.classPathMappingsFileName} in the class path.") + throw new RuntimeException(s"Couldn't find ${ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME} in the class path.") ProjectBundleClassPaths.load(Paths.get(classPathMappingsFileLocation.toURI)) } diff --git a/scalalib/pom.xml b/scalalib/pom.xml index 78237211ac3..d4556d4648b 100644 --- a/scalalib/pom.xml +++ b/scalalib/pom.xml @@ -29,10 +29,6 @@ annotations ${project.version} - - org.json4s - json4s-native_${scala.major-version} - diff --git a/scalalib/src/main/scala/com/yahoo/vespa/scalalib/osgi/maven/ProjectBundleClassPaths.scala b/scalalib/src/main/scala/com/yahoo/vespa/scalalib/osgi/maven/ProjectBundleClassPaths.scala deleted file mode 100644 index 08b8f05b96f..00000000000 --- a/scalalib/src/main/scala/com/yahoo/vespa/scalalib/osgi/maven/ProjectBundleClassPaths.scala +++ /dev/null @@ -1,44 +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.vespa.scalalib.osgi.maven - -import java.nio.charset.StandardCharsets -import java.nio.file.{Files, Path} - -import org.json4s.NoTypeHints -import org.json4s.native.Serialization - -import ProjectBundleClassPaths._ - -/** - * Represents the bundles in a maven project and the classpath elements - * corresponding to code that would end up in the bundle. - * @author tonytv - */ -case class ProjectBundleClassPaths(mainBundle: BundleClasspathMapping, - providedDependencies: List[BundleClasspathMapping]) - - -object ProjectBundleClassPaths { - //Written by bundle-plugin in the test classes directory. - val classPathMappingsFileName = "bundle-plugin.bundle-classpath-mappings.json" - - case class BundleClasspathMapping(bundleSymbolicName: String, classPathElements: List[String]) - - //Used by Serialization.* methods. See https://github.com/json4s/json4s - private implicit val serializationFormat = Serialization.formats(NoTypeHints) - - def save(path: Path, mappings: ProjectBundleClassPaths) { - Files.createDirectories(path.getParent) - val outputFile = Files.newBufferedWriter(path, StandardCharsets.UTF_8) - try { - Serialization.write(mappings, outputFile) - } finally { - outputFile.close() - } - } - - def load(path: Path): ProjectBundleClassPaths = { - val inputFile = Files.newBufferedReader(path, StandardCharsets.UTF_8) - Serialization.read[ProjectBundleClassPaths](inputFile) - } -} diff --git a/vespajlib/src/main/java/com/yahoo/osgi/maven/ProjectBundleClassPaths.java b/vespajlib/src/main/java/com/yahoo/osgi/maven/ProjectBundleClassPaths.java new file mode 100644 index 00000000000..92ba8b79572 --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/osgi/maven/ProjectBundleClassPaths.java @@ -0,0 +1,130 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.osgi.maven; + +import com.yahoo.slime.Cursor; +import com.yahoo.slime.Inspector; +import com.yahoo.slime.JsonDecoder; +import com.yahoo.slime.JsonFormat; +import com.yahoo.slime.Slime; + +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Represents the bundles in a maven project and the classpath elements + * corresponding to code that would end up in the bundle. + * + * @author tonytv + * @author bjorncs + */ + +public class ProjectBundleClassPaths { + public static final String CLASSPATH_MAPPINGS_FILENAME = "bundle-plugin.bundle-classpath-mappings.json"; + + public final BundleClasspathMapping mainBundle; + public final List providedDependencies; + + public ProjectBundleClassPaths(BundleClasspathMapping mainBundle, + List providedDependencies) { + this.mainBundle = mainBundle; + this.providedDependencies = providedDependencies; + } + + public static void save(Path path, ProjectBundleClassPaths mappings) throws IOException { + Files.createDirectories(path.getParent()); + try (OutputStream out = new BufferedOutputStream(Files.newOutputStream(path))) { + save(out, mappings); + } + } + + static void save(OutputStream out, ProjectBundleClassPaths mappings) throws IOException { + Slime slime = new Slime(); + Cursor rootCursor = slime.setObject(); + Cursor mainBundleCursor = rootCursor.setObject("mainBundle"); + BundleClasspathMapping.save(mainBundleCursor, mappings.mainBundle); + Cursor dependenciesCursor = rootCursor.setArray("providedDependencies"); + mappings.providedDependencies + .forEach(d -> BundleClasspathMapping.save(dependenciesCursor.addObject(), d)); + new JsonFormat(false).encode(out, slime); + } + + public static ProjectBundleClassPaths load(Path path) throws IOException { + byte[] bytes = Files.readAllBytes(path); + return load(bytes); + } + + static ProjectBundleClassPaths load(byte[] bytes) { + Slime slime = new Slime(); + new JsonDecoder().decode(slime, bytes); + Inspector inspector = slime.get(); + BundleClasspathMapping mainBundle = BundleClasspathMapping.load(inspector.field("mainBundle")); + Inspector dependenciesInspector = inspector.field("providedDependencies"); + List providedDependencies = new ArrayList<>(); + for (int i = 0; i < dependenciesInspector.entries(); i++) { + providedDependencies.add(BundleClasspathMapping.load(dependenciesInspector.entry(i))); + } + return new ProjectBundleClassPaths(mainBundle, providedDependencies); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ProjectBundleClassPaths that = (ProjectBundleClassPaths) o; + return Objects.equals(mainBundle, that.mainBundle) && + Objects.equals(providedDependencies, that.providedDependencies); + } + + @Override + public int hashCode() { + return Objects.hash(mainBundle, providedDependencies); + } + + public static class BundleClasspathMapping { + public final String bundleSymbolicName; + public final List classPathElements; + + public BundleClasspathMapping(String bundleSymbolicName, + List classPathElements) { + this.bundleSymbolicName = bundleSymbolicName; + this.classPathElements = classPathElements; + } + + static void save(Cursor rootCursor, BundleClasspathMapping mapping) { + rootCursor.setString("bundleSymbolicName", mapping.bundleSymbolicName); + Cursor arrayCursor = rootCursor.setArray("classPathElements"); + mapping.classPathElements.forEach(arrayCursor::addString); + } + + static BundleClasspathMapping load(Inspector inspector) { + String bundleSymoblicName = inspector.field("bundleSymbolicName").asString(); + Inspector elementsInspector = inspector.field("classPathElements"); + List classPathElements = new ArrayList<>(); + for (int i = 0; i < elementsInspector.entries(); i++) { + classPathElements.add(elementsInspector.entry(i).asString()); + } + return new BundleClasspathMapping(bundleSymoblicName, classPathElements); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BundleClasspathMapping that = (BundleClasspathMapping) o; + return Objects.equals(bundleSymbolicName, that.bundleSymbolicName) && + Objects.equals(classPathElements, that.classPathElements); + } + + @Override + public int hashCode() { + return Objects.hash(bundleSymbolicName, classPathElements); + } + } + +} diff --git a/vespajlib/src/test/java/com/yahoo/osgi/maven/ProjectBundleClassPathsTest.java b/vespajlib/src/test/java/com/yahoo/osgi/maven/ProjectBundleClassPathsTest.java new file mode 100644 index 00000000000..9bb66afd876 --- /dev/null +++ b/vespajlib/src/test/java/com/yahoo/osgi/maven/ProjectBundleClassPathsTest.java @@ -0,0 +1,35 @@ +package com.yahoo.osgi.maven; + +import com.yahoo.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; + +/** + * @author bjorncs + */ +public class ProjectBundleClassPathsTest { + + @Test + public void bundle_classpaths_serializes_correctly_to_json() throws IOException { + ProjectBundleClassPaths projectBundleClassPaths = + new ProjectBundleClassPaths( + new BundleClasspathMapping("main-bundle-name", asList("classpath-elem-0-1", "classpath-elem-0-2")), + asList( + new BundleClasspathMapping( + "main-bundle-dep1", + asList("classpath-elem-1-1", "classpath-elem-1-2")), + new BundleClasspathMapping( + "main-bundle-dep2", + asList("classpath-elem-2-1", "classpath-elem-2-2")))); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ProjectBundleClassPaths.save(out, projectBundleClassPaths); + ProjectBundleClassPaths deserialized = ProjectBundleClassPaths.load(out.toByteArray()); + assertEquals(projectBundleClassPaths, deserialized); + } + +} -- cgit v1.2.3 From d6b8211a77ff66b1f945710e3997d51f8d1c8fd9 Mon Sep 17 00:00:00 2001 From: Bjørn Christian Seime Date: Wed, 19 Jul 2017 14:02:17 +0200 Subject: Remove scalalib --- application/pom.xml | 6 --- container-di/pom.xml | 5 -- .../com/yahoo/container/di/osgi/OsgiUtil.scala | 16 ++++-- maven-plugins/pom.xml | 1 - pom.xml | 1 - scalalib/OWNERS | 1 - scalalib/README | 1 - scalalib/pom.xml | 60 ---------------------- .../scala/com/yahoo/vespa/scalalib/arm/Using.scala | 17 ------ .../java/function/FunctionConverters.scala | 20 -------- 10 files changed, 13 insertions(+), 115 deletions(-) delete mode 100644 scalalib/OWNERS delete mode 100644 scalalib/README delete mode 100644 scalalib/pom.xml delete mode 100644 scalalib/src/main/scala/com/yahoo/vespa/scalalib/arm/Using.scala delete mode 100644 scalalib/src/main/scala/com/yahoo/vespa/scalalib/java/function/FunctionConverters.scala diff --git a/application/pom.xml b/application/pom.xml index f58e16a0341..b83c1e92190 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -76,12 +76,6 @@ ${project.version} test - - com.yahoo.vespa - scalalib - ${project.version} - test - diff --git a/container-di/pom.xml b/container-di/pom.xml index f6a31ea16a1..86baa0f2081 100644 --- a/container-di/pom.xml +++ b/container-di/pom.xml @@ -49,11 +49,6 @@ pom provided - - com.yahoo.vespa - scalalib - ${project.version} - org.scala-lang scala-compiler diff --git a/container-di/src/main/scala/com/yahoo/container/di/osgi/OsgiUtil.scala b/container-di/src/main/scala/com/yahoo/container/di/osgi/OsgiUtil.scala index d119f7b0cd4..489760dcbc8 100644 --- a/container-di/src/main/scala/com/yahoo/container/di/osgi/OsgiUtil.scala +++ b/container-di/src/main/scala/com/yahoo/container/di/osgi/OsgiUtil.scala @@ -12,8 +12,6 @@ import com.yahoo.component.ComponentSpecification import com.yahoo.container.di.Osgi.RelativePath import com.yahoo.osgi.maven.ProjectBundleClassPaths import com.yahoo.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping -import com.yahoo.vespa.scalalib.arm.Using.using -import com.yahoo.vespa.scalalib.java.function.FunctionConverters._ import org.osgi.framework.Bundle import org.osgi.framework.wiring.BundleWiring @@ -119,15 +117,27 @@ object OsgiUtil { if (packagePathsToScan.isEmpty) (name: String) => true else (name: String) => packagePathsToScan(packagePath(name)) - using(new JarFile(jarPath.toFile)) { jarFile => + var jarFile: JarFile = null + try { + jarFile = new JarFile(jarPath.toFile) jarFile.stream(). map[String] { entry: JarEntry => entry.getName}. filter { name: String => name.endsWith(classFileTypeSuffix)}. filter(acceptedPackage). collect(Collectors.toList()). asScala + } finally { + if (jarFile != null) jarFile.close() } } def packageToPath(packageName: String) = packageName.replaceAllLiterally(".", "/") + + implicit class JavaPredicate[T](f: T => Boolean) extends Predicate[T] { + override def test(t: T): Boolean = f(t) + } + + implicit class JavaFunction[T, R](f: T => R) extends java.util.function.Function[T, R] { + override def apply(t: T): R = f(t) + } } diff --git a/maven-plugins/pom.xml b/maven-plugins/pom.xml index 3fdb91adf7f..2f7343e753c 100644 --- a/maven-plugins/pom.xml +++ b/maven-plugins/pom.xml @@ -17,7 +17,6 @@ ../annotations - ../scalalib ../bundle-plugin ../configgen ../config-class-plugin diff --git a/pom.xml b/pom.xml index 618cc3837fb..abe03898086 100644 --- a/pom.xml +++ b/pom.xml @@ -1039,6 +1039,5 @@ vsm yolean zkfacade - scalalib diff --git a/scalalib/OWNERS b/scalalib/OWNERS deleted file mode 100644 index 3b2ba1ede81..00000000000 --- a/scalalib/OWNERS +++ /dev/null @@ -1 +0,0 @@ -gjoranv diff --git a/scalalib/README b/scalalib/README deleted file mode 100644 index 9c622c66ec0..00000000000 --- a/scalalib/README +++ /dev/null @@ -1 +0,0 @@ -Module for shared Scala utility code in Vespa. diff --git a/scalalib/pom.xml b/scalalib/pom.xml deleted file mode 100644 index d4556d4648b..00000000000 --- a/scalalib/pom.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - 4.0.0 - - com.yahoo.vespa - parent - 6-SNAPSHOT - - scalalib - jar - 6-SNAPSHOT - ${project.artifactId} - Library for use in Scala components of Vespa. - - - - junit - junit - test - - - org.scala-lang - scala-library - - - com.yahoo.vespa - annotations - ${project.version} - - - - - - net.alchim31.maven - scala-maven-plugin - - - - add-source - compile - testCompile - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - once - - ${project.version} - - - - - - diff --git a/scalalib/src/main/scala/com/yahoo/vespa/scalalib/arm/Using.scala b/scalalib/src/main/scala/com/yahoo/vespa/scalalib/arm/Using.scala deleted file mode 100644 index bee1172a26f..00000000000 --- a/scalalib/src/main/scala/com/yahoo/vespa/scalalib/arm/Using.scala +++ /dev/null @@ -1,17 +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.vespa.scalalib.arm - -import scala.language.reflectiveCalls - -/** - * @author tonytv - */ -object Using { - def using[RESOURCE <: { def close() }, RETURN](resource: RESOURCE)(f: RESOURCE => RETURN) = { - try { - f(resource) - } finally { - if (resource != null) resource.close() - } - } -} diff --git a/scalalib/src/main/scala/com/yahoo/vespa/scalalib/java/function/FunctionConverters.scala b/scalalib/src/main/scala/com/yahoo/vespa/scalalib/java/function/FunctionConverters.scala deleted file mode 100644 index b8cce3cf343..00000000000 --- a/scalalib/src/main/scala/com/yahoo/vespa/scalalib/java/function/FunctionConverters.scala +++ /dev/null @@ -1,20 +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.vespa.scalalib.java.function - -import java.util.function.Predicate - -import scala.language.implicitConversions - -/** - * For using scala functions in Java APIs, such as the stream API. - * @author tonytv - */ -object FunctionConverters { - implicit class JavaPredicate[T](f: T => Boolean) extends Predicate[T] { - override def test(t: T): Boolean = f(t) - } - - implicit class JavaFunction[T, R](f: T => R) extends java.util.function.Function[T, R] { - override def apply(t: T): R = f(t) - } -} -- cgit v1.2.3 From d84c0532dc98482d10204a6c7a4b6b8aa3c4b3f9 Mon Sep 17 00:00:00 2001 From: Bjørn Christian Seime Date: Fri, 21 Jul 2017 11:22:18 +0200 Subject: Module only contains Scala test sources --- application/pom.xml | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/application/pom.xml b/application/pom.xml index b83c1e92190..8f301c1a884 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -113,31 +113,11 @@ scala-maven-plugin - compile - - compile - - compile - - - test-compile + scala-test-compile + process-test-resources testCompile - test-compile - - - process-resources - - compile - - - - process-test-resources - early-test-compile - - testCompile - -- cgit v1.2.3